使用 PYNQ 和 Zigbee 創建一個簡單且可擴展的家庭自動化系統。
介紹
我們經常忘記 FPGA 可用于消費類應用,而不僅僅是工業、汽車、國防/航空航天等。對于諸如 Artix、Spartan 和 Zynq 7000 系列設備等 cist 優化范圍內的設備尤其如此。
可編程邏輯和 SoC 提供了一系列起初可能并不明顯的優勢,包括
系統集成——將幾個離散的處理元件組合成一個包。
上市時間 - 與 ASIC 解決方案相比縮短了時間
現場更新——隨著標準和產品路線圖的發展,不僅可以升級軟件,還可以升級“固定”邏輯設計
架構靈活性——為可編程邏輯提供廣泛的接口和功能加速的能力。
De Risking - 盡早開始開發的能力。
FPGA 在消費市場中的一種常見應用是家庭自動化。在家庭自動化系統中,通常有一個中央安全網關來管理設備和更廣泛系統的連接。
對于這個項目,我們將演示連接到 ZigBee 控制燈系列的中央網關。
該項目的路線圖是在稍后階段將其與基于智能人工智能的數字鎖連接,該數字鎖將與網關通信并為解鎖人員建立家庭設置。
家庭自動化、PYNQ 和 ZigBee
完全可以直接從 PYNQ 的 Juptyer 筆記本控制和自動化 ZigBee 設備。這有一些很大的好處,例如自定義用戶界面,與其他家庭助理和自動化軟件相比,這本身就非常獨特。不僅如此,我們甚至可以利用這是一個 PYNQ 板這一事實,我們可以利用 PL 來進一步定制我們的應用程序。它非常適合家庭助理社區,令人驚訝的是它相對簡單。讓我們向您展示我們是如何做到的。
特色圖片
方法總結
本節是對本項目中使用的方法進行總結。
PYNQ 框架運行和底層操作系統。PYNQ 框架的底層操作系統是 Ubuntu。稍后我們將利用它來安裝 docker,然后安裝 deCONZ 軟件。
什么是 docker ?
簡單地說,docker 是一種分發軟件的好方法,可以減少多個虛擬機的開銷。Docker 能夠在所謂的“容器”中運行軟件,容器是一個完全打包的軟件,其中包括鏡像、庫和配置文件。由于容器將運行軟件,因此我們不必擔心兼容性問題,并且可以直接按預期運行,只需最少的干預。
為什么使用
Conbee II 使用制造商 Dresden Elektronik 提供的 deCONZ 軟件來連接和控制設備。deCONZ 軟件允許我們通過 Web 應用程序連接和控制設備。使這一切正常工作的原因是 deCONZ Web 應用程序具有內置的 REST API,我們可以從 Juypter Notebook 環境中進行接口!
先決條件 - 硬件
對于此演示將用于硬件:
Arty Z7 賽靈思 ZYNQ 7000
Conbee II USB 網關
智能燈 - 飛利浦 Hue GO 便攜式燈
Arty Z7 能夠運行 PYNQ 框架并具有 USB 插槽。USB 插槽是必需的,因為我們將直接從 Arty Z7 本身使用 ConBee II USB 網關。
Conbee II 是一個很棒的小型 USB 記憶棒,可以連接智能設備,如燈、開關、插座和傳感器。這個小棒適用于從 Windows 到 Ubuntu 的所有平臺,我們將在 PYNQ 上安裝它。
這個項目中的智能燈,是一個通用的藍牙智能燈,您可以在線獲取。您不必購買相同的,但一定要檢查它是否與 Conbee II 兼容。可在此處找到兼容設備的完整列表:https ://phoscon.de/en/conbee2/compatible
設置 PYNQ
開始之前,我們需要從http://www.pynq.io/board.html下載 PYNQ 映像,在撰寫本文時 2.7 版是最新版本。在這里,我們將下載 PYNQ-Z1 圖像,因為它與我們的 Arty Z7 板兼容。
下載后,我們需要將圖像閃存到 SD 卡上。我們將使用 WinDisk32 軟件來刷寫鏡像。注意 刷寫 SD 卡會擦除所有內容。確保 SD 卡上沒有任何內容。
刷機過程完成后。取出 SD 卡并將卡插入 Arty Z7,確保 Boot Jumper 設置為 SD。插入 Arty 并等待 Pynq 映像啟動。
一旦 PYNQ 完成加載,我們需要找到我們的 IP 地址,輸入以下命令。
ifconfig -a
找到我們的IP地址,應該在eth0接口下。這里我們的 IP 地址是 192.168.0.38。記下這一點,我們稍后將需要它。
設置 Docker 和 Docker-Compose
如方法摘要部分所述,我們將安裝 Docker。首先,我們需要將當前用戶添加到撥出組
sudo usermod -a G dialout $USER
接下來我們需要使用以下命令下載 docker 包:
sudo apt-get install docker.io
等待安裝完成。完成后,我們需要安裝 docker compose。Docker compose 是一個使用工具,它將幫助我們創建和修改我們的軟件。
sudo apt-get install docker-compose
使用 docker compose 設置 DeConz
安裝 docker-compose 后,我們接下來需要設置 deCONZ 容器/應用程序,這是與我們的 zigbee 設備進行交互和查找的軟件。
導航到 /opt 文件夾:
cd /opt
接下來我們將創建一個新的 docker-compose.yaml 文件。
這是我們添加和配置容器的文件。
所以,回到創建 yaml 文件。
sudo nano docker-compose.yaml
確保保持縮進正確!
version: "3.2"
services:
? deconz:
? image: deconzcommunity/deconz:latest
? privileged: true
? container_name: deCONZ
? network_mode: host
? restart: always
? volumes:
? ?- type: bind
? ?source: /opt/deconz
? ?target: /opt/deCONZ
? devices:
? - /dev/ttyACM0
? environment:
? ?- TZ=Europe/London
? ?- DECONZ_WEB_PORT=8090
? ?- DECONZ_WS_PORT=443
? ?- DEBUG_INFO=1
? ?- DEBUG_APS=0
? ?- DEBUG_ZCL=0
? ?- DEBUG_ZDP=0
? ?- DEBUG_OTAU=0
這一步將配置容器,以便下載最新版本的 deCONZ 軟件并將我們的門戶網站設置為端口 8090。這是關鍵,因為 PYNQ 使用 Jupyter 筆記本的門戶網站,默認情況下使用端口 80 來訪問網頁和已打開額外的 9090 端口。這就是我們將 deCONZ 應用程序的端口設置為使用 8090 的原因。因為這不會干擾 Pynq Jupyter 的筆記本網絡套接字。
保存 (CTR-S) 并關閉 (CTR-X) 配置。
接下來我們可以使用 docker-compose 啟動 deCONZ 應用程序。輸入以下命令:
sudo docker-compose up -d
這將下載 deCONZ 應用程序并在完成后自動啟動容器。
當我們得到“Done”響應時,讓我們做一個健全性檢查,看看容器是否真的在運行。
sudo docker container ls
容器正在運行。
Conbee II 和 deCONZ 設置
現在在容器中運行 deCONZ 應用程序。我們可以使用以下說明打開 deCONZ 網絡應用程序。
打開 Web 瀏覽器并輸入 IP 和端口號 8090。在我們的實例中,我們的 IP 地址是 192.168.0.32,端口號是:192.168.0.32:8090。
這將打開 Phoscon 網絡應用程序。從下圖中我們可以看到我們的網關點擊圖標開始設置。
在下一頁上,我們需要創建我們的登錄憑據(見下圖)。完成后單擊下一步。
Phoscon 應用程序現在將要求您連接任何燈。您可以現在或以后連接您的燈。我們將連接我們的飛利浦 Hue GO 便攜式燈。確保我們的燈已插入。單擊搜索按鈕。
從上圖中我們可以看到,我們可以看到我們的 Lamp。如果您單擊燈,您可以重命名它以便更容易識別燈。一旦檢測到所有燈。單擊無燈繼續。不用擔心已經檢測到的燈會被記住。
在下一頁上,我們可以創建一個新組來添加燈。下面是一個例子。
創建一個新組,編輯,管理燈光。
將我們的燈添加到組中。我們只有 1 盞燈要添加。單擊綠色加號圖標
單擊保存并按箭頭圖標返回組頁面。
將燈光添加到我們的自定義組中,我們可以控制它。請注意,在 webapp 和燈光下可能會有一些延遲。要有耐心。如果仍然存在問題,請考慮刷新頁面、將設備移近或使用以下命令重新啟動容器:
sudo docker container restart deCONZ
快速測試
單擊燈光選項卡以調整亮度、顏色和飽和度。也可以使用下圖中的圖標更改色溫。
設置 REST API
現在通過燈光設置,我們可以使用 Jupyter 的 Notebook 創建自己的界面。這相對容易。由于 deCONZ 應用程序有一個內置的 API,我們可以通過使用一些簡單的 python 腳本來利用它。
打開一個新的 Web 瀏覽器并導航到 Jupyter 的筆記本頁面。在我們的例子中是 192.168.0.32:80。這將打開熟悉的 jupyter 筆記本。
我們將創建一個新文件夾以保持一切整潔。我們將文件夾命名為 ConBee II,并在該文件夾中創建一個新的 python3 應用程序
REST API 通過發出請求來工作。
我們需要導入一些庫來發出請求。
import requests
import json
接下來,我們需要創建一個請求以獲取 API 密鑰。在新單元格中輸入:
URL = “http://192.168.0.38:8090/api”
device = {‘devicetype’: ‘application’}
p = requests.post(URL, json=device)
pretty_json = json.loads(p.text)
print (json.dumps(pretty_json, indent=2))
運行上面的代碼,我們會收到如下錯誤:
錯誤是未按下鏈接按鈕。這是指身份驗證檢查。我們需要授權第三方應用程序。回到 Phoscon 應用程序并單擊網關選項。
在高級設置下,單擊驗證應用程序。您將有 60 秒的時間重新運行上一步中的代碼。如果在時間內完成,則使用 API 密鑰成功。您現在已經成功驗證了您的應用程序,并且可以開始使用 Jupyter 配置和控制設備。
在 Juypter 中控制我們的設備
現在要發出請求,我們需要提供我們的 API 密鑰。例如,我們希望看到我們的燈光。
# 代表上一步的 API 密鑰
r = requests.get(URL+“/D########9/lights”)
pretty_json = json.loads(r.text)
print (json.dumps(pretty_json, indent=2))
上圖向我們展示了 Philip Hue Lamp 和 ConBee II 設備
請使用命令查看完整列表。使用提供的鏈接:
https://dresden-elektronik.github.io/deconz-rest-doc/
可以修改的參數是“狀態”類別下列出的參數:
這些參數需要請求 PUT 命令。例如,我們可以關閉我們的設備。
使用 Jupyter Notebook 創建自定義界面
既然我們知道如何控制我們的設備,接下來就是將它們集成到 Jupyter 的內置 GUI 創建工具中。我們將使用 ipywidgets 庫。
import ipywidgets
讓我們先來了解一下 Light 的一些基本控件。我們需要一個“開啟開關”和一個“關閉開關”。沒有任何開關,但我們可以使用按鈕。下面的代碼創建了一個將“on”值更改為 True 的按鈕。
btn = widgets.Button(description=‘On’)
display(btn)
def btn_eventhandler(obj):
data = {“on”: True}
r = requests.put(URL+“/D78828C329/lights/1/state”, json = data)
print(“Lamp is On!”)
btn.on_click(btn_eventhandler)
接下來讓我們關掉燈泡。這次我們將“on”值設置為 False。
btn = widgets.Button(description=‘OFF’)
display(btn)
def btn_eventhandler(obj):
data = {“on”: False}
r = requests.put(URL+“/D78828C329/lights/1/state”, json = data)
print(“Lamp is OFF!”)
btn.on_click(btn_eventhandler)
我們甚至可以添加一個顏色選擇器小部件。顏色選擇器小部件返回所選顏色的 RGB 值。然而,這帶來了一個小問題。deCONZ rest api 需要 HSV 中的值。HSV 顏色模型中的色調參數在 0°–360° 之間,映射到 0–65535 以獲得 16 位分辨率。
首先讓我們添加顏色選擇器
colorpicker = widgets.ColorPicker(
concise=False,
description=‘Pick a color’,
value=“#121254”,
disabled=False )
colorpicker ## Click the little blue square
接下來是獲取顏色選擇器中的信息并將值轉換為 deCONZ 軟件可以理解的可用格式。經過無數小時的調試和撓頭。復制以下代碼:
import math?
#print(colorpicker.value)
def RGBtoHSV(colorpicker):
? ? R = int(colorpicker.value[1:3],16)
? ? G = int(colorpicker.value[3:5],16)
? ? B = int(colorpicker.value[5:7],16)
? ? R1 = R/255
? ? G1 = G/255
? ? B1 = B/255
? ? #print(R1)
? ? #print(G1)
? ? #print(B1)
? ? #print("\n")
? ? Cmax = max(R1,G1,B1)
? ? #print(Cmax)
? ? Cmin = min(R1,G1,B1)
? ? #print(Cmin)
? ? delta = Cmax - Cmin
? ? if delta != 0:
? ? ? ? if Cmax == R1:
? ? ? ? ? ? Hue = round(60*(((G1-B1)/delta)%6))
? ? ? ? elif Cmax == G1:
? ? ? ? ? ? Hue = round(60*(((B1-R1)/delta)+2))
? ? ? ? else:
? ? ? ? ? ? Hue = round(60*(((R1-G1)/delta)+4))
? ? else:
? ? ? ? if Cmax == R1:
? ? ? ? ? ? Hue = R1
? ? ? ? if Cmax == G1:
? ? ? ? ? ? Hue = G1
? ? ? ? if Cmax == B1:
? ? ? ? ? ? Hue = B1
? ? if Cmax != 0:
? ? ? ? Sat = 255*(delta/Cmax)
? ? ? ? #print("\nSaturation: {0}% of 255 is {1}".format(round((delta/Cmax)*100), round(Sat)))
? ? else:
? ? ? ? Sat = 0
? ? ? ? #print("Saturation: 0%")
? ? Vis = 255 * Cmax
? ? Hue = round(Hue * ((2**16)/360)) ## Mapped to 360 degrees
? ? #print("Visablity: {0}% of 255 is {1}".format(round((Cmax*100)), Vis))
? ? #print("\nRed {0} Green {1} Blue {2}".format(R,G,B))
? ? #print("Hue {0} Sat {1} Vis {2}".format(Hue,round(Sat),round(Vis)))
? ? #print (json.dumps(pretty_json, indent=2))
? ? return Hue, Sat, Vis
這會正確地從顏色選擇器返回色相、飽和度和可見度。調用此函數:
Hue,Sat,Vis = RGBtoHSV(colorpicker)
接下來是簡單地發送 PUT 請求,Lamp 將根據需要更改顏色。
data = {"on": True,?
? ? ? ? "bri" : Vis,
? ? ? ? "hue" : Hue,
? ? ? ? "sat" : Sat
? ? ? ?}
r = requests.put(URL+"/D78828C329/lights/1/state", json = data)
#print(r)
pretty_json = json.loads(r.text)
#print (json.dumps(pretty_json, indent=2))
對于我們的最后一個示例,我們將使用滑塊控制色相、飽和度和亮度!
有了這個,我們可以改變看到的光。
現在我們已經擁有了我們想要的所有 GUI 元素。我們需要將它們添加在一起以創建一個 GUI。我們可以通過使用 Juypter/Labs 創建我們自己的自定義界面來做到這一點,無需額外修改!
保存并關閉 Python3 筆記本。我們要導航到 Jupyter Labs,在搜索欄中簡單輸入 《ip》:9090/lab。在我們的例子中是 192.168.0.38:9090/lab。這將打開實驗室環境。在這里,我們要導航并打開我們的 python3 文件。
從這里您可以單擊并拖動帶有 UI 的單元格并開始創建獨特的 UI
這是我們非常基本的用戶界面。這可以在新選項卡中打開,如下所示。
評論
查看更多