Ovládání barevného světla Lidl/Livarnolux s kódováním xy CIE z HomeKitu

Prostřednictvím ConBee II připojíme do Node-RED a následně do HomeKitu leccos, nicméně můžeme narazit na problém ovládání barev. Používá se totiž více způsobů předávání informací o zvolené barvě – HomeKit používá HSV (Hue, Saturation, Value s pevně nastavenou hodnotou "Value": 100). Velmi často se používá „tradiční“ kódování RGB a bohužel není nezvyklé ani XY ( detail na Wikipedii).

Prvním problémem, se kterým jsem se musel vypořádat bylo, že HomeKit tlačítko posílá vždy jen jednu hodnotu. Takže z něj vyjdou dva různé message, jeden s Hue, druhý se Saturation… anebo také naopak. Začal jsem Join nodem, který je nakonfigurovaný tak, aby každé dva message spojil do jednoho „merged object“ a poslal je dál.

V dalším, funkčním nodu jsem přidal definici „lightness“ který vyžaduje další nod a message seřadil do Array, který posílám dál do Color convert nodu, který z Array [hue, saturation, lighntess] vyrobí [red, blue, green] což je tradiční RGB, ke kterému jsem našel kód a ten se nachází v dalším funkčním nodu, z něho už je výstup ve formátu xy.

Dalším krokem by mohlo být vytažení xy formátu ze světla, jeho překlopení zpět do HSV a poslání do HomeKit tlačítka. To bych použil, pokud by bylo možné ovládat barevnou žárovku i jinak – nějakou nativní aplikací například.


A na závěr celý kód:

[{"id":"928b60aa.9f26b8","type":"homekit-service","z":"aff5ebc7.b0d05","isParent":true,"bridge":"8a163217.6671f","parentService":"","name":"Test Bulb","serviceName":"Lightbulb","topic":"","filter":false,"manufacturer":"NRCHKB","model":"1.2.0","serialNo":"Default Serial Number","firmwareRev":"1.2.0","hardwareRev":"1.2.0","softwareRev":"1.2.0","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","cameraConfigInterfaceName":"","characteristicProperties":"{\"On\": true, \"Brightness\":true, \"Hue\":true, \"Saturation\":true}","waitForSetupMsg":false,"outputs":2,"x":80,"y":860,"wires":[[],["fcfda359.bbf428"]]},{"id":"ff2bba61.1c7958","type":"color-convert","z":"aff5ebc7.b0d05","input":"hsv","output":"rgb","outputType":"array","scaleInput":false,"x":490,"y":860,"wires":[["7f0f4cf6.8c2f94","edc425a5.fc9cf"]]},{"id":"7f0f4cf6.8c2f94","type":"debug","z":"aff5ebc7.b0d05","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":650,"y":800,"wires":[]},{"id":"fcfda359.bbf428","type":"join","z":"aff5ebc7.b0d05","name":"","mode":"custom","build":"merged","property":"payload","propertyType":"msg","key":"topic","joiner":"\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":210,"y":860,"wires":[["92f3c03a.c0c328"]]},{"id":"92f3c03a.c0c328","type":"function","z":"aff5ebc7.b0d05","name":"","func":"var hue = msg.payload.Hue\nvar saturation = msg.payload.Saturation\nvar lightness = 100\n\nmsg.payload = [hue, saturation, lightness];\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","x":340,"y":860,"wires":[["97b7cb28.b340a","ff2bba61.1c7958"]]},{"id":"97b7cb28.b340a","type":"debug","z":"aff5ebc7.b0d05","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":470,"y":800,"wires":[]},{"id":"edc425a5.fc9cf","type":"function","z":"aff5ebc7.b0d05","name":"RGB2xy","func":"var red = msg.payload[0];\nvar green = msg.payload[1];\nvar blue = msg.payload[2];\n\n\n // The RGB values should be between 0 and 1. So convert them.\n // The RGB color (255, 0, 100) becomes (1.0, 0.0, 0.39)\n red /= 255; green /= 255; blue /= 255;\n\n // Apply a gamma correction to the RGB values, which makes the color\n // more vivid and more the like the color displayed on the screen of your device\n red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92);\n green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92);\n blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92);\n\n // RGB values to XYZ using the Wide RGB D65 conversion formula\n const X = red * 0.664511 + green * 0.154324 + blue * 0.162028;\n const Y = red * 0.283881 + green * 0.668433 + blue * 0.047685;\n const Z = red * 0.000088 + green * 0.072310 + blue * 0.986039;\n\n // Calculate the xy values from the XYZ values\n let x = (X / (X + Y + Z)).toFixed(4);\n let y = (Y / (X + Y + Z)).toFixed(4);\n\n if (isNaN(x)) {\n x = 0;\n }\n\n if (isNaN(y)) {\n y = 0;\n }\n msg.payload = {\"xy\":[Number.parseFloat(x), Number.parseFloat(y)]};\n\n return msg ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":640,"y":860,"wires":[["14d8fc24.01f3dc","abe694ad.c1c91"]]},{"id":"14d8fc24.01f3dc","type":"debug","z":"aff5ebc7.b0d05","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":790,"y":860,"wires":[]},{"id":"8a163217.6671f","type":"homekit-bridge","bridgeName":"Test_rpi_2","pinCode":"111-99-999","port":"","allowInsecureRequest":false,"manufacturer":"NRCHKB","model":"1.2.0","serialNo":"Default Serial Number","firmwareRev":"1.2.0","hardwareRev":"1.2.0","softwareRev":"1.2.0","customMdnsConfig":false,"mdnsMulticast":true,"mdnsInterface":"","mdnsPort":"","mdnsIp":"","mdnsTtl":"","mdnsLoopback":true,"mdnsReuseAddr":true,"allowMessagePassthrough":true}]

Za případné postřehy a opravy v diskusi budu vděčný.

Zanechat komentář