-
-
Notifications
You must be signed in to change notification settings - Fork 52
Example Bulb Dimmer
To have a bulb appear in the Home app as dimmable, colored, or adjustable temperature use the "Characteristic Properties" area of the service node.
Characteristic | Optional/Required | Characteristic Properties (to enable property) |
---|---|---|
On | Required | |
Brightness | Optional | {"Brightness":true} |
Hue | Optional | {"Hue":true} |
Saturation | Optional | {"Saturation":true} |
Color temperature | Optional | {"ColorTemperature":true} |
IMPORTANT: characteristic properties DO NOT set any value in the Home app, only define which values the Home app should display. For example defining any Brightness
value will only define the bulb as "dimmable" - it will never set an actual brightness in HomeKit.
Characteristic | Format | Accepted Values | Notes |
---|---|---|---|
On | bool | true/false |
{"On":true} / {"On":false}
|
Brightness | int | 0 - 100 | Percentage, step value = 1 |
Hue | float | 0 - 360 | Arcdegrees, step value = 1 |
Saturation | float | 0 - 100 | Percentage, step value = 1 |
Color temperature | uint32 | 50 - 400 | Reciprocal megakelvin, step value=1 |
These examples are meant to be copied into your Node-RED system and adapted to your setup.
This is the simplest example of a light bulb item. The input nodes are "On" and "Off". The debug node will return values when the switch is turned on or off via the Home app on an Apple device.
Copyable Node-RED flow:
[{"id":"ed2d8340.e1d5d8","type":"homekit-service","z":"7b43483c.39305","bridge":"d334490b.40dac","name":"Example Bulb OnOff","serviceName":"Lightbulb","topic":"","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":380,"y":160,"wires":[["5844674e.178708"]]},{"id":"5844674e.178708","type":"debug","z":"7b43483c.39305","name":"HomeKit Out","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":590,"y":160,"wires":[]},{"id":"8db975bc.c2e9d","type":"inject","z":"7b43483c.39305","name":"On","topic":"","payload":"{\"On\":true}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":120,"wires":[["ed2d8340.e1d5d8"]]},{"id":"629771.da7c409","type":"inject","z":"7b43483c.39305","name":"Off","topic":"","payload":"{\"On\":false}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":180,"wires":[["ed2d8340.e1d5d8"]]},{"id":"d334490b.40dac","type":"homekit-bridge","z":"","bridgeName":"Example Bridge","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number"}]
This is an example of a dimmable light bulb item. The input nodes are "On" and "Off" also there is a "Brightness" input that will send a random brightness level to your item.
The On
state and Brightness
may be sent in the same payload for example:
{"On":true, "Brightness":75}
If {"On":true}
is sent without a brightness payload, HomeKit will return to the last set brightness on the device. In this example, there are 2 functions. The Brightness to HomeKit
function translates an integer number range 1-100 into a proper payload for the HomeKit node. The Brightness to Integer
function node translates the output of the HomeKit node back into an integer level 0-100 where 0 is "off". Additionally the Brightness to Integer
node saves the previously used brightness value (as a context variable) to pass on in the case that HomeKit sends {"On":true}
without any Brightness
value.
Use the following JSON in your characteristic properties so the Home app shows a dimmable bulb by default.
{"Brightness":true}
Copyable Node-RED flow:
[{"id":"ed2d8340.e1d5d8","type":"homekit-service","z":"7b43483c.39305","bridge":"d334490b.40dac","name":"Example Bulb OnOff","serviceName":"Lightbulb","topic":"","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{\"Brightness\":true}","x":600,"y":160,"wires":[["5844674e.178708","71e17ac6.d31024"]]},{"id":"5844674e.178708","type":"debug","z":"7b43483c.39305","name":"HomeKit Out","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":870,"y":160,"wires":[]},{"id":"8db975bc.c2e9d","type":"inject","z":"7b43483c.39305","name":"On","topic":"","payload":"{\"On\":true}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":350,"y":120,"wires":[["ed2d8340.e1d5d8"]]},{"id":"629771.da7c409","type":"inject","z":"7b43483c.39305","name":"Off","topic":"","payload":"{\"On\":false}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":350,"y":180,"wires":[["ed2d8340.e1d5d8"]]},{"id":"1bc33e3a.60be9a","type":"function","z":"7b43483c.39305","name":"Brightness to HomeKit","func":"var input = msg.payload;\nif (input < 101){\n if (input < 1) {\n msg.payload = {\n \"On\": false\n }\n }\n else {\n msg.payload = {\n \"Brightness\": input,\n \"On\": true\n }\n }\n return msg;\n}","outputs":1,"noerr":0,"x":460,"y":240,"wires":[["ed2d8340.e1d5d8"]]},{"id":"71e17ac6.d31024","type":"function","z":"7b43483c.39305","name":"Brightness to Integer","func":"var b = context.get('b')||0;\nif(msg.payload.Brightness){\n b = msg.payload.Brightness;\n context.set('b',b);\n msg.payload=b\n}\n\n// Uncomment lines 9 and 20 to prevent looping\n//if (msg.hap.context !== undefined) {\n if(msg.payload.Brightness === 0){\n msg.payload = 0\n }\n if(msg.payload.On === false){\n msg.payload = 0\n }\n if(msg.payload.On === true){\n msg.payload = b\n }\n return msg\n//}","outputs":1,"noerr":0,"x":760,"y":240,"wires":[["309c6439.b99464"]]},{"id":"f3d77f18.27dbf8","type":"random","z":"7b43483c.39305","name":"Random","low":"0","high":"100","inte":"true","property":"payload","x":280,"y":240,"wires":[["1bc33e3a.60be9a"]]},{"id":"309c6439.b99464","type":"debug","z":"7b43483c.39305","name":"Brightness Out","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":980,"y":240,"wires":[]},{"id":"c9205543.2990f8","type":"inject","z":"7b43483c.39305","name":"Send brightness","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":240,"wires":[["f3d77f18.27dbf8"]]},{"id":"d334490b.40dac","type":"homekit-bridge","z":"","bridgeName":"Example Bridge","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number"}]
For a further example how to apply a dimmable light have a look on this page of our wiki.
This example is of a color light bulb item. It uses 4 separate MQTT topics for input and output. The topics used in the example are:
-
kitchenws/hue
for hue, range 0-360 -
kitchenws/sat
for saturation, range 0-100 -
kitchenws/val
for brightness or value, range 0-100 -
kitchenws/function
for power state, can beON
orOFF
The use case of this example is an ESP8266 running a custom Arduino sketch (built on FastLED). The arduino subscribes and publishes to the same topics listed above. The hardware used is an esp-01 and a string of ws2812 RGB lights.
The function nodes simply change the inputs into JSON format readable by HomeKit then back from JSON to numbers or strings for MQTT.
Use the following JSON in your characteristic properties for the bulb to show in the Home app as a color/brightness bulb.
{
"Brightness":true,
"Hue":true,
"Saturation":true
}
Copyable Node-RED code:
[{"id":"58abab1.2339654","type":"mqtt in","z":"73af6e5e.58fa08","name":"","topic":"kitchenws/sat","qos":"1","broker":"57430b.f40734f4","x":110,"y":620,"wires":[["d171bb04.65ae1"]]},{"id":"d171bb04.65ae1","type":"function","z":"73af6e5e.58fa08","name":"To homekit","func":"if(msg.topic == \"kitchenws/hue\"){\n var hue = msg.payload;\n msg.payload = {\n \"Hue\":hue\n }\n return [msg];\n}\nif(msg.topic == \"kitchenws/sat\"){\n var sat = msg.payload;\n msg.payload = {\n \"Saturation\":sat\n }\n return [msg];\n}\nif(msg.topic == \"kitchenws/val\"){\n var val = msg.payload;\n msg.payload = {\n \"Brightness\":val\n }\n return [msg];\n}\nif(msg.topic == \"kitchenws/function\"){\n if(msg.payload == \"ON\"){\n msg.payload = {\n \"On\":true\n }\n return [msg];\n }\n if(msg.payload == \"OFF\"){\n msg.payload = {\n \"On\":false\n }\n return [msg];\n }\n}","outputs":1,"noerr":0,"x":370,"y":640,"wires":[["75501318.6b43ec"]]},{"id":"75501318.6b43ec","type":"homekit-service","z":"73af6e5e.58fa08","bridge":"4b4fbb6e.6cfaec","name":"Countertop","serviceName":"Lightbulb","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{\n \"Brightness\":true,\n \"Hue\":true,\n \"Saturation\":true\n}","x":550,"y":640,"wires":[["e421e87d.3f0948"]]},{"id":"8294d2c0.7b538","type":"mqtt in","z":"73af6e5e.58fa08","name":"","topic":"kitchenws/hue","qos":"1","broker":"57430b.f40734f4","x":120,"y":560,"wires":[["d171bb04.65ae1"]]},{"id":"bd574d89.5545d8","type":"mqtt in","z":"73af6e5e.58fa08","name":"","topic":"kitchenws/val","qos":"1","broker":"57430b.f40734f4","x":110,"y":680,"wires":[["d171bb04.65ae1"]]},{"id":"5ad6f814.e774a","type":"mqtt in","z":"73af6e5e.58fa08","name":"","topic":"kitchenws/function","qos":"1","broker":"57430b.f40734f4","x":130,"y":740,"wires":[["d171bb04.65ae1"]]},{"id":"e421e87d.3f0948","type":"function","z":"73af6e5e.58fa08","name":"To MQTT","func":"if(msg.hap.context !== undefined){\n if(msg.payload.On === true){\n return [null,null,null,{\"payload\":\"ON\"}];\n }\n if(msg.payload.On === false){\n return [null,null,null,{\"payload\":\"OFF\"}];\n\n }\n if(msg.payload.Hue !== undefined){\n var hue = msg.payload.Hue;\n return [{\"payload\":hue},null,null,null];\n }\n if(msg.payload.Saturation !== undefined){\n var sat = msg.payload.Saturation;\n return [null,{\"payload\":sat},null,null];\n }\n if(msg.payload.Brightness !== undefined){\n var bright = msg.payload.Brightness;\n return [null,null,{\"payload\":bright},null];\n }\n}","outputs":4,"noerr":0,"x":720,"y":640,"wires":[["ecd2fcfe.bdd898"],["eac1313.36a6bd"],["21f736c6.3e3d42"],["8d2b6ebc.dad2b"]]},{"id":"ecd2fcfe.bdd898","type":"mqtt out","z":"73af6e5e.58fa08","name":"","topic":"kitchenws/hue","qos":"1","retain":"false","broker":"57430b.f40734f4","x":940,"y":560,"wires":[]},{"id":"eac1313.36a6bd","type":"mqtt out","z":"73af6e5e.58fa08","name":"","topic":"kitchenws/sat","qos":"1","retain":"false","broker":"57430b.f40734f4","x":940,"y":620,"wires":[]},{"id":"21f736c6.3e3d42","type":"mqtt out","z":"73af6e5e.58fa08","name":"","topic":"kitchenws/val","qos":"1","retain":"false","broker":"57430b.f40734f4","x":940,"y":680,"wires":[]},{"id":"8d2b6ebc.dad2b","type":"mqtt out","z":"73af6e5e.58fa08","name":"","topic":"kitchenws/function","qos":"1","retain":"false","broker":"57430b.f40734f4","x":950,"y":740,"wires":[]},{"id":"57430b.f40734f4","type":"mqtt-broker","z":"","name":"OHMQTT","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""},{"id":"4b4fbb6e.6cfaec","type":"homekit-bridge","z":"","bridgeName":"Node Red","pinCode":"514-02-658","port":"","manufacturer":"Garrett Porter","model":"Pi3","serialNo":"Rev.1"}]
This is an example of a color light bulb item. The input nodes include off, red, green, blue, and white for each of 3 different color spaces. Please note the color convert node is required for this flow to work properly - unless your inputs/outputs are already HSV format. Please find information about the color convert node here.
Depending on your hardware, it is likely that you will be using HSV, RGB, or HSL color format. HomeKit uses the HSV color space. Provided in this flow are functions that create off, red, green, blue, and white arrays for each of these color spaces. These arrays are then converted to HSV and sent to the HomeKit node. (note HSV is also called HSB, these are equivalent)
Simply replace the correct Input
node with your input and the correct Output
debug node with your output. Note there is loop prevention built into the Output
function so the outgoing messages are only sent when originating within the Home app on your device.
Copyable node-red flow:
[{"id":"6c90892b.b229a","type":"inject","z":"8ab94716.868738","name":"RGB Red","topic":"","payload":"Red","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":1020,"wires":[["faed9f12.16cd1"]]},{"id":"faed9f12.16cd1","type":"function","z":"8ab94716.868738","name":"RGB Input","func":"if(msg.payload == \"Off\"){\n return[{\"payload\":[0,0,0]}]\n}\nif(msg.payload == \"Red\"){\n return[{\"payload\":[255,0,0]}]\n}\nif(msg.payload == \"Green\"){\n return[{\"payload\":[0,255,0]}]\n}\nif(msg.payload == \"Blue\"){\n return[{\"payload\":[0,0,255]}]\n}\nif(msg.payload == \"White\"){\n return[{\"payload\":[255,255,255]}]\n}\n","outputs":1,"noerr":0,"x":290,"y":1040,"wires":[["df96d518.9356e8"]]},{"id":"76ba113d.5f2f78","type":"inject","z":"8ab94716.868738","name":"RGB Off","topic":"","payload":"Off","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":980,"wires":[["faed9f12.16cd1"]]},{"id":"3d806d56.009ff2","type":"inject","z":"8ab94716.868738","name":"RGB Green","topic":"","payload":"Green","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":1060,"wires":[["faed9f12.16cd1"]]},{"id":"7226341b.12915c","type":"inject","z":"8ab94716.868738","name":"RGB Blue","topic":"","payload":"Blue","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":1100,"wires":[["faed9f12.16cd1"]]},{"id":"448b762c.ea0d08","type":"inject","z":"8ab94716.868738","name":"RGB White","topic":"","payload":"White","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":1140,"wires":[["faed9f12.16cd1"]]},{"id":"df96d518.9356e8","type":"color-convert","z":"8ab94716.868738","input":"rgb","output":"hsv","outputType":"array","x":490,"y":1040,"wires":[["e9ba32f3.ba157"]]},{"id":"e9ba32f3.ba157","type":"function","z":"8ab94716.868738","name":"Format","func":"var outmsg={};\nvar Hue = flow.get('Hue')||0;\nvar Saturation = flow.get('Saturation')||0;\nvar Brightness = flow.get('Brightness')||100;\n\nif(msg.payload[0]===0 && msg.payload[1]===0 && msg.payload[2]===0){\n outmsg.payload={\"On\":false};\n} else{\n Hue = msg.payload[0];\n flow.set('Hue',Hue);\n Saturation = msg.payload[1];\n flow.set('Saturation',Saturation);\n Brightness = msg.payload[2];\n flow.set('Brightness',Brightness);\n outmsg.payload={\n \"On\":true,\n \"Hue\":Hue,\n \"Saturation\":Saturation,\n \"Brightness\":Brightness\n }\n}\nreturn [outmsg];\n","outputs":1,"noerr":0,"x":680,"y":1260,"wires":[["42123222.b7e504"]]},{"id":"42123222.b7e504","type":"homekit-service","z":"8ab94716.868738","isParent":true,"bridge":"63a21f39.7ace9","parentService":"","name":"HSV light","serviceName":"Lightbulb","topic":"","filter":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{\n \"Brightness\":true,\n \"Hue\":true,\n \"Saturation\":true\n}","x":820,"y":1260,"wires":[["3d71759d.d3f53a","8c376820.c4396"]]},{"id":"7e3120e3.3af968","type":"function","z":"8ab94716.868738","name":"HSV Input","func":"if(msg.payload == \"Off\"){\n return[{\"payload\":[0,0,0]}]\n}\nif(msg.payload == \"Red\"){\n return[{\"payload\":[0,100,100]}]\n}\nif(msg.payload == \"Green\"){\n return[{\"payload\":[120,100,100]}]\n}\nif(msg.payload == \"Blue\"){\n return[{\"payload\":[240,100,100]}]\n}\nif(msg.payload == \"White\"){\n return[{\"payload\":[0,0,100]}]\n}\n","outputs":1,"noerr":0,"x":530,"y":1260,"wires":[["e9ba32f3.ba157"]]},{"id":"709af2e1.0ee534","type":"color-convert","z":"8ab94716.868738","input":"hsl","output":"hsv","outputType":"array","x":490,"y":1480,"wires":[["e9ba32f3.ba157"]]},{"id":"3d71759d.d3f53a","type":"function","z":"8ab94716.868738","name":"Output","func":"var Hue = flow.get('Hue')||0;\nvar Saturation = flow.get('Saturation')||0;\nvar Brightness = flow.get('Brightness')||100;\n\nif(msg.payload.Hue){\n Hue = msg.payload.Hue;\n flow.set('Hue',Hue);\n}\nif(msg.payload.Saturation){\n Saturation = msg.payload.Saturation;\n flow.set('Saturation',Saturation);\n}\nif(msg.payload.Brightness){\n Brightness = msg.payload.Brightness;\n flow.set('Brightness',Brightness);\n}\nif (msg.hap.context !== undefined) {\n if(msg.payload.On === true){\n return [{\"payload\":[Hue,Saturation,Brightness]}]\n }\n if(msg.payload.On === false){\n return [{\"payload\":[0,0,0]}]\n }\n else{\n return [{\"payload\":[Hue,Saturation,Brightness]}]\n }\n}","outputs":1,"noerr":0,"x":970,"y":1260,"wires":[["378a5cc2.a2fb14","c2ba3395.dd7958","26f78f6b.3ba1a8"]]},{"id":"8c376820.c4396","type":"debug","z":"8ab94716.868738","name":"HomeKit output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":940,"y":1340,"wires":[]},{"id":"429f936e.8cbdf4","type":"inject","z":"8ab94716.868738","name":"HSV Off","topic":"","payload":"Off","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":330,"y":1200,"wires":[["7e3120e3.3af968"]]},{"id":"418d88dc.c1b87","type":"inject","z":"8ab94716.868738","name":"HSV Red","topic":"","payload":"Red","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":340,"y":1240,"wires":[["7e3120e3.3af968"]]},{"id":"d3b4ad7.b57e05","type":"inject","z":"8ab94716.868738","name":"HSV Green","topic":"","payload":"Green","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":340,"y":1280,"wires":[["7e3120e3.3af968"]]},{"id":"4a4c3806.1b2c78","type":"inject","z":"8ab94716.868738","name":"HSV Blue","topic":"","payload":"Blue","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":340,"y":1320,"wires":[["7e3120e3.3af968"]]},{"id":"c58a6f7a.75a37","type":"inject","z":"8ab94716.868738","name":"HSV White","topic":"","payload":"White","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":340,"y":1360,"wires":[["7e3120e3.3af968"]]},{"id":"e8e3d457.abe05","type":"function","z":"8ab94716.868738","name":"HSL Input","func":"if(msg.payload == \"Off\"){\n return[{\"payload\":[0,0,0]}]\n}\nif(msg.payload == \"Red\"){\n return[{\"payload\":[0,100,50]}]\n}\nif(msg.payload == \"Green\"){\n return[{\"payload\":[120,100,50]}]\n}\nif(msg.payload == \"Blue\"){\n return[{\"payload\":[240,100,50]}]\n}\nif(msg.payload == \"White\"){\n return[{\"payload\":[0,0,100]}]\n}\n","outputs":1,"noerr":0,"x":280,"y":1480,"wires":[["709af2e1.0ee534"]]},{"id":"378a5cc2.a2fb14","type":"color-convert","z":"8ab94716.868738","input":"hsv","output":"rgb","outputType":"array","x":1150,"y":1040,"wires":[["a2de29b9.6cf5a8"]]},{"id":"c2ba3395.dd7958","type":"debug","z":"8ab94716.868738","name":"HSV output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1230,"y":1260,"wires":[]},{"id":"26f78f6b.3ba1a8","type":"color-convert","z":"8ab94716.868738","input":"hsv","output":"hsl","outputType":"array","x":1150,"y":1480,"wires":[["a514f44e.e7227"]]},{"id":"476847d9.8f77f","type":"inject","z":"8ab94716.868738","name":"HSL Red","topic":"","payload":"Red","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":1460,"wires":[["e8e3d457.abe05"]]},{"id":"9a4225a0.3ecab","type":"inject","z":"8ab94716.868738","name":"HSL Off","topic":"","payload":"Off","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":90,"y":1420,"wires":[["e8e3d457.abe05"]]},{"id":"9e02a9f3.eef378","type":"inject","z":"8ab94716.868738","name":"HSL Green","topic":"","payload":"Green","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":1500,"wires":[["e8e3d457.abe05"]]},{"id":"62ad3f72.e1f078","type":"inject","z":"8ab94716.868738","name":"HSL Blue","topic":"","payload":"Blue","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":1540,"wires":[["e8e3d457.abe05"]]},{"id":"80199324.4b8e48","type":"inject","z":"8ab94716.868738","name":"HSL White","topic":"","payload":"White","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":1580,"wires":[["e8e3d457.abe05"]]},{"id":"a2de29b9.6cf5a8","type":"debug","z":"8ab94716.868738","name":"RGB output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1330,"y":1040,"wires":[]},{"id":"a514f44e.e7227","type":"debug","z":"8ab94716.868738","name":"HSL output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1330,"y":1480,"wires":[]},{"id":"893b1330.ebae9","type":"comment","z":"8ab94716.868738","name":"RGB TEST INPUTS","info":"","x":130,"y":940,"wires":[]},{"id":"91a405cc.7b88b8","type":"comment","z":"8ab94716.868738","name":"HSV TEST INPUTS","info":"","x":350,"y":1160,"wires":[]},{"id":"894ae6b4.b76b3","type":"comment","z":"8ab94716.868738","name":"HSL TEST INPUTS","info":"","x":110,"y":1380,"wires":[]},{"id":"63a21f39.7ace9","type":"homekit-bridge","z":"","bridgeName":"Dev2","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number"}]
Please note that if these functions are used multiple times within the same flow, then unique names will be required for the flow.get
and flow.set
variables in the functions.
This is a node-red flow to integrate a Sonoff-Tasmota flashed WiFi Dimmers with HomeKit. This flow creates a dimmable light in HomeKit, and also detects if the device is disconnected, and sets the device as 'not responding' after 15 minutes. This node-red flow would also work with dimmable light bulb's as well, but not color or RGB lightbulbs.
To set this up for use in your environment you will need to change a couple of settings
1 - Configure the MQTT In and Out Nodes configuration node with your MQTT server.
2 - Set the topic on the MQTT In node to include your device name. ie '+/sonoff-1790/#'
3 - Configure the HomeKit configuration node for your setup
4 - Set the Name of the HomeKit node for the name you want to use in HomeKit
5 - Set the topic of the HomeKit to include your device name. ie 'cmnd/sonoff-1790/'
Copyable Node-RED code:
[{"id":"f5bcc9a5.132dc8","type":"mqtt in","z":"3d8fb80e.d7c11","name":"Internet Down","topic":"+/sonoff-1790/#","qos":"0","datatype":"auto","broker":"b8c25d0c.8f5108","x":90,"y":160,"wires":[["14371369.7327f5","66d2df40.b7172"]]},{"id":"cf4812d8.2340a8","type":"mqtt out","z":"3d8fb80e.d7c11","name":"Internet Down","topic":"","qos":"0","retain":"","broker":"b8c25d0c.8f5108","x":780,"y":380,"wires":[]},{"id":"527452c0.d0bd54","type":"function","z":"3d8fb80e.d7c11","name":"HB to Tasmota","func":"var result;\nfor (var characteristic in msg.payload) {\n console.log(\"characteristic\", characteristic, msg.payload[characteristic]);\n switch (characteristic.toLowerCase()) {\n case \"rotationspeed\":\n case \"brightness\":\n result = msg.payload[characteristic];\n msg.topic = msg.topic + \"DIMMER\";\n break;\n case \"on\":\n // msg.payload = ( msg.payload.On ? \"ON\" : \"OFF\" );\n result = (msg.payload.On ? \"ON\" : \"OFF\");\n msg.topic = msg.topic + \"POWER\";\n break;\n default:\n console.log(\"Unhandled characteristic\", characteristic);\n }\n}\nmsg.payload = result;\nreturn msg;","outputs":1,"noerr":0,"x":560,"y":380,"wires":[["d33b5eae.25dde","cf4812d8.2340a8"]]},{"id":"37b80aea.d13166","type":"debug","z":"3d8fb80e.d7c11","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":570,"y":440,"wires":[]},{"id":"84993b33.6c3518","type":"debug","z":"3d8fb80e.d7c11","name":"HomeKit","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":740,"y":100,"wires":[]},{"id":"d33b5eae.25dde","type":"debug","z":"3d8fb80e.d7c11","name":"sonoff","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":750,"y":440,"wires":[]},{"id":"db8ae8ef.05ec18","type":"inject","z":"3d8fb80e.d7c11","name":"status","topic":"cmnd/sonoff-1790/status","payload":"11","payloadType":"num","repeat":"","crontab":"","once":true,"onceDelay":"1","x":590,"y":320,"wires":[["cf4812d8.2340a8","b5a47782.8b04b"]]},{"id":"14371369.7327f5","type":"debug","z":"3d8fb80e.d7c11","name":"Status","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":270,"y":100,"wires":[]},{"id":"f99b3fb.edb3ec","type":"function","z":"3d8fb80e.d7c11","name":"sonoffToHomeKit","func":"var result = {};\nvar input = JSON.parse(msg.payload);\nif (input.StatusSTS) {\n input = input.StatusSTS;\n}\nfor (var characteristic in input) {\n // console.log(\"characteristic\", characteristic, msg.payload[characteristic]);\n switch (characteristic.toLowerCase()) {\n case \"dimmer\":\n result[\"RotationSpeed\"] = input[characteristic];\n break;\n case \"power\":\n // ( msg.payload === \"ON\" ? { \"On\": 1 } : { \"On\": 0 } );\n result[\"On\"] = (input[characteristic] === \"ON\" ? 1 : 0);\n break;\n default:\n // console.log(\"Unhandled characteristic\", characteristic);\n }\n}\nmsg.payload = result;\nreturn msg;","outputs":1,"noerr":0,"x":510,"y":160,"wires":[["84993b33.6c3518","b98429b5.3be8e8"]]},{"id":"66d2df40.b7172","type":"switch","z":"3d8fb80e.d7c11","name":"Topic Router","property":"topic","propertyType":"msg","rules":[{"t":"regex","v":"(stat|tele)\\/.*\\/(RESULT|STATE|STATUS11)","vt":"str","case":true}],"checkall":"false","repair":false,"outputs":1,"x":290,"y":160,"wires":[["75b4d514.f515e4","f99b3fb.edb3ec","b5a47782.8b04b"]]},{"id":"75b4d514.f515e4","type":"debug","z":"3d8fb80e.d7c11","name":"Match","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":490,"y":100,"wires":[]},{"id":"b98429b5.3be8e8","type":"homekit-service","z":"3d8fb80e.d7c11","isParent":true,"bridge":"b94bcc8c.535138","accessoryCategory":"OTHER","parentService":"","name":"Internet Down","serviceName":"Lightbulb","topic":"cmnd/sonoff-1790/","filter":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","cameraConfigVideoProcessor":"ffmpeg","cameraConfigSource":"","cameraConfigStillImageSource":"","cameraConfigMaxStreams":2,"cameraConfigMaxWidth":1280,"cameraConfigMaxHeight":720,"cameraConfigMaxFPS":10,"cameraConfigMaxBitrate":300,"cameraConfigVideoCodec":"libx264","cameraConfigAudioCodec":"libfdk_aac","cameraConfigAudio":false,"cameraConfigPacketSize":1316,"cameraConfigVerticalFlip":false,"cameraConfigHorizontalFlip":false,"cameraConfigMapVideo":"0:0","cameraConfigMapAudio":"0:1","cameraConfigVideoFilter":"scale=1280:720","cameraConfigAdditionalCommandLine":"-tune zerolatency","cameraConfigDebug":false,"cameraConfigSnapshotOutput":"disabled","characteristicProperties":"{\"Brightness\":true}","x":340,"y":380,"wires":[["527452c0.d0bd54","37b80aea.d13166"],[]]},{"id":"b5a47782.8b04b","type":"trigger","z":"3d8fb80e.d7c11","op1":"","op2":"0","op1type":"nul","op2type":"json","duration":"11","extend":true,"units":"min","reset":"","bytopic":"all","name":"","x":310,"y":260,"wires":[["da26578e.e58f9"]]},{"id":"da26578e.e58f9","type":"function","z":"3d8fb80e.d7c11","name":"No Response","func":"msg.payload = {On: 'NO_RESPONSE'};\nreturn msg;","outputs":1,"noerr":0,"x":500,"y":260,"wires":[["b98429b5.3be8e8","84993b33.6c3518","b5a47782.8b04b"]]},{"id":"b8c25d0c.8f5108","type":"mqtt-broker","z":"","name":"Sheldon","broker":"sheldon.local","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""},{"id":"b94bcc8c.535138","type":"homekit-bridge","z":"","bridgeName":"air-dev-node-red","pinCode":"031-45-154","port":"51287","allowInsecureRequest":false,"manufacturer":"node-red","model":"Default Model","serialNo":"air-dev","customMdnsConfig":false,"mdnsMulticast":true,"mdnsInterface":"","mdnsPort":"","mdnsIp":"","mdnsTtl":"","mdnsLoopback":true,"mdnsReuseAddr":true,"allowMessagePassthrough":false}]