Try   HackMD

送餐機器人畢業專題

必做:環境初始化

  1. 請先在/web/config.json裡面設定軟硬體運行的ip及port

  2. 設定資料庫資訊:

    請在路徑"C:"下新增"rescarDB.txt":

    "C:\rescarDb.txt"

    ​​​​rescarDb.txt內容如下:
    ​​​​{"dbpwd":"填入資料庫密碼(參閱群組記事本)"}
    

先在你要放檔案的位置使用以下指令以下載專題資料夾

​​​​git clone https://github.com/Liuming9124/rescar.git
​​​​cd "剛剛的資料夾名稱"

Neo4j 自學資訊

Fastapi 自學資訊

點餐系統環境建置

1. 需有 npm 環境 (for nodejs)

2. 透過 npm install 下載以下packages

由於需要將網頁資料放在web資料夾裡 請先將當前位置改到web裡面,請下指令

​​​​"cd web"

接下來透過以下指令安裝模組

​​​​"npm install" 

模組詳細資料請見/web/package.json

3. 執行以下指令將網頁開啟

​​​​"nodemon server.js"
​​​​if nodemon not found -> "npm install -g nodemon"
​​​​-g means global

透過網址以造訪頁面

​​​​localhost:7000/home

要進去點餐頁面請先生成桌號代碼,生成QR碼之後點擊QR碼即可開始點餐

http://localhost:7000/qrchoose

Neo4j 資料庫搭建

常用指令:

  • 建立節點:

    • n:變數名稱
    • lable:標籤(通常都用標籤查詢資料)
    • (key,value):節點相關的資料會用此方法儲存
    • 注意:每次下指令時會有許多變數,請勿將變數名稱重複使用!!!
    • 每個小括號內放一個Node,若要一次使用多個請用逗號隔開
create (n:lable1{key:'value'})
create (n2:lable2{key1:'value',key2:'value2'})

create (t1:'l1'), (t2:'l2'), (t3:'l3')
  • 建立關係

    • create (node1)-[rel:'關係']->(node2)

    • 思考方式:
    • A與B有關係 A->B,但是只有箭頭不足以表示關係為何,因此我們要為關係命名
    • A-[關係變數名稱:'like']->B

    • 因此我們可以知道A與B的關係為A喜歡B
match(第一組節點:l1), (第二組節點:l2)
create (第一個節點)-[變數名稱:'關係名稱']->(第二組節點)
  • 查詢NODE

    • 語法: match (var:type{key:'value'}) return var
查詢所有節點
match(n) return(n)

一次查詢兩組節點
match(n1:t1),(n2:t2{k1:'v1'})
return n1, n2

透過關係查詢節點
match(n1:t1)-[rel:'like']->(n2:t2{k1:'v1'})
return n1, rel, n2
  • NODE進階查詢

透過neo4j查詢node會回傳以下格式:
Node {
  identity: Integer { low: 75, high: 0 },
  labels: [ 'order' ],
  properties: { time: 'Sun Mar 26 2023 17:34:45 GMT+0800 (台北標準時間)', status: '0' },
  elementId: '4:b36e673b-2419-44d0-abfc-81af86d3f09d:75'
}

透過elementId可進行查詢:

(1)
需要注意的是,elementId屬性並不是Neo4j中的內建屬性,因此不能直接在Cypher查詢中使用。因此,在上面的示例中,我們需要將elementId屬性的值解析為Element ID,並將其傳遞給id()函數。

在上面的示例中,我們使用split()函數來解析Element ID的值,並從中獲取Element ID。然後,我們使用toInteger()函數將Element ID轉換為整數,並將其傳遞給id()函數進行匹配。

最後,我們使用RETURN子句返回匹配到的節點。在這個例子中,節點的屬性和標籤沒有在查詢中使用,因此返回的節點將包含所有屬性和標籤。
MATCH (n)
WHERE id(n) = toInteger(split('4:b36e673b-2419-44d0-abfc-81af86d3f09d:77', ':')[2])
RETURN n

(2) 直接將回傳值進行轉換
var elementId = record.get('n').elementId = '4:b36e673b-2419-44d0-abfc-81af86d3f09d:77'

eleId = parseInt(elementId.split(':')[2]);
  • 刪除NODE時也刪除連帶關係

match(n:lable{key:'value'})
detach delete n
  • 刪除特定NODE

match(n) where ID(n)=300 delete (n)
  • 找出特定類別(test)的節點,該節點與其他節點沒有relation(可用於刪除特定沒用到的資料)

MATCH (n:test {category: 'test'})
WHERE NOT (n)--()
RETURN n;

