From b52bd61e34aa9db4865ec5b5f43d6c0860f15011 Mon Sep 17 00:00:00 2001 From: Andrew Linden Date: Wed, 27 Sep 2017 19:39:10 +0300 Subject: [PATCH] Initial commit --- .gitignore | 1 + README.md | 28 ++++++++++++++++++++ index.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 30 ++++++++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 index.js create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 00cbbdf53..f271986e1 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ typings/ # dotenv environment variables file .env +package-lock.json diff --git a/README.md b/README.md index 7594f4a64..ab2636f1e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,30 @@ # xiaomi-zb2mqtt Xiaomi Zigbee to MQTT bridge using zigbee-shepherd + +### To run the bridge + +* Install +```sh +$ git clone https://github.com/AndrewLinden/xiaomi-zb2mqtt.git +$ cd xiaomi-zb2mqtt +/xiaomi-zb2mqtt$ npm install +``` + +* Run it +```sh +/xiaomi-zb2mqtt$ node index.js +``` + +* To see whats happening behind the scenes run it with debug enabled: +```sh +/xiaomi-zb2mqtt$ DEBUG=* node index.js +``` +### Supports +* WXKG01LM +* WXKG02LM + + +### Notes +* You need to flash your CC2531 with CC2531ZNP-Pro-Secure_LinkKeyJoin.hex from here: https://github.com/mtornblad/zstack-1.2.2a.44539/tree/master/CC2531 +* Zigbee shepherd's pairing process can take quite a while (more than a minute). +* When pairing WXKG01LM, after reset you need to toggle (short keypress) the reset button every couple of seconds to keep the switch from going to sleep until the pairing is complete. diff --git a/index.js b/index.js new file mode 100644 index 000000000..6e59f236c --- /dev/null +++ b/index.js @@ -0,0 +1,72 @@ +var util = require("util"); +var perfy = require('perfy'); +var ZShepherd = require('zigbee-shepherd'); +var mqtt = require('mqtt') + +var client = mqtt.connect('mqtt://192.168.1.10') + +var shepherd = new ZShepherd('/dev/ttyACM3', { + net: { + panId: 0x1a61 + } +}); + +shepherd.on('ready', function () { + console.log('Server is ready.'); + + // allow devices to join the network within 60 secs + shepherd.permitJoin(60, function (err) { + if (err) + console.log(err); + }); +}); + +shepherd.on('permitJoining', function (joinTimeLeft) { + console.log(joinTimeLeft); +}); + +shepherd.on('ind', function (msg) { + switch (msg.type) { + case 'devIncoming': + console.log('Device: ' + msg.data + ' joining the network!'); + break; + case 'attReport': + console.log('attreport: ' + msg.endpoints[0].device.ieeeAddr +' '+ msg.endpoints[0].devId +' '+ msg.endpoints[0].epId +' '+util.inspect(msg.data, false, null)); + var topic = 'xiaomiZb/' + msg.endpoints[0].device.ieeeAddr.substr(2) + '/' + msg.endpoints[0].epId; + var pl = '1'; + switch (msg.endpoints[0].devId) { + case 260: // WXKG01LM + if (msg.data.data['onOff'] == 0) { // click down + perfy.start(msg.endpoints[0].device.ieeeAddr); // start timer + pl = ''; // do not send mqtt message + } else if (msg.data.data['onOff'] == 1) { // click release + var clicktime = perfy.end(msg.endpoints[0].device.ieeeAddr); // end timer + if (clicktime.seconds > 0 || clicktime.milliseconds > 240) { // seems like a long press so .. + topic = 'xiaomiZb/' + msg.endpoints[0].device.ieeeAddr.substr(2) + '/2'; //change topic to 2 + pl = clicktime.seconds+Math.floor(clicktime.milliseconds)+''; // and payload to elapsed seconds + } + } else if (msg.data.data['32768']) { // multiple clicks + pl = ''+msg.data.data['32768']; + } + } + if (pl.length > 0) { // only publish message if we have not set payload to null + client.publish(topic, pl); + } + break; + default: + // console.log(util.inspect(msg, false, null)); + // Not deal with other msg.type in this example + break; + } +}); + +client.on('connect', function () { + client.publish('xiaomiZb', 'Bridge online') +}) + + +shepherd.start(function (err) { // start the server + if (err) + console.log(err); +}); + diff --git a/package.json b/package.json new file mode 100644 index 000000000..92c9a0e15 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "xiaomi-zb2mqtt", + "version": "1.0.0", + "description": "Xiaomi Zigbee to MQTT bridge using zigbee-shepherd", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/AndrewLinden/xiaomi-zb2mqtt.git" + }, + "keywords": [ + "xiaomi", + "zigbee", + "mqtt", + "cc2531" + ], + "author": "Andrew Linden", + "license": "GPL-3.0", + "bugs": { + "url": "https://github.com/AndrewLinden/xiaomi-zb2mqtt/issues" + }, + "homepage": "https://github.com/AndrewLinden/xiaomi-zb2mqtt#readme", + "dependencies": { + "mqtt": "^2.13.0", + "perfy": "^1.1.2", + "zigbee-shepherd": "git+https://github.com/AndrewLinden/zigbee-shepherd.git" + } +}