diff --git a/README.md b/README.md index 1529dbc..c8f5371 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ The following devices are currently supported: * Motion sensor * Power plug (zigbee) * Power plug (wifi) +* Yeelight White (mono) +* Yeelight RGB ## Preperation @@ -42,13 +44,13 @@ Tip: use the configurator from the side-panel (hamburger menu, configuration nod ### How to use different nodes -Here an example of how to use the different nodes (screenshot of [importable flows-overview.json](flows-overview.json "Mi Devices overview")): +Here an example of how to use the different nodes (screenshot of [importable flows-overview.json](flows-overview.json?raw=true "Mi Devices overview")): ![Mi devices example in node-red](resources/mi-devices-overview.png?raw=true "Mi devices example in node-red") ### Sample flows -Here are different flow (screenshot of [importable flows-sample.json](flows-sample.json "Different flows using Mi Devices")): +Here are different flow (screenshot of [importable flows-sample.json](flows-sample.json?raw=true "Different flows using Mi Devices")): ![Mi devices example in node-red](resources/mi-devices-sample.png?raw=true "Mi devices flow sample") ## Enable LAN mode @@ -59,7 +61,7 @@ Here are different flow (screenshot of [importable flows-sample.json](flows-samp 2. Make sure you set your region to: Mainland China under settings -> Locale - required for the moment. Mainland China and language can set on English. 3. Select your Gateway in Mi Home -4. Then the 3 dots at the top right of the screen +4. Then click the 3 dots at the top right of the screen 5. Then click on about 6. Tap under Tutorial menu (on the blank part) repeatedly 7. You should see now 3 extra options listed in Chinese until you did now enable the developer mode (like the first screenshot below, if not try all steps again!) @@ -72,6 +74,19 @@ If you change here something, you lose your password! ![Gateway advanced mode](resources/xiaomi-gateway-advanced-mode.png?raw=true "Gateway advanced mode") ![Gateway LAN mode enabled](resources/xiaomi-gateway-lan-enabled.png?raw=true "Gateway LAN mode enabled") +### Yeelight + +1. Install Yeelight App +2. Select your Yeelight in Mi Home +3. Then click the third icon at the bottom of the screen +4. Then click on the lightning icon "LAN control" +5. In the new panel, toggle the switch to "on" + +The lightning icon should be underline un yellow. + +![Yeelight options](resources/xiaomi-yeelight-options.png?raw=true "Yeelight options") +![Yeelight LAN mode enabled](resources/xiaomi-yeelight-lan-enabled.png?raw=true "Yeelight LAN mode enabled") + ## Sources * [Harald Rietman node-red module](https://github.com/hrietman/node-red-contrib-xiaomi-devices) @@ -79,6 +94,7 @@ If you change here something, you lose your password! * [louisZl Gateway Local API](https://github.com/louisZL/lumi-gateway-local-api) * [Domoticz Gateway Code](https://github.com/domoticz/domoticz/blob/development/hardware/XiaomiGateway.cpp) * [Node-red UDP nodes](https://github.com/node-red/node-red/blob/master/nodes/core/io/32-udp.js) +* [Yeelight specs](http://www.yeelight.com/download/Yeelight_Inter-Operation_Spec.pdf) ## Credits diff --git a/flows-overview.json b/flows-overview.json index b30275d..18d45ac 100644 --- a/flows-overview.json +++ b/flows-overview.json @@ -1,477 +1 @@ -[ - { - "id": "d6af659e.672c78", - "type": "tab", - "label": "Mi Devices Overview", - "disabled": false, - "info": "" - }, - { - "id": "8b46a76a.3750f8", - "type": "xiaomi-gateway in", - "z": "d6af659e.672c78", - "name": "", - "gateway": "", - "ip": "", - "x": 100, - "y": 260, - "wires": [ - [ - "c6c7895f.ca9ed", - "fff96479.f72ff8", - "896173ae.aff0c", - "55f81bbe.cdf944", - "e3bc2a33.7bc178", - "6b4e0181.7aac38" - ] - ] - }, - { - "id": "c6c7895f.ca9ed", - "type": "xiaomi-ht", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "sid": "", - "x": 420, - "y": 120, - "wires": [ - [ - "a196a200.9d0ca8" - ] - ] - }, - { - "id": "fff96479.f72ff8", - "type": "xiaomi-magnet", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "sid": "", - "x": 440, - "y": 180, - "wires": [ - [ - "a196a200.9d0ca8" - ] - ] - }, - { - "id": "896173ae.aff0c", - "type": "xiaomi-motion", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "sid": "", - "motionmsg": "", - "nomotionmsg": "", - "output": "0", - "x": 440, - "y": 240, - "wires": [ - [ - "a196a200.9d0ca8" - ] - ] - }, - { - "id": "55f81bbe.cdf944", - "type": "xiaomi-switch", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "sid": "", - "outmsg": "{{click}}", - "outmsgdbcl": "{{double_click}}", - "output": "0", - "x": 440, - "y": 300, - "wires": [ - [ - "a196a200.9d0ca8" - ] - ] - }, - { - "id": "e3bc2a33.7bc178", - "type": "xiaomi-gateway", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "x": 440, - "y": 360, - "wires": [ - [ - "a196a200.9d0ca8" - ] - ] - }, - { - "id": "6b4e0181.7aac38", - "type": "xiaomi-plug", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "sid": "", - "onmsg": "", - "offmsg": "", - "output": "0", - "x": 430, - "y": 420, - "wires": [ - [ - "a196a200.9d0ca8" - ] - ] - }, - { - "id": "a196a200.9d0ca8", - "type": "debug", - "z": "d6af659e.672c78", - "name": "", - "active": true, - "console": "false", - "complete": "true", - "x": 790, - "y": 280, - "wires": [] - }, - { - "id": "fced461e.36cda", - "type": "xiaomi-ht", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "sid": "", - "x": 480, - "y": 580, - "wires": [ - [ - "f2d6b99.0cc43c8" - ] - ] - }, - { - "id": "5f9390f2.5a3798", - "type": "xiaomi-magnet", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "sid": "", - "x": 500, - "y": 640, - "wires": [ - [ - "f2d6b99.0cc43c8" - ] - ] - }, - { - "id": "727ea237.226064", - "type": "xiaomi-motion", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "sid": "", - "motionmsg": "", - "nomotionmsg": "", - "output": "0", - "x": 500, - "y": 700, - "wires": [ - [ - "f2d6b99.0cc43c8" - ] - ] - }, - { - "id": "9b7afab9.3b9d28", - "type": "xiaomi-switch", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "sid": "", - "outmsg": "{{click}}", - "outmsgdbcl": "{{double_click}}", - "output": "0", - "x": 500, - "y": 760, - "wires": [ - [ - "f2d6b99.0cc43c8", - "87e3d24d.dca938", - "17f55e85.67fa39" - ] - ] - }, - { - "id": "56b84611.e528d", - "type": "xiaomi-gateway", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "x": 500, - "y": 820, - "wires": [ - [ - "f2d6b99.0cc43c8", - "63506419.25ea9c", - "802789b5.325168", - "f5d2d9a.c0cfaa8", - "714e9c81.a6814c" - ] - ] - }, - { - "id": "f56c4e2.98543b", - "type": "inject", - "z": "d6af659e.672c78", - "name": "", - "topic": "", - "payload": "", - "payloadType": "date", - "repeat": "", - "crontab": "", - "once": false, - "x": 100, - "y": 700, - "wires": [ - [ - "fced461e.36cda", - "5f9390f2.5a3798", - "727ea237.226064", - "9b7afab9.3b9d28", - "56b84611.e528d", - "cde54564.5db488", - "2e035ef8.13ee12", - "6e073d99.348974", - "5d917375.467da4" - ] - ] - }, - { - "id": "cde54564.5db488", - "type": "xiaomi-plug", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "sid": "", - "onmsg": "", - "offmsg": "", - "output": "0", - "x": 490, - "y": 880, - "wires": [ - [ - "f2d6b99.0cc43c8", - "6dde3295.cc1f94", - "bc27b766.47eb" - ] - ] - }, - { - "id": "2e035ef8.13ee12", - "type": "xiaomi-plug-wifi", - "z": "d6af659e.672c78", - "name": "", - "ip": "", - "onmsg": "", - "offmsg": "", - "output": "0", - "x": 500, - "y": 940, - "wires": [ - [] - ] - }, - { - "id": "f2d6b99.0cc43c8", - "type": "xiaomi-actions read", - "z": "d6af659e.672c78", - "name": "", - "x": 810, - "y": 580, - "wires": [ - [ - "39eb644e.a67c94" - ] - ] - }, - { - "id": "63506419.25ea9c", - "type": "xiaomi-actions get_id_list", - "z": "d6af659e.672c78", - "name": "", - "x": 820, - "y": 800, - "wires": [ - [ - "39eb644e.a67c94" - ] - ] - }, - { - "id": "802789b5.325168", - "type": "xiaomi-actions gateway_light", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "brightness": 100, - "hexRgbColor": "#ffffff", - "color": { - "red": 255, - "green": 255, - "blue": 255 - }, - "x": 820, - "y": 840, - "wires": [ - [ - "39eb644e.a67c94" - ] - ] - }, - { - "id": "f5d2d9a.c0cfaa8", - "type": "xiaomi-actions gateway_sound", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "mid": "", - "volume": "", - "x": 830, - "y": 880, - "wires": [ - [ - "39eb644e.a67c94" - ] - ] - }, - { - "id": "714e9c81.a6814c", - "type": "xiaomi-actions gateway_stop_sound", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "x": 830, - "y": 920, - "wires": [ - [ - "39eb644e.a67c94" - ] - ] - }, - { - "id": "6dde3295.cc1f94", - "type": "xiaomi-actions on", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "x": 820, - "y": 980, - "wires": [ - [ - "39eb644e.a67c94" - ] - ] - }, - { - "id": "bc27b766.47eb", - "type": "xiaomi-actions off", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "x": 820, - "y": 1020, - "wires": [ - [ - "39eb644e.a67c94" - ] - ] - }, - { - "id": "87e3d24d.dca938", - "type": "xiaomi-actions click", - "z": "d6af659e.672c78", - "name": "", - "x": 810, - "y": 680, - "wires": [ - [ - "39eb644e.a67c94" - ] - ] - }, - { - "id": "17f55e85.67fa39", - "type": "xiaomi-actions double_click", - "z": "d6af659e.672c78", - "name": "", - "x": 830, - "y": 720, - "wires": [ - [ - "39eb644e.a67c94" - ] - ] - }, - { - "id": "39eb644e.a67c94", - "type": "xiaomi-gateway out", - "z": "d6af659e.672c78", - "name": "", - "gateway": "", - "ip": "", - "x": 1200, - "y": 780, - "wires": [] - }, - { - "id": "6e073d99.348974", - "type": "xiaomi-actions on", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "x": 280, - "y": 920, - "wires": [ - [ - "2e035ef8.13ee12" - ] - ] - }, - { - "id": "5d917375.467da4", - "type": "xiaomi-actions off", - "z": "d6af659e.672c78", - "gateway": "", - "name": "", - "x": 280, - "y": 960, - "wires": [ - [ - "2e035ef8.13ee12" - ] - ] - }, - { - "id": "bd81cdbf.1964", - "type": "comment", - "z": "d6af659e.672c78", - "name": "Filter incoming", - "info": "", - "x": 420, - "y": 40, - "wires": [] - }, - { - "id": "99d83097.bf0968", - "type": "comment", - "z": "d6af659e.672c78", - "name": "Outgoing", - "info": "", - "x": 420, - "y": 500, - "wires": [] - } -] +[{"id":"b7132358.47476","type":"tab","label":"Mi Devices Overview","disabled":false,"info":""},{"id":"37ac569b.b3ef02","type":"xiaomi-gateway in","z":"b7132358.47476","name":"","gateway":"","ip":"","x":100,"y":220,"wires":[["b7bdc18a.4b45","94672654.872fb","b03e7c0c.d344e","540ce4ae.b5a26c","a6d2ae60.7ee088","bb36a54.ac665d8","3229d6fd.1e35fa"]]},{"id":"b7bdc18a.4b45","type":"xiaomi-ht","z":"b7132358.47476","gateway":"","name":"","sid":"","x":420,"y":140,"wires":[["37052c54.e2b62c"]]},{"id":"94672654.872fb","type":"xiaomi-magnet","z":"b7132358.47476","gateway":"","name":"","sid":"","x":440,"y":180,"wires":[["37052c54.e2b62c"]]},{"id":"b03e7c0c.d344e","type":"xiaomi-motion","z":"b7132358.47476","gateway":"","name":"","sid":"","motionmsg":"","nomotionmsg":"","output":"0","x":440,"y":220,"wires":[["37052c54.e2b62c"]]},{"id":"540ce4ae.b5a26c","type":"xiaomi-switch","z":"b7132358.47476","gateway":"","name":"","sid":"","x":440,"y":260,"wires":[["37052c54.e2b62c"]]},{"id":"a6d2ae60.7ee088","type":"xiaomi-gateway","z":"b7132358.47476","gateway":"","name":"","x":440,"y":300,"wires":[["37052c54.e2b62c"]]},{"id":"bb36a54.ac665d8","type":"xiaomi-plug","z":"b7132358.47476","gateway":"","name":"","sid":"","onmsg":"","offmsg":"","output":"0","x":430,"y":340,"wires":[["37052c54.e2b62c"]]},{"id":"37052c54.e2b62c","type":"debug","z":"b7132358.47476","name":"","active":true,"console":"false","complete":"true","x":710,"y":220,"wires":[]},{"id":"a2db7256.81c91","type":"xiaomi-ht","z":"b7132358.47476","gateway":"","name":"","sid":"","x":480,"y":560,"wires":[["ee6734f2.6e1e6"]]},{"id":"1f15867.488737a","type":"xiaomi-magnet","z":"b7132358.47476","gateway":"","name":"","sid":"","x":500,"y":600,"wires":[["ee6734f2.6e1e6"]]},{"id":"36a62693.5c11b2","type":"xiaomi-motion","z":"b7132358.47476","gateway":"","name":"","sid":"","motionmsg":"","nomotionmsg":"","output":"0","x":500,"y":640,"wires":[["ee6734f2.6e1e6"]]},{"id":"79681c1e.90ebdc","type":"xiaomi-switch","z":"b7132358.47476","gateway":"","name":"","sid":"","x":500,"y":700,"wires":[["ee6734f2.6e1e6","9e60c17d.8a64a8","6d2591a6.89d498"]]},{"id":"d5fb64b6.8e94e8","type":"xiaomi-gateway","z":"b7132358.47476","gateway":"","name":"","x":500,"y":760,"wires":[["ee6734f2.6e1e6","ff64227b.22f8a","92cbad8e.098568","520452ff.0f57e4","87e164af.8c453"]]},{"id":"6f3e29cc.ab17e","type":"inject","z":"b7132358.47476","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":100,"y":700,"wires":[["a2db7256.81c91","1f15867.488737a","36a62693.5c11b2","79681c1e.90ebdc","d5fb64b6.8e94e8","3ae7a6cd.805cda","61d3e354.cc9f7c","f9105b74.d9fc5","48720e7b.df608","2e3bfe95.2f5a9a","39683881.e496b8","1e24075e.7c64a9","e3216d45.144648"]]},{"id":"3ae7a6cd.805cda","type":"xiaomi-plug","z":"b7132358.47476","gateway":"","name":"","sid":"","onmsg":"","offmsg":"","output":"0","x":490,"y":820,"wires":[["ee6734f2.6e1e6","b46eec04.6a401","53516e47.bdb338"]]},{"id":"61d3e354.cc9f7c","type":"xiaomi-plug-wifi","z":"b7132358.47476","name":"","ip":"","onmsg":"","offmsg":"","output":"0","x":500,"y":880,"wires":[[]]},{"id":"ee6734f2.6e1e6","type":"xiaomi-actions read","z":"b7132358.47476","name":"","x":810,"y":580,"wires":[["1aa456d0.dea0e9"]]},{"id":"ff64227b.22f8a","type":"xiaomi-actions get_id_list","z":"b7132358.47476","name":"","x":820,"y":800,"wires":[["1aa456d0.dea0e9"]]},{"id":"92cbad8e.098568","type":"xiaomi-actions gateway_light","z":"b7132358.47476","name":"","brightness":100,"hexRgbColor":"#ffffff","color":{"red":255,"green":255,"blue":255},"x":820,"y":840,"wires":[["1aa456d0.dea0e9"]]},{"id":"520452ff.0f57e4","type":"xiaomi-actions gateway_sound","z":"b7132358.47476","name":"","mid":"","volume":"","x":830,"y":880,"wires":[["1aa456d0.dea0e9"]]},{"id":"87e164af.8c453","type":"xiaomi-actions gateway_stop_sound","z":"b7132358.47476","name":"","x":830,"y":920,"wires":[["1aa456d0.dea0e9"]]},{"id":"b46eec04.6a401","type":"xiaomi-actions on","z":"b7132358.47476","name":"","x":820,"y":980,"wires":[["1aa456d0.dea0e9"]]},{"id":"53516e47.bdb338","type":"xiaomi-actions off","z":"b7132358.47476","name":"","x":820,"y":1020,"wires":[["1aa456d0.dea0e9"]]},{"id":"9e60c17d.8a64a8","type":"xiaomi-actions click","z":"b7132358.47476","name":"","x":810,"y":680,"wires":[["1aa456d0.dea0e9"]]},{"id":"6d2591a6.89d498","type":"xiaomi-actions double_click","z":"b7132358.47476","name":"","x":830,"y":720,"wires":[["1aa456d0.dea0e9"]]},{"id":"1aa456d0.dea0e9","type":"xiaomi-gateway out","z":"b7132358.47476","name":"","gateway":"","ip":"","x":1200,"y":780,"wires":[]},{"id":"f9105b74.d9fc5","type":"xiaomi-actions on","z":"b7132358.47476","name":"","x":280,"y":860,"wires":[["61d3e354.cc9f7c"]]},{"id":"48720e7b.df608","type":"xiaomi-actions off","z":"b7132358.47476","name":"","x":280,"y":900,"wires":[["61d3e354.cc9f7c"]]},{"id":"29bb58e2.28de","type":"comment","z":"b7132358.47476","name":"Filter incoming","info":"","x":420,"y":40,"wires":[]},{"id":"33967b37.6d4e44","type":"comment","z":"b7132358.47476","name":"Outgoing","info":"","x":420,"y":500,"wires":[]},{"id":"a39ea960.771b88","type":"xiaomi-yeelight out","z":"b7132358.47476","name":"","ip":"","port":55443,"x":490,"y":1040,"wires":[]},{"id":"2e3bfe95.2f5a9a","type":"xiaomi-actions on","z":"b7132358.47476","name":"","x":280,"y":980,"wires":[["a39ea960.771b88"]]},{"id":"39683881.e496b8","type":"xiaomi-actions off","z":"b7132358.47476","name":"","x":280,"y":1020,"wires":[["a39ea960.771b88"]]},{"id":"1e24075e.7c64a9","type":"xiaomi-actions toggle","z":"b7132358.47476","name":"","x":290,"y":1060,"wires":[["a39ea960.771b88"]]},{"id":"e3216d45.144648","type":"xiaomi-actions gateway_light","z":"b7132358.47476","name":"","brightness":100,"hexRgbColor":"#ffffff","color":{"red":255,"green":255,"blue":255},"x":280,"y":1100,"wires":[["a39ea960.771b88"]]},{"id":"3229d6fd.1e35fa","type":"xiaomi-all","z":"b7132358.47476","gateway":"","name":"","onlyModels":[],"excludedSids":[],"x":420,"y":100,"wires":[["37052c54.e2b62c"]]}] \ No newline at end of file diff --git a/flows-sample.json b/flows-sample.json index 682912b..8f71180 100644 --- a/flows-sample.json +++ b/flows-sample.json @@ -1,586 +1 @@ -[ - { - "id": "821cff63.382248", - "type": "tab", - "label": "Mi Devices Sample", - "disabled": false, - "info": "" - }, - { - "id": "6caf94b0.f846f4", - "type": "comment", - "z": "821cff63.382248", - "name": "Get all sensors and gateway statuses", - "info": "", - "x": 390, - "y": 40, - "wires": [] - }, - { - "id": "e28ead99.c33338", - "type": "inject", - "z": "821cff63.382248", - "name": "", - "topic": "", - "payload": "", - "payloadType": "date", - "repeat": "", - "crontab": "", - "once": true, - "x": 107.14285714285711, - "y": 95, - "wires": [ - [ - "db3b7e35.9432a8", - "eae70f40.0c904" - ] - ] - }, - { - "id": "db3b7e35.9432a8", - "type": "xiaomi-all", - "z": "821cff63.382248", - "gateway": "", - "name": "", - "x": 300, - "y": 100, - "wires": [ - [ - "2e706194.3c27ee" - ] - ] - }, - { - "id": "eae70f40.0c904", - "type": "xiaomi-gateway", - "z": "821cff63.382248", - "gateway": "", - "name": "", - "x": 320, - "y": 160, - "wires": [ - [ - "aa109dae.2d9438" - ] - ] - }, - { - "id": "2e706194.3c27ee", - "type": "split", - "z": "821cff63.382248", - "name": "", - "splt": "\\n", - "spltType": "str", - "arraySplt": 1, - "arraySpltType": "len", - "stream": false, - "addname": "", - "x": 490, - "y": 100, - "wires": [ - [ - "e1cbbde3.9a2ab8" - ] - ] - }, - { - "id": "e1cbbde3.9a2ab8", - "type": "change", - "z": "821cff63.382248", - "name": "set id", - "rules": [ - { - "t": "set", - "p": "sid", - "pt": "msg", - "to": "payload.sid", - "tot": "msg" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 650, - "y": 100, - "wires": [ - [ - "aa109dae.2d9438" - ] - ] - }, - { - "id": "aa109dae.2d9438", - "type": "xiaomi-actions read", - "z": "821cff63.382248", - "name": "", - "x": 810, - "y": 100, - "wires": [ - [ - "d42a0577.a9bbb" - ] - ] - }, - { - "id": "d42a0577.a9bbb", - "type": "xiaomi-gateway out", - "z": "821cff63.382248", - "name": "", - "gateway": "", - "ip": "", - "x": 1000, - "y": 100, - "wires": [] - }, - { - "id": "43eaf652.25b4b8", - "type": "comment", - "z": "821cff63.382248", - "name": "Check if a window at least one window open", - "info": "", - "x": 410, - "y": 300, - "wires": [] - }, - { - "id": "2df06b27.29db24", - "type": "xiaomi-all", - "z": "821cff63.382248", - "gateway": "", - "name": "", - "x": 300, - "y": 360, - "wires": [ - [ - "219409ac.757b0e", - "b6ad7f55.18f99" - ] - ] - }, - { - "id": "e1ff739f.b36108", - "type": "split", - "z": "821cff63.382248", - "name": "", - "splt": "\\n", - "spltType": "str", - "arraySplt": 1, - "arraySpltType": "len", - "stream": false, - "addname": "", - "x": 630, - "y": 360, - "wires": [ - [ - "f03d4922.cee86" - ] - ] - }, - { - "id": "219409ac.757b0e", - "type": "function", - "z": "821cff63.382248", - "name": "filter windows", - "func": "let windowSensors = msg.payload.filter((e) => {\n return e.model === \"magnet\";\n});\nmsg.payload = windowSensors;\nreturn msg;", - "outputs": 1, - "noerr": 0, - "x": 460, - "y": 360, - "wires": [ - [ - "e1ff739f.b36108" - ] - ] - }, - { - "id": "f03d4922.cee86", - "type": "change", - "z": "821cff63.382248", - "name": "set id", - "rules": [ - { - "t": "set", - "p": "sid", - "pt": "msg", - "to": "payload.sid", - "tot": "msg" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 770, - "y": 360, - "wires": [ - [ - "fc9ceef6.4b5ab" - ] - ] - }, - { - "id": "fc9ceef6.4b5ab", - "type": "xiaomi-actions read", - "z": "821cff63.382248", - "name": "", - "x": 910, - "y": 360, - "wires": [ - [ - "5b0ada34.5af104" - ] - ] - }, - { - "id": "5b0ada34.5af104", - "type": "xiaomi-gateway out", - "z": "821cff63.382248", - "name": "", - "gateway": "", - "ip": "", - "x": 1100, - "y": 360, - "wires": [] - }, - { - "id": "d9ffa93a.e40638", - "type": "xiaomi-gateway in", - "z": "821cff63.382248", - "name": "", - "gateway": "", - "ip": "", - "x": 100, - "y": 480, - "wires": [ - [ - "1c6df817.0a0bb" - ] - ] - }, - { - "id": "1c6df817.0a0bb", - "type": "function", - "z": "821cff63.382248", - "name": "set window sensor value", - "func": "if ([\"magnet\", \"sensor_magnet.aq2\"].indexOf(msg.payload.model) >= 0 && msg.payload.sid !== \"158d0001ab1fa8\") {\n let globalKey = `windowSensorStatus-${msg.payload.sid}`;\n global.set(globalKey, msg.payload.data.status);\n}\n", - "outputs": "0", - "noerr": 0, - "x": 330, - "y": 480, - "wires": [] - }, - { - "id": "e030edc3.f85a18", - "type": "function", - "z": "821cff63.382248", - "name": "get window sensors values", - "func": "let windowSensors = {};\nmsg.payload.filter((e) => {\n return e.model === \"magnet\";\n}).forEach((e) => {\n let globalKey = `windowSensorStatus-${e.sid}`;\n let value = global.get(globalKey);\n if(!value || value == \"open\") {\n windowSensors[e.sid] = value || \"na\";\n }\n});\n\nmsg.payload = windowSensors;\nif(Object.keys(windowSensors).length) {\n return [msg, null];\n}\nreturn [null, msg];", - "outputs": "2", - "noerr": 0, - "x": 680, - "y": 420, - "wires": [ - [], - [] - ], - "outputLabels": [ - "at least one window is open", - "all windows are close" - ] - }, - { - "id": "b6ad7f55.18f99", - "type": "delay", - "z": "821cff63.382248", - "name": "", - "pauseType": "delay", - "timeout": "500", - "timeoutUnits": "milliseconds", - "rate": "1", - "nbRateUnits": "1", - "rateUnits": "second", - "randomFirst": "1", - "randomLast": "5", - "randomUnits": "seconds", - "drop": false, - "x": 450, - "y": 420, - "wires": [ - [ - "e030edc3.f85a18" - ] - ] - }, - { - "id": "7838f0b6.d0ea5", - "type": "comment", - "z": "821cff63.382248", - "name": "Doorbell", - "info": "", - "x": 300, - "y": 580, - "wires": [] - }, - { - "id": "8de3e2f.b76f2a", - "type": "xiaomi-gateway in", - "z": "821cff63.382248", - "name": "", - "gateway": "", - "ip": "", - "x": 100, - "y": 660, - "wires": [ - [ - "f96c8911.21e9" - ] - ] - }, - { - "id": "26684d11.692aa2", - "type": "function", - "z": "821cff63.382248", - "name": "is click", - "func": "if(msg.payload.cmd === \"report\" && msg.payload.data.status == \"click\") {\n return msg;\n}\nreturn null;", - "outputs": "1", - "noerr": 0, - "x": 470, - "y": 660, - "wires": [ - [ - "2be5185d.959f2", - "1d76619d.106536", - "1afbffce.6c1d2" - ] - ] - }, - { - "id": "2be5185d.959f2", - "type": "xiaomi-actions gateway_sound", - "z": "821cff63.382248", - "gateway": "", - "name": "", - "mid": "10", - "volume": "20", - "x": 650, - "y": 640, - "wires": [ - [ - "7fa04a92.0851dc" - ] - ] - }, - { - "id": "7fa04a92.0851dc", - "type": "xiaomi-gateway out", - "z": "821cff63.382248", - "name": "", - "gateway": "", - "ip": "", - "x": 1260, - "y": 640, - "wires": [] - }, - { - "id": "21b53d98.e9ecca", - "type": "template", - "z": "821cff63.382248", - "name": "off", - "field": "brightness", - "fieldType": "msg", - "format": "handlebars", - "syntax": "plain", - "template": "0", - "output": "str", - "x": 850, - "y": 800, - "wires": [ - [ - "7bac4ce.ffef434" - ] - ] - }, - { - "id": "1d76619d.106536", - "type": "template", - "z": "821cff63.382248", - "name": "on", - "field": "brightness", - "fieldType": "msg", - "format": "handlebars", - "syntax": "plain", - "template": "100", - "output": "str", - "x": 850, - "y": 760, - "wires": [ - [ - "7bac4ce.ffef434" - ] - ] - }, - { - "id": "7bac4ce.ffef434", - "type": "xiaomi-actions gateway_light", - "z": "821cff63.382248", - "gateway": "", - "name": "", - "x": 1000, - "y": 760, - "wires": [ - [ - "7fa04a92.0851dc" - ] - ] - }, - { - "id": "1afbffce.6c1d2", - "type": "delay", - "z": "821cff63.382248", - "name": "500ms", - "pauseType": "delay", - "timeout": "500", - "timeoutUnits": "milliseconds", - "rate": "1", - "nbRateUnits": "1", - "rateUnits": "second", - "randomFirst": "1", - "randomLast": "5", - "randomUnits": "seconds", - "drop": false, - "x": 650, - "y": 720, - "wires": [ - [ - "21b53d98.e9ecca", - "ad79b644.f7e05" - ] - ] - }, - { - "id": "ad79b644.f7e05", - "type": "delay", - "z": "821cff63.382248", - "name": "500ms", - "pauseType": "delay", - "timeout": "500", - "timeoutUnits": "milliseconds", - "rate": "1", - "nbRateUnits": "1", - "rateUnits": "second", - "randomFirst": "1", - "randomLast": "5", - "randomUnits": "seconds", - "drop": false, - "x": 650, - "y": 760, - "wires": [ - [ - "1d76619d.106536", - "8916da4a.6aeb58" - ] - ] - }, - { - "id": "8916da4a.6aeb58", - "type": "delay", - "z": "821cff63.382248", - "name": "500ms", - "pauseType": "delay", - "timeout": "500", - "timeoutUnits": "milliseconds", - "rate": "1", - "nbRateUnits": "1", - "rateUnits": "second", - "randomFirst": "1", - "randomLast": "5", - "randomUnits": "seconds", - "drop": false, - "x": 650, - "y": 800, - "wires": [ - [ - "21b53d98.e9ecca", - "b83a24c8.4d0f38" - ] - ] - }, - { - "id": "b83a24c8.4d0f38", - "type": "delay", - "z": "821cff63.382248", - "name": "500ms", - "pauseType": "delay", - "timeout": "500", - "timeoutUnits": "milliseconds", - "rate": "1", - "nbRateUnits": "1", - "rateUnits": "second", - "randomFirst": "1", - "randomLast": "5", - "randomUnits": "seconds", - "drop": false, - "x": 650, - "y": 840, - "wires": [ - [ - "1d76619d.106536", - "ce69d5d.693d4a8" - ] - ] - }, - { - "id": "ce69d5d.693d4a8", - "type": "delay", - "z": "821cff63.382248", - "name": "500ms", - "pauseType": "delay", - "timeout": "500", - "timeoutUnits": "milliseconds", - "rate": "1", - "nbRateUnits": "1", - "rateUnits": "second", - "randomFirst": "1", - "randomLast": "5", - "randomUnits": "seconds", - "drop": false, - "x": 650, - "y": 880, - "wires": [ - [ - "21b53d98.e9ecca" - ] - ] - }, - { - "id": "b7526133.93348", - "type": "comment", - "z": "821cff63.382248", - "name": "gateway light flick 3 times", - "info": "", - "x": 890, - "y": 720, - "wires": [] - }, - { - "id": "f96c8911.21e9", - "type": "xiaomi-switch", - "z": "821cff63.382248", - "gateway": "", - "name": "", - "sid": "", - "outmsg": "{{click}}", - "outmsgdbcl": "{{double_click}}", - "output": "0", - "x": 300, - "y": 660, - "wires": [ - [ - "26684d11.692aa2" - ] - ] - } -] +[{"id":"42c840ac.0d4088","type":"tab","label":"Mi Devices Sample","disabled":false,"info":""},{"id":"a2d5e2c3.b92fd","type":"comment","z":"42c840ac.0d4088","name":"Get all sensors and gateway statuses","info":"","x":390,"y":40,"wires":[]},{"id":"c53c673b.414f28","type":"inject","z":"42c840ac.0d4088","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"x":107.14285714285711,"y":95,"wires":[["41eb0695.e63408","eafddced.3b04a"]]},{"id":"41eb0695.e63408","type":"xiaomi-all","z":"42c840ac.0d4088","gateway":"","name":"","x":300,"y":100,"wires":[["91c1bb66.39253"]]},{"id":"eafddced.3b04a","type":"xiaomi-gateway","z":"42c840ac.0d4088","gateway":"","name":"","x":320,"y":160,"wires":[["d19fb980.133f68"]]},{"id":"91c1bb66.39253","type":"split","z":"42c840ac.0d4088","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":490,"y":100,"wires":[["3185cd39.74c96a"]]},{"id":"3185cd39.74c96a","type":"change","z":"42c840ac.0d4088","name":"set id","rules":[{"t":"set","p":"sid","pt":"msg","to":"payload.sid","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":650,"y":100,"wires":[["d19fb980.133f68"]]},{"id":"d19fb980.133f68","type":"xiaomi-actions read","z":"42c840ac.0d4088","name":"","x":810,"y":100,"wires":[["257a96ea.456742"]]},{"id":"257a96ea.456742","type":"xiaomi-gateway out","z":"42c840ac.0d4088","name":"","gateway":"","ip":"","x":1000,"y":100,"wires":[]},{"id":"15a7a55c.ee2a13","type":"comment","z":"42c840ac.0d4088","name":"Check if a window at least one window open","info":"","x":410,"y":300,"wires":[]},{"id":"6444fdcc.e8d0b4","type":"xiaomi-all","z":"42c840ac.0d4088","gateway":"","name":"","x":300,"y":360,"wires":[["f3ac9439.133d68","47f2046.6bea47c"]]},{"id":"c04374e6.58de3","type":"split","z":"42c840ac.0d4088","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":630,"y":360,"wires":[["97dc0a89.8f2808"]]},{"id":"f3ac9439.133d68","type":"function","z":"42c840ac.0d4088","name":"filter windows","func":"let windowSensors = msg.payload.filter((e) => {\n return e.model === \"magnet\";\n});\nmsg.payload = windowSensors;\nreturn msg;","outputs":1,"noerr":0,"x":460,"y":360,"wires":[["c04374e6.58de3"]]},{"id":"97dc0a89.8f2808","type":"change","z":"42c840ac.0d4088","name":"set id","rules":[{"t":"set","p":"sid","pt":"msg","to":"payload.sid","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":770,"y":360,"wires":[["c92e4522.5f451"]]},{"id":"c92e4522.5f451","type":"xiaomi-actions read","z":"42c840ac.0d4088","name":"","x":910,"y":360,"wires":[["faa7cd47.2f0ed"]]},{"id":"faa7cd47.2f0ed","type":"xiaomi-gateway out","z":"42c840ac.0d4088","name":"","gateway":"","ip":"","x":1100,"y":360,"wires":[]},{"id":"a354a2db.a472c8","type":"xiaomi-gateway in","z":"42c840ac.0d4088","name":"","gateway":"","ip":"","x":100,"y":480,"wires":[["c888e01a.97754"]]},{"id":"c888e01a.97754","type":"function","z":"42c840ac.0d4088","name":"set window sensor value","func":"if ([\"magnet\", \"sensor_magnet.aq2\"].indexOf(msg.payload.model) >= 0 && msg.payload.sid !== \"158d0001ab1fa8\") {\n let globalKey = `windowSensorStatus-${msg.payload.sid}`;\n global.set(globalKey, msg.payload.data.status);\n}\n","outputs":"0","noerr":0,"x":330,"y":480,"wires":[]},{"id":"b6ce1add.fd8098","type":"function","z":"42c840ac.0d4088","name":"get window sensors values","func":"let windowSensors = {};\nmsg.payload.filter((e) => {\n return e.model === \"magnet\";\n}).forEach((e) => {\n let globalKey = `windowSensorStatus-${e.sid}`;\n let value = global.get(globalKey);\n if(!value || value == \"open\") {\n windowSensors[e.sid] = value || \"na\";\n }\n});\n\nmsg.payload = windowSensors;\nif(Object.keys(windowSensors).length) {\n return [msg, null];\n}\nreturn [null, msg];","outputs":"2","noerr":0,"x":680,"y":420,"wires":[[],[]],"outputLabels":["at least one window is open","all windows are close"]},{"id":"47f2046.6bea47c","type":"delay","z":"42c840ac.0d4088","name":"","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":450,"y":420,"wires":[["b6ce1add.fd8098"]]},{"id":"d85b4cea.a9e338","type":"comment","z":"42c840ac.0d4088","name":"Doorbell","info":"","x":300,"y":580,"wires":[]},{"id":"f1a76c90.712d08","type":"xiaomi-gateway in","z":"42c840ac.0d4088","name":"","gateway":"","ip":"","x":100,"y":660,"wires":[["2418c093.cc257"]]},{"id":"b11d36c7.eac58","type":"function","z":"42c840ac.0d4088","name":"is click","func":"if(msg.payload.cmd === \"report\" && msg.payload.data.status == \"click\") {\n return msg;\n}\nreturn null;","outputs":"1","noerr":0,"x":470,"y":660,"wires":[["f7756ac2.ebcec","b82c564e.b4d968","65bfdf1e.559d48"]]},{"id":"f7756ac2.ebcec","type":"xiaomi-actions gateway_sound","z":"42c840ac.0d4088","name":"","mid":"10","volume":"20","x":650,"y":640,"wires":[["d9796e1c.9da33"]]},{"id":"d9796e1c.9da33","type":"xiaomi-gateway out","z":"42c840ac.0d4088","name":"","gateway":"","ip":"","x":1260,"y":640,"wires":[]},{"id":"c2d7b15f.511b9","type":"template","z":"42c840ac.0d4088","name":"off","field":"brightness","fieldType":"msg","format":"handlebars","syntax":"plain","template":"0","output":"str","x":850,"y":800,"wires":[["c580b5dc.f26a8"]]},{"id":"b82c564e.b4d968","type":"template","z":"42c840ac.0d4088","name":"on","field":"brightness","fieldType":"msg","format":"handlebars","syntax":"plain","template":"100","output":"str","x":850,"y":760,"wires":[["c580b5dc.f26a8"]]},{"id":"c580b5dc.f26a8","type":"xiaomi-actions gateway_light","z":"42c840ac.0d4088","name":"","x":1000,"y":760,"wires":[["d9796e1c.9da33"]]},{"id":"65bfdf1e.559d48","type":"delay","z":"42c840ac.0d4088","name":"500ms","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":650,"y":720,"wires":[["c2d7b15f.511b9","71efc952.99aa1"]]},{"id":"71efc952.99aa1","type":"delay","z":"42c840ac.0d4088","name":"500ms","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":650,"y":760,"wires":[["b82c564e.b4d968","9de20a84.4b1798"]]},{"id":"9de20a84.4b1798","type":"delay","z":"42c840ac.0d4088","name":"500ms","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":650,"y":800,"wires":[["c2d7b15f.511b9","c6e951d9.77c5"]]},{"id":"c6e951d9.77c5","type":"delay","z":"42c840ac.0d4088","name":"500ms","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":650,"y":840,"wires":[["b82c564e.b4d968","6b737819.10c298"]]},{"id":"6b737819.10c298","type":"delay","z":"42c840ac.0d4088","name":"500ms","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":650,"y":880,"wires":[["c2d7b15f.511b9"]]},{"id":"8b00845a.d05ae","type":"comment","z":"42c840ac.0d4088","name":"gateway light flick 3 times","info":"","x":890,"y":720,"wires":[]},{"id":"2418c093.cc257","type":"xiaomi-switch","z":"42c840ac.0d4088","gateway":"","name":"","sid":"","x":300,"y":660,"wires":[["b11d36c7.eac58"]]}] \ No newline at end of file diff --git a/node-red-contrib-xiaomi-actions/icons/mi-toggle.png b/node-red-contrib-xiaomi-actions/icons/mi-toggle.png new file mode 100644 index 0000000..dbebc29 Binary files /dev/null and b/node-red-contrib-xiaomi-actions/icons/mi-toggle.png differ diff --git a/node-red-contrib-xiaomi-actions/xiaomi-actions.html b/node-red-contrib-xiaomi-actions/xiaomi-actions.html index b600998..01740a7 100644 --- a/node-red-contrib-xiaomi-actions/xiaomi-actions.html +++ b/node-red-contrib-xiaomi-actions/xiaomi-actions.html @@ -86,10 +86,7 @@ - + - + + + + + + + + diff --git a/node-red-contrib-xiaomi-actions/xiaomi-actions.js b/node-red-contrib-xiaomi-actions/xiaomi-actions.js index 5f825c0..f3dbe4e 100644 --- a/node-red-contrib-xiaomi-actions/xiaomi-actions.js +++ b/node-red-contrib-xiaomi-actions/xiaomi-actions.js @@ -36,8 +36,11 @@ module.exports = (RED) => { RED.nodes.createNode(this, config); this.on('input', (msg) => { - this.gateway = msg.gateway; - miDevicesUtils.sendWritePayloadToGateway(this, msg, {status: "click", sid: msg.sid}); + msg.payload = { + cmd: "write", + data: { status: "click", sid: msg.sid } + }; + this.send(msg); }); } RED.nodes.registerType("xiaomi-actions click", XiaomiActionSingleClick); @@ -49,7 +52,11 @@ module.exports = (RED) => { RED.nodes.createNode(this, config); this.on('input', (msg) => { - miDevicesUtils.sendWritePayloadToGateway(this, msg, {status: "double_click", sid: msg.sid}); + msg.payload = { + cmd: "write", + data: { status: "double_click", sid: msg.sid } + }; + this.send(msg); }); } RED.nodes.registerType("xiaomi-actions double_click", XiaomiActionDoubleClick); @@ -59,15 +66,26 @@ module.exports = (RED) => { *********************************************/ function XiaomiActionGatewayLight(config) { RED.nodes.createNode(this, config); - this.gateway = RED.nodes.getNode(config.gateway); - this.color = RED.nodes.getNode(config.color); - this.brightness = RED.nodes.getNode(config.brightness); + this.color = config.color; + this.brightness = config.brightness; this.on('input', (msg) => { let color = msg.color || this.color; let brightness = msg.brightness || this.brightness; - let rgb = miDevicesUtils.computeColorValue(brightness, color.red, color.green, color.blue); - miDevicesUtils.sendWritePayloadToGateway(this, msg, {rgb: rgb}); + if(msg.sid) { + let rgb = miDevicesUtils.computeColorValue(color.red, color.green, color.blue, brightness); + msg.payload = { + cmd: "write", + data: { rgb: rgb, sid: msg.sid } + }; + } + else { + msg.payload = { + color: miDevicesUtils.computeColorValue(color.red, color.green, color.blue), + brightness: brightness + }; + } + this.send(msg); }); } RED.nodes.registerType("xiaomi-actions gateway_light", XiaomiActionGatewayLight); @@ -77,15 +95,19 @@ module.exports = (RED) => { *********************************************/ function XiaomiActionGatewaySound(config) { RED.nodes.createNode(this, config); - this.gateway = RED.nodes.getNode(config.gateway); this.mid = config.mid; this.volume = config.volume; this.on('input', (msg) => { - miDevicesUtils.sendWritePayloadToGateway(this, msg, { - mid: parseInt(msg.mid || this.mid), - volume: parseInt(msg.volume || this.volume) - }); + msg.payload = { + cmd: "write", + data: { + mid: parseInt(msg.mid || this.mid), + volume: parseInt(msg.volume || this.volume), + sid: msg.sid + } + }; + this.send(msg); }); } RED.nodes.registerType("xiaomi-actions gateway_sound", XiaomiActionGatewaySound); @@ -95,10 +117,13 @@ module.exports = (RED) => { *********************************************/ function XiaomiActionGatewayStopSound(config) { RED.nodes.createNode(this, config); - this.gateway = RED.nodes.getNode(config.gateway); this.on('input', (msg) => { - miDevicesUtils.sendWritePayloadToGateway(this, msg, { mid: 1000 }); + msg.payload = { + cmd: "write", + data: { mid: 1000, sid: msg.sid } + }; + this.send(msg); }); } RED.nodes.registerType("xiaomi-actions gateway_stop_sound", XiaomiActionGatewayStopSound); @@ -108,16 +133,18 @@ module.exports = (RED) => { *********************************************/ function XiaomiActionPowerOn(config) { RED.nodes.createNode(this, config); - this.gateway = RED.nodes.getNode(config.gateway); this.on('input', (msg) => { if(msg.sid){ - miDevicesUtils.sendWritePayloadToGateway(this, msg, { status: "on", sid: msg.sid}); + msg.payload = { + cmd: "write", + data: { status: "on", sid: msg.sid } + }; } else { - msg.payload = "off"; - this.send(msg); + msg.payload = "on"; } + this.send(msg); }); } RED.nodes.registerType("xiaomi-actions on", XiaomiActionPowerOn); @@ -127,17 +154,32 @@ module.exports = (RED) => { *********************************************/ function XiaomiActionPowerOff(config) { RED.nodes.createNode(this, config); - this.gateway = RED.nodes.getNode(config.gateway); this.on('input', (msg) => { if(msg.sid){ - miDevicesUtils.sendWritePayloadToGateway(this, msg, { status: "off", sid: msg.sid}); + msg.payload = { + cmd: "write", + data: { status: "off", sid: msg.sid } + }; } else { msg.payload = "off"; - this.send(msg); } + this.send(msg); }); } RED.nodes.registerType("xiaomi-actions off", XiaomiActionPowerOff); + + /********************************************* + Toggle device + *********************************************/ + function XiaomiActionToggle(config) { + RED.nodes.createNode(this, config); + + this.on('input', (msg) => { + msg.payload = "toggle"; + this.send(msg); + }); + } + RED.nodes.registerType("xiaomi-actions toggle", XiaomiActionToggle); } diff --git a/node-red-contrib-xiaomi-all/xiaomi-all.js b/node-red-contrib-xiaomi-all/xiaomi-all.js index d4262a9..df3cb30 100644 --- a/node-red-contrib-xiaomi-all/xiaomi-all.js +++ b/node-red-contrib-xiaomi-all/xiaomi-all.js @@ -12,11 +12,9 @@ module.exports = (RED) => { this.gateway = RED.nodes.getNode(config.gateway); this.onlyModels = getOnlyModelsValue(config.onlyModels || []); this.excludedSids = config.excludedSids; - console.log(this.onlyModels); this.isDeviceValid = (device) => { - console.log(device.sid, device.model, this.onlyModels, this.excludeSids); if((!this.onlyModels || this.onlyModels.length == 0) && (!this.excludedSids || this.excludedSids.length == 0)) { return true; } diff --git a/node-red-contrib-xiaomi-gateway/xiaomi-gateway.js b/node-red-contrib-xiaomi-gateway/xiaomi-gateway.js index 4053c09..acc56b9 100644 --- a/node-red-contrib-xiaomi-gateway/xiaomi-gateway.js +++ b/node-red-contrib-xiaomi-gateway/xiaomi-gateway.js @@ -88,18 +88,21 @@ module.exports = (RED) => { } msg = { payload: jsonMsg }; if(this.gateway && jsonMsg.data.ip && jsonMsg.data.ip === this.gateway.ip) { - RED.nodes.eachNode((tmpNode) => { - if(tmpNode.type.indexOf("xiaomi-gateway") === 0 && tmpNode.gateway == this.gatewayNodeId) { - let tmpNodeInst = RED.nodes.getNode(tmpNode.id); - tmpNodeInst.status({fill:"blue", shape:"dot", text: "online"}); - } - }); if(jsonMsg.token) { this.gateway.lastToken = jsonMsg.token; if(!this.gateway.sid) { this.gateway.sid = jsonMsg.sid; } } + RED.nodes.eachNode((tmpNode) => { + if(tmpNode.type.indexOf("xiaomi-gateway") === 0 && tmpNode.gateway == this.gatewayNodeId) { + let tmpNodeInst = RED.nodes.getNode(tmpNode.id); + if(tmpNode.type === "xiaomi-gateway out" && !this.gateway.lastToken) { + tmpNodeInst.status({fill:"yellow", shape:"ring", text: "waiting input"}); + } + tmpNodeInst.status({fill:"blue", shape:"dot", text: "online"}); + } + }); } this.send(msg); } @@ -155,6 +158,9 @@ module.exports = (RED) => { this.ipv = this.ip && this.ip.indexOf(":") >= 0 ? "udp6" : "udp4"; this.multicast = false; + this.gatewayNodeId = n.gateway; + this.gateway = RED.nodes.getNode(n.gateway); + this.status({fill:"red", shape:"ring", text: "offline"}); var opts = {type:this.ipv, reuseAddr:true}; @@ -193,6 +199,9 @@ module.exports = (RED) => { } else if (isNaN(por) || (por < 1) || (por > 65535)) { this.warn(RED._("udp.errors.port-invalid")); } else { + if(msg.payload.cmd === "write" && !msg.payload.data.key && this.gateway && this.gateway.sid && this.gateway.key && this.gateway.lastToken) { + msg.payload.data.key = miDevicesUtils.getGatewayKey(this.gateway.key, this.gateway.lastToken); + } var message = Buffer.from(JSON.stringify(msg.payload)); sock.send(message, 0, message.length, por, add, (err, bytes) => { if (err) { diff --git a/node-red-contrib-xiaomi-switch/xiaomi-switch.html b/node-red-contrib-xiaomi-switch/xiaomi-switch.html index be449a3..97f79d9 100644 --- a/node-red-contrib-xiaomi-switch/xiaomi-switch.html +++ b/node-red-contrib-xiaomi-switch/xiaomi-switch.html @@ -5,10 +5,7 @@ defaults: { gateway: {value:"", type:"xiaomi-configurator"}, name: {value: ""}, - sid: {value: "", required: true}, - outmsg: {value: "{{click}}"}, - outmsgdbcl: {value: "{{double_click}}"}, - output: {value: "0"} + sid: {value: "", required: true} }, inputs: 1, outputs: 1, diff --git a/node-red-contrib-xiaomi-yeelight/icons/mi-yeelight.png b/node-red-contrib-xiaomi-yeelight/icons/mi-yeelight.png new file mode 100644 index 0000000..0ba6ad3 Binary files /dev/null and b/node-red-contrib-xiaomi-yeelight/icons/mi-yeelight.png differ diff --git a/node-red-contrib-xiaomi-yeelight/xiaomi-yeelight.html b/node-red-contrib-xiaomi-yeelight/xiaomi-yeelight.html new file mode 100644 index 0000000..19daae7 --- /dev/null +++ b/node-red-contrib-xiaomi-yeelight/xiaomi-yeelight.html @@ -0,0 +1,79 @@ + + + + + diff --git a/node-red-contrib-xiaomi-yeelight/xiaomi-yeelight.js b/node-red-contrib-xiaomi-yeelight/xiaomi-yeelight.js new file mode 100644 index 0000000..693be4d --- /dev/null +++ b/node-red-contrib-xiaomi-yeelight/xiaomi-yeelight.js @@ -0,0 +1,57 @@ +const miDevicesUtils = require('../src/utils'); +const Yeelight = require("yeelight2"); + +module.exports = (RED) => { + function XiaomiYeelightOutputNode(config) { + RED.nodes.createNode(this, config); + this.ip = config.ip; + this.port = config.port; + + this.status({fill:"grey", shape:"ring", text:"na"}); + + this.setupConnection = function(){ + try { + this.light = Yeelight(`yeelight://${this.ip}:${this.port}`); + this.status({fill:"blue", shape:"dot", text:"connected"}); + } catch(err) { + this.status({fill:"red",shape:"ring",text:err.message}); + this.light = null; + this.error(err); + + // try to reconnect in 5 minutes + window.setTimeout((function(self) { + return function() { + self.setupConnection.apply(self, arguments); + } + })(this), 1000*60*5); + } + } + + if (this.ip && this.port) { + this.setupConnection(); + this.on('input', (msg) => { + if(msg.payload === "on") { + this.light && this.light.set_power('on'); + } + else if(msg.payload === "off") { + this.light && this.light.set_power('off'); + } + else if(msg.payload === "toggle") { + this.light && this.light.toggle(); + } + + if(msg.payload.color !== undefined) { + this.light && this.light.set_rgb(msg.payload.color); + } + if(msg.payload.brightness !== undefined) { + this.light && this.light.set_bright(msg.payload.brightness); + } + }); + + this.on('close', () => { + this.light && this.light.exit(); + }); + } + } + RED.nodes.registerType("xiaomi-yeelight out", XiaomiYeelightOutputNode); +}; diff --git a/package.json b/package.json index 14c6322..bfc4283 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-mi-devices", - "version": "1.0.6", + "version": "1.1.0", "description": "A set of nodes to control some of the popular Xiaomi sensors which are connected to the Xiaomi Gateway, and the Gateway itself.", "repository": { "type": "git", @@ -23,7 +23,8 @@ "xiaomi-all": "node-red-contrib-xiaomi-all/xiaomi-all.js", "xiaomi-configurator": "node-red-contrib-xiaomi-configurator/xiaomi-configurator.js", "xiaomi-gateway": "node-red-contrib-xiaomi-gateway/xiaomi-gateway.js", - "xiaomi-actions": "node-red-contrib-xiaomi-actions/xiaomi-actions.js" + "xiaomi-actions": "node-red-contrib-xiaomi-actions/xiaomi-actions.js", + "xiaomi-yeelight": "node-red-contrib-xiaomi-yeelight/xiaomi-yeelight.js" } }, "author": "Pierre CLEMENT", @@ -32,7 +33,8 @@ }, "dependencies": { "cryptojs": "^2.5.3", - "miio": "0.13.0" + "miio": "0.13.0", + "yeelight2": "^1.3.5" }, "engines": { "node": ">=4.4.5" diff --git a/resources/mi-devices-overview.png b/resources/mi-devices-overview.png index fd7bd40..01f428c 100644 Binary files a/resources/mi-devices-overview.png and b/resources/mi-devices-overview.png differ diff --git a/resources/xiaomi-gateway-advanced-mode.png b/resources/xiaomi-gateway-advanced-mode.png index 5248fbd..6235c7a 100644 Binary files a/resources/xiaomi-gateway-advanced-mode.png and b/resources/xiaomi-gateway-advanced-mode.png differ diff --git a/resources/xiaomi-yeelight-lan-enabled.png b/resources/xiaomi-yeelight-lan-enabled.png new file mode 100644 index 0000000..72a9f8e Binary files /dev/null and b/resources/xiaomi-yeelight-lan-enabled.png differ diff --git a/resources/xiaomi-yeelight-options.png b/resources/xiaomi-yeelight-options.png new file mode 100644 index 0000000..63d5507 Binary files /dev/null and b/resources/xiaomi-yeelight-options.png differ diff --git a/src/utils.js b/src/utils.js index a4e5da4..1ab3e75 100644 --- a/src/utils.js +++ b/src/utils.js @@ -39,24 +39,12 @@ module.exports = { return key; }, - sendWritePayloadToGateway: function(node, msg, data) { - let gateway = node.gateway; - if(gateway && gateway.sid && gateway.key && gateway.lastToken) { - data.sid = data.sid || gateway.sid; - data.key = this.getGatewayKey(gateway.key, gateway.lastToken); - msg.payload = { - cmd: "write", - data: data - }; - node.send(msg); - } - }, prepareForGatewayRequest: function(node, msg) { msg.sid = node.sid; msg.gateway = node.gateway; }, - computeColorValue: function (brightness, red, green, blue) { - return Math.round(256*256*256*brightness) + (256*256*red) + (256*green) + blue; + computeColorValue: function (red, green, blue, brightness) { + return (brightness !== undefined ? 256*256*256*brightness : 0) + (256*256*red) + (256*green) + blue; }, computeColor: function (rgb) { var blue = rgb % 256;