本資料庫使用指令

  • 創建主節點Menu

    create(n:menu{name:'menu'})

  • 創建類型

    Create (:type {name:'壽司'}),(:type{name:'拉麵'}),(:type{name:'刺身'}),(:type{name:'定食'}),(:type{name:'甜點'})

  • 建立主節點menu與類型type的關係

    ​​​​match(n:menu),(t:type)
    ​​​​CREATE (n)-[p:has]->(t)
    ​​​​return p
    

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  • 綁定type與item的關係:從壽司開始

    • merge:先查看node使否存在,若否則建立,若是則查詢
    • 創建眾多節點時,可以透過Unwind將多項資訊包裝在一起並用As建立別稱

    使用unwind時必須結合【with】使用,為固定用法,否則會報錯

    ​​​​merge(n:type{name:'壽司'})
    ​​​​with n
    ​​​​UNWIND [
    ​​​​    {name: '綜合壽司', price: 180, description:'xxx', image:'food1.jpg'},
    ​​​​    {name: '鮭魚壽司', price: 200, description:'xxx', image:'food1.jpg'},
    ​​​​    {name: '鮪魚壽司', price: 200, description:'xxx', image:'food1.jpg'},
    ​​​​    {name: '干貝壽司', price: 300, description:'xxx', image:'food1.jpg'},
    ​​​​] AS p
    ​​​​CREATE (i:item) SET i = p
    ​​​​CREATE (n)-[:own]->(i)
    ​​​​RETURN n, i
    

  • 建立QRcode對應URL的關係

    ​​​​建立url資料 status:0->可以點餐, 1->已結帳且無法點餐
    ​​​​create(n:url{link:'網址後綴碼',time:'入座時間',table:'桌號',status:0})
    
  • 新增訂單

    • status:狀態(下訂、製作中、待配送、待結帳、已結帳)
    • status == 0 1 2 3 4
    ​​​​match (n:url{link:'y1tnmwil24'})
    ​​​​create(o:order{time:'now', status: 0})
    ​​​​create (n) -[:order]-> (o)
    ​​​​with o
    ​​​​UNWIND [
    ​​​​    {name: '綜合壽司', price: '11', amt:'1', status:'0'},
    ​​​​    {name: '鮭魚壽司', price: '11', amt:'1', status:'0'},
    ​​​​    {name: '鮪魚壽司', price: '11', amt:'2', status:'0'},
    ​​​​    {name: '干貝壽司', price: '11', amt:'1', status:'0'}
    ​​​​] AS carts
    ​​​​CREATE (c:cart) SET c = carts
    ​​​​CREATE (o)-[:orders]->(c)
    ​​​​RETURN o,c
    
    

  • 查詢訂單:根據時間排序

    ​​​​match(u:url{link:''})-[:order]->(o:order)
    ​​​​return (o)
    ​​​​ORDER BY o.time DESC
    
  • 根據訂單查詢訂單明細

    ​​​​match(o)
    ​​​​where ID(o) = 70
    ​​​​match(o) -[:orders]-> (p:cart)
    ​​​​return p
    
  • 查詢時間在特定區間內的訂單資料

    ​​​​MATCH (o:order) WHERE o.time >= ('2023-04-05-05-27-16.569Z') AND o.time < ('2023-04-22-11-42-05.051Z') RETURN (o) order by o.time desc
    
  • 查詢目前響服務鈴的客戶桌號

    ​​​​MATCH (n:url{alert: "0"})
    ​​​​RETURN n.table
    
  • 客戶發起服務鈴

    ​​​​MATCH (n:url{link: "${req.session.seed}"}) set n.alert='1'
    
  • 商家完成服務鈴

    ​​​​MATCH (n:url{table:'${table}',alert:'1'}) set n.alert='0'
    
  • 結帳

    ​​​​match (n:url{table:'${req.params.table}',status:0})-[r:order]->(o)  
    ​​​​set n.status=1 ,o.status=4  return n,o
    

硬體:

https://fastapi.tiangolo.com/zh/tutorial/

請先參考fastapi的tutorial將環境先建置完成

如果沒看上面的tutorial,一定要安裝的:

pip install fastapi
pip install "uvicorn[standard]"

運行fastapi

1.先進入到/hardware的資料夾

cd /hardware

2.啟動fastapi指令: host 機器人IP位址 port 機器人開放post reload 程式碼有修正會自動重啟

  • note: 127.0.0.1 代表本機,可以在自己的電腦上先測試,若要進行遠端控制請配置一個區網下的真實IP才可以進行遠端連線。

uvicorn main:app --host 127.0.0.1 --port 8000 --reload

logs

1. 軟硬體logs紀錄

有兩筆logs,分別放在:

  • /web/logs.txt
  • /hardware/logs.txt

2. logs 整合

檔案放在/rescar/checkLogs.py,執行該程式碼後logs會整合web及hardware的logs並打印出來以供參考,方式採用read,不會出現搶占硬體資源的情況。

待處理 :

  • 每一秒鐘就再次查詢logs是否有新的資料,若是有新的資料則會打印出新的資料到終端機。
  • 格式及目的需要再更詳細且精準
  • 可參考資料: https://enochliu.pixnet.net/blog/post/46671816
  • 可以建立一個GUI來查看logs
  • 目前格式定義: [時間]{JSON資料}