這個智能控制系統採用 ZigBee 做爲無線通訊協議。
在支持 OpenWRT 系統的路由器上刷入 Ruff,利用 ZigBee-USB dongle 模塊,和其餘 ZigBee 終端設備通訊,實現遙控功能。html
極路由3 ,已刷入 Ruff。json
ZigBee-USB dongle 模塊 網絡
ZigBee 燈 app
小米 ZigBee 開關 this
初始化 APP $ rap init
spa
添加 zigbee 驅動,id 爲 zigbee ,型號選擇 jn5168a
$ rap device add zigbee (jn5168a)
prototype
編寫 src/index.js
代碼code
'use strict'; var zigbee; $.ready(function (error) { if (error) { console.log(error); return; } zigbee = $('#zigbee'); zigbee.startup(); zigbee.setTurnLightOn(); zigbee.setTurnLightOff(); zigbee.setToggleLight(); }); $.end(function () { });
改寫板卡描述 board.json
router
因爲路由器上沒有 GPIO 之類的接口,因此咱們要改寫板卡描述文件 ruff_modules/ruff-mbd-v1/board.json
。視頻
{ "version": "2.0", "id": "ruff-mbd-v1", "model": "ruff-mbd-v1", "preloads": { "uart-0": "uart-0/uart" }, "outputs": { "uart-0": "uart-0/uart", "gnd-0": "ground/gnd-0", "vdd-0": "power/vdd-0" }, "devices": [ { "id": "ground", "outputs": { "gnd-0": { "type": "ground" } } }, { "id": "power", "outputs": { "vdd-0": { "type": "power", "args": { "voltage": "3.3v" } } } }, { "id": "uart-0", "model": "ruff-sys-uart", "driver": "sys-uart", "inputs": { "device": { "type": "string", "args": { "path": "/dev/ttyUSB0" } } }, "outputs": { "uart" : { "type":"uart" } } } ] }
5.部署代碼
`$ rap deploy your-router-ip -s`
如下三個部分分別從
ZigBee 網絡包的組成
ZigBee 網絡的組建
開關燈控制
三個方面,來介紹 ZigBee 驅動模塊。
以開關燈的控制協議來看 ZigBee 的組包過程:
start = 0x1 end = 0x3 data = [0x2, 0x44, 0xa6, 0x1, 0x1, 0x1] msgType = 146 = 0x92 (OnOff) msgLen = 0x6 crc = 0x92 ^ 0x6 ^ 0x2 ^ 0x44 ^ 0xa6 ^ 0x1 ^ 0x1 ^ 0x1 = 0x75 ----------------------------------------------------------------------------------- | 0x1 | 0x92 | 0x6 | 0x75 | 0x2, 0x44, 0xa6, 0x1, 0x1, 0x1 | 0x3 | ----------------------------------------------------------------------------------- | start | msgType | msgLen | crc | Data | stop | -----------------------------------------------------------------------------------
包的首尾是開始和結束標誌。前三個字段分別是message type, message length, CRC checksum, 以後就是具體的控制數據。
因爲要在包內容裏避免使用開頭或者結尾的標誌字段,因此須要對源包內容進行轉義,轉義示意以下。
0x00 0x92 -> 0x2 0x10^0x00 0x92 ------------------------------------------------------------------------------------------------------------ | 0x1 | 0x2 0x10 0x92 | 0x2 0x10 0x2 0x16 | 0x75 | 0x2 0x12 0x44 0xa6 0x2 0x11 0x2 0x11 0x2 0x11 | 0x3 | ------------------------------------------------------------------------------------------------------------ | start | msgType | msgLen | crc | Data | stop | ------------------------------------------------------------------------------------------------------------
解包是組包的逆過程。
解析而是依據ZigBee協議的數據手冊(JN-AN-1194-ZigBee-IoT-Gateway-Control-Bridge pdf),一一對照着解析包的內容。
根據數據手冊,ZigBee初始化組建網絡須要通過如下幾個步驟:
this.getVersion(); this.setExtendedPANID(); this.setChannelMask(); this.setSecurityStateAndKey(); this.setDeviceType(); this.startNetwork(); this.permitJoiningRequest();
在這以後,ZigBee 網絡處於開放狀態,能夠接受鏈接請求。咱們就能夠接入上面展現的 ZigBee 燈和開關了。
ZigBee 協議裏有直接控制開關的通訊類型,經過查找 ZigBee 數據手冊,能夠找到以下信息:
利用這個通訊類型,咱們寫的開關燈的代碼是這樣的。
ZigBee.prototype.turnLightOn = function () { console.log('turn light on'); var devices = interpreter.getDeviceList(); var msg = new Buffer([0x2, 0xff, 0xff, 0x1, 0x1, 0x1]); if (devices.length !== 0) { msg.writeUInt16BE(devices[0].shortAddress, 1); } this._writeCmd(0x92, msg); } ZigBee.prototype.turnLightOff = function () { console.log('turn light off'); var devices = interpreter.getDeviceList(); var msg = new Buffer([0x2, 0xff, 0xff, 0x1, 0x1, 0x0]); if (devices.length !== 0) { msg.writeUInt16BE(devices[0].shortAddress, 1); } this._writeCmd(0x92, msg); } ZigBee.prototype.toggleLight = function () { console.log('toggle light'); var devices = interpreter.getDeviceList(); var msg = new Buffer([0x2, 0xff, 0xff, 0x1, 0x1, 0x2]); if (devices.length !== 0) { msg.writeUInt16BE(devices[0].shortAddress, 1); } this._writeCmd(0x92, msg); }