Skip to content

Example Bulb Dimmer

Roland B edited this page Nov 4, 2020 · 6 revisions

Properties

Available Properties

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.

Details

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

Examples

These examples are meant to be copied into your Node-RED system and adapted to your setup.

On/Off Light

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.

screen shot 2019-03-05 at 11 33 52 am

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"}]

Dimmable Light

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.

screen shot 2019-03-05 at 11 48 05 am

Characteristic Properties

Use the following JSON in your characteristic properties so the Home app shows a dimmable bulb by default.

{"Brightness":true}

Example

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.

Color Light (HSV with MQTT input/output)

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 be ON or OFF

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.

Screen Shot 2019-03-21 at 9 35 16 AM

Characteristic Properties

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
}

Example

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"}]

Color Light (with color space conversions)

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.

Screen Shot 2019-03-20 at 8 31 45 PM

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.

Sample Implementation with a Sonoff-Tasmota flashed TuYa WiFi Dimmer Switch

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}]
Clone this wiki locally