NRCHKB / node-red-contrib-homekit-bridged

Node-RED Contribution - HomeKit Bridged : Node-RED nodes to simulate Apple HomeKit devices.
https://nrchkb.github.io
MIT License
416 stars 52 forks source link

How to handle msg.payload.Brightness #433

Closed Barabba11 closed 3 years ago

Barabba11 commented 3 years ago

NRCHKB Plugin Version

1.3.6

Node JS Version

14.17.2

NPM Version

7.19.1

Node-RED Version

1.3.5

Operating System

Windows, but also on Raspberry

What happened?

Hi, the node does output only a msg.payload.Brightness if brightness is changed on Homekit, so I suppose it accepts only msg.payload.Brightness too to change the status on Homekit (I'm using Alexa too, and I need to keep them syncronized). It produces no reaction to node, it accepts only msg.payload.On and yes it changes the status. Can you please check? Thank you

How to reproduce?

Give it an input msg.payload.Brightness, see if it changes status

Expected behavior:

Should change status on Homekit

Additional comments?

Thank you

Relevant log output

No response

Shaquu commented 3 years ago

@Barabba11 what do you say exactly to Alexa? Also you should know that our node is working with HomeKit and not Alexa (directly).

Please share the flow.

Barabba11 commented 3 years ago

Thanks for quick answer, forget now about Alexa, let's work only with inject nodes. PLease give it a msg.payload.Brightness on a LIghtbulb and see what happens

crxporter commented 3 years ago

You may need to include characteristic properties to enable brightness. This would be available in our wiki, I can't link right now I'm traveling...

I have many brightness bulbs where I inject msg.payload.On when they turn on/off and msg.payload.Brightness to adjust brightness.

Shaquu commented 3 years ago

Link as mentioned:

https://nrchkb.github.io/wiki/service/lightbulb/

Barabba11 commented 3 years ago

thank you for kind answer, the node outputs only msg.payload.Brightness if the brigltness is changed, so I supoose it accepts only this also as input, if status didn't change. Are you suggesting me instead to send in the same message a On:true too? Thank you

crxporter commented 3 years ago

You can send in the same or different messages.

On:true will cause the light to be "on" in home app On:false will cause it to be "off"

Brightness:100 will set brightness to 100 but will not show anything in home app unless the light is on from the On:true Brightness:0 without On:false will cause the light to be "on" but 0% brightness

so yes, you need to input both payloads.

Barabba11 commented 3 years ago

Hi, I've tested it now, the input accepts Off and On but doesn't make any change when I send both On and Brightness. I still see the old bightness value. How can I change the brightness to show it properly on homekit? Thank you a lot

crxporter commented 3 years ago

Send first:

{"On":true}

Second:

{"Brightness":30}

Third:

{"Brightness":90}

And so on. Your home app should change as you send these payloads. It is best to send as individual messages, not with two characteristics in a single message (meaning send "On" and "Brightness" completely separately)

Barabba11 commented 3 years ago

I understand, I'll try. This will create me a trouble, I'll need to add split node with 2 outputs and add one delay to give the sequence as you described, this for each light bulb node. On Alexa and Google Home I don't have such problem, from a switch off lamp I can send an on and brightness and I've the desidered result on the app. May you please condsider to add in your node the function (option) to add (internally) an On:true to each Brightness you receive? Thank you a lot!

Barabba11 commented 3 years ago

Hi mates, what is your opinion about my request? I mean, I have several ways to change the bulb status and its brightness, for me is really comfortable to send both status and brightness to the homekit node, and see it reflected to the icons on homekit on phone. Unfortunately if there is an on message the brightness is not changed, it's ignored. Can you kindly correct this? Thank you a lot!

crxporter commented 3 years ago

Well, this isn't a bug. It's not something to fix but it is something we can help you build flows for if you are still struggling. Please share your flow so one of us can take a look and share suggestions on how to make it work more reliably.

We all are using dimmer bulbs and have no issues - the system works as designed by Apple. I have about 25 dimmable bulbs, always working properly for the past few years.

The brightness and on messages should be sent separately to the HomeKit node. This is the best way to be sure both are received. This is how Apple systems expect to receive the data, as two separate messages.

Barabba11 commented 3 years ago

Ok, thanks for your answer, I'm pasting here one light control (I have many of them), where Alexa, Google Home, Homekit and external messages (wall buttons, scenario and Dashboard) are connected and can drive the lamp. All devices got a feedback from a change, so everything is syncronized. Alexa and Google Home can get without problems a message that turns on and regulate intensity, only Homekit needs 2 of them. I'm asking you kindly help to make you module work like others, maybe you can add an option on the light bulb to accept On and Brightness at the same time, thank you a lot!

You may focus only in the first part of the function code, where the sincronization takes place, the second part is about driving the dimmers

[{"id":"61af4795.7c1798","type":"vsh-virtual-device","z":"cc2c1666.3d904","name":"Camera","topic":"Alexa","connection":"74ff5f28.f69a2","template":"DIMMABLE_LIGHT_BULB","passthrough":false,"diff":false,"filter":false,"x":3920,"y":1760,"wires":[["547c9cac.e8cd04"]]},{"id":"811e065a.a837e","type":"noraf-light","z":"cc2c1666.3d904","devicename":"Camera","lightcolor":false,"brightnesscontrol":true,"commandonlycolor":false,"turnonwhenbrightnesschanges":false,"passthru":false,"errorifstateunchaged":false,"statepayload":true,"brightnessoverride":"","roomhint":"Zona Camera","name":"","colortype":"hsv","nora":"da480cdc.493608","topic":"GoogleHome","onvalue":"true","onvalueType":"bool","offvalue":"false","offvalueType":"bool","temperaturemin":"2700","temperaturemax":"5500","twofactor":"off","twofactorpin":"","filter":false,"x":3920,"y":1800,"wires":[["547c9cac.e8cd04"]]},{"id":"d812be7e.4af7b","type":"homekit-service","z":"cc2c1666.3d904","isParent":true,"hostType":"0","bridge":"bd1c7136.ba96d","accessoryId":"","parentService":"","name":"Camera","serviceName":"Lightbulb","topic":"Homekit","filter":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","firmwareRev":"","hardwareRev":"","softwareRev":"","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":"{\"Brightness\":true}","waitForSetupMsg":false,"outputs":2,"x":3920,"y":1840,"wires":[["547c9cac.e8cd04"],[]]},{"id":"547c9cac.e8cd04","type":"function","z":"cc2c1666.3d904","name":"Camera","func":"const sogliabassaintensita=10; //metti qui l'intensità minima della lampada\nconst nomeluceintensita=\"Camera_intensita\";\nconst nomeluce=\"Camera\";\nvar id1=0x95; var id2=0x85; var id3=0xa5; var zona=0x1;\n\n/////////// INCOLLA DA QUI IN POI!!!\n\n// se arriva una direttiva di brightness il comando ha quel valore numerico, e si creano due buffer se prima era spenta, altrimenti solo si varia il brightness\n// uscita 6 comando log/telegram\n// pulsante a muro con topic=nome luce, se numerico è un brighness, altrimenti acceso spento\n\nvar intensitaOUT=0;\nvar acceso=global.get(nomeluce)|| false;\nvar intensita=global.get(nomeluceintensita)|| 0;\nvar comando;\n\nmsg1=null; msg2=null; msg3=null; msg4=null; msg5=null;msg6=null;msg7=null;\n\nif (typeof msg.topic !== 'undefined') {\nif (msg.topic==nomeluce) {\n    if (typeof msg.on !== 'undefined') {\n    if (typeof msg.on != \"boolean\") {\n        comando=msg.on;global.set(nomeluceintensita,msg.on);global.set(nomeluce,true);msg3={payload:{powerState:\"ON\",brightness:msg.on}};msg4={payload:{on:true,brightness:msg.on}};msg5={payload:{On:true,Brightness:msg.on}};msg6={topic:\"Pulsante\",device:nomeluce,payload:{comando:\"reg.intensità\",brightness:msg.on}};}\n    else {\n        if (msg.on===true) {comando=true;global.set(nomeluce,true);msg3={payload:{powerState:\"ON\"}};msg4={payload:{on:true}};msg5={payload:{On:true}};msg6={topic:\"Pulsante\",device:nomeluce,payload:{comando:\"accendi\",brightness:intensita}};}\n        if (msg.on===false) {comando=false;global.set(nomeluce,false);msg3={payload:{powerState:\"OFF\"}};msg4={payload:{on:false}};msg5={payload:{On:false}};msg6={topic:\"Pulsante\",device:nomeluce,payload:{comando:\"spegni\",brightness:intensita}};}}}}\n    \nif (msg.topic==\"Alexa\") {  //prende l'input dall'uscita 3\n\tif (msg.payload.directive==\"TurnOn\") {comando=true;global.set(nomeluce,true);msg3=null;msg4={payload:{on:true}};msg5={payload:{On:true}};msg6={topic:msg.topic,device:nomeluce,payload:{comando:\"accendi\",brightness:msg.payload.brightness}};}\n\tif (msg.payload.directive==\"TurnOff\") {comando=false;global.set(nomeluce,false);global.set(nomeluceintensita,msg.payload.brightness);msg3=null;msg4={payload:{on:false, online: true}};msg5={payload:{On:false}};msg6={topic:msg.topic,device:nomeluce,payload:{comando:\"spegni\",brightness:msg.payload.brightness}};}\n\tif (msg.payload.directive==\"SetBrightness\") {comando=msg.payload.brightness;global.set(nomeluceintensita,msg.payload.brightness);global.set(nomeluce,true);msg3=null;msg4={payload:{on:true,brightness:msg.payload.brightness}};msg5={payload:{On:true,Brightness:msg.payload.brightness}};msg6={topic:msg.topic,device:nomeluce,payload:{comando:\"reg.intensità\",brightness:msg.payload.brightness}};}}\n\nif (msg.topic==\"GoogleHome\") { //prende l'input dall'uscita 4\n\tif (msg.payload.on===true) {\n\t\tif (msg.payload.brightness==intensita) {comando=true; global.set(nomeluce,true);msg3={payload:{powerState:\"ON\"}};msg4=null;msg5={payload:{On:true}};msg6={topic:msg.topic,device:nomeluce,payload:{comando:\"accendi\",brightness:msg.payload.brightness}};} else {comando=msg.payload.brightness;global.set(nomeluceintensita,msg.payload.brightness);global.set(nomeluce,true);msg3={payload:{powerState:\"ON\",brightness:msg.payload.brightness}};msg4=null;msg5={payload:{On:true,Brightness:msg.brightness}};msg6={topic:msg.topic,device:nomeluce,payload:{comando:\"intensità\",brightness:msg.payload.brightness}};}}\n\tif (msg.payload.on===false) {comando=false;global.set(nomeluce,false);global.set(nomeluceintensita,msg.payload.brightness);msg3={payload:{powerState:\"OFF\"}};msg4=null;msg5={payload:{On:false}};msg6={topic:msg.topic,device:nomeluce,payload:{comando:\"spegni\",brightness:msg.payload.brightness}};}}\n\t\nif (msg.topic==\"Homekit\") { //prende l'input dall'uscita 5\n\tif (msg.payload.On===true) {comando=true;global.set(nomeluce,true);msg3={payload:{powerState:\"ON\"}};msg4={payload:{on:true}};msg5=null;msg6={topic:msg.topic,device:nomeluce,payload:{comando:\"accendi\",brightness:global.get(nomeluceintensita)}};}\n\tif (typeof msg.payload.Brightness !== 'undefined') {\n\t\tif (msg.payload.Brightness==intensita) {comando=true;global.set(nomeluce,true);msg3={payload:{powerState:\"ON\"}};msg4={payload:{on:true}};msg5=null;msg6={topic:msg.topic,device:nomeluce,payload:{comando:\"accendi\",brightness:msg.payload.Brightness}};} \n\t\telse {comando=msg.payload.Brightness;global.set(nomeluceintensita,msg.payload.Brightness);global.set(nomeluce,true);msg3={payload:{powerState:\"ON\",brightness:msg.payload.Brightness}};msg4={payload:{on:true,brightness:msg.payload.Brightness}};msg5=null;msg6={topic:msg.topic,device:nomeluce,payload:{comando:\"intensità\",brightness:msg.payload.Brightness}};}}\n\tif (msg.payload.On===false) {comando=false;global.set(nomeluce,false);msg3={payload:{powerState:\"OFF\"}};msg4={payload:{on:false}};msg5=null;msg6={topic:msg.topic,device:nomeluce,payload:{comando:\"spegni\",brightness:global.get(nomeluceintensita)}};}}}\n\nif (typeof comando !== 'undefined') {\nif ((typeof comando != \"boolean\")) { if (comando<sogliabassaintensita) {intensitaOUT=sogliabassaintensita;} else {if (comando>100) {intensitaOUT=100;} else {intensitaOUT=comando;}} \n\tvar intensitaBYTE=Math.round((intensitaOUT/100)*254); if (intensitaBYTE>254) {intensitaBYTE=254;};\n\tvar comandobri1=0x8;var comandobri2=0x38; var comandobri3=intensitaBYTE;\n\tvar checksumBRI=(1+zona+comandobri1+comandobri2+comandobri3);\n\tvar checksumBRI2 = parseInt(checksumBRI,10) & 255;\n\tvar buffer2 = new Uint8Array (24);\n\tbuffer2= Buffer.from([0x55, id1, id2, id3,0x01, zona, comandobri1, comandobri2, comandobri3, checksumBRI2, 0xaa, 0xaa, 0x55, id1, id2, id3,0x01, zona, comandobri1, comandobri2, comandobri3, checksumBRI2, 0xaa, 0xaa]);\n\tbuffer=null;\n\t\n\tif (acceso===false) {\n\tvar comando1=2;var comando2=0x0a; var comando3=0x93;  //se era spenta e arriva solo una cambio di brighness, accendo\n\tvar checksumONOFF=(1+zona+comando1+comando2+comando3);\n\tvar checksumONOFF2 = parseInt(checksumONOFF,10) & 255;\n\tvar buffer = new Uint8Array (24);\n\tbuffer= Buffer.from([0x55, id1, id2, id3,0x01, zona, comando1, comando2, comando3, checksumONOFF2, 0xaa, 0xaa,0x55, id1, id2, id3,0x01, zona, comando1, comando2, comando3, checksumONOFF2, 0xaa, 0xaa]);\n\tnode.status({fill:\"green\",shape:\"dot\",text:global.get(nomeluceintensita)});\n\tmsg1={payload:buffer}; msg2={payload:buffer2}; return [msg1,msg2,msg3,msg4,msg5,msg6];}\n\t\n\telse {msg1=null; msg2={payload:buffer2}; return [msg1,msg2,msg3,msg4,msg5,msg6];}}\n\t\n\tif (comando===true) {\n\tvar comando1=2;var comando2=0x0a; var comando3=0x93;  //accendo\n\tvar checksumONOFF=(1+zona+comando1+comando2+comando3);\n\tvar checksumONOFF2 = parseInt(checksumONOFF,10) & 255;\n\tvar buffer = new Uint8Array (24);\n\tbuffer= Buffer.from([0x55, id1, id2, id3,0x01, zona, comando1, comando2, comando3, checksumONOFF2, 0xaa, 0xaa,0x55, id1, id2, id3,0x01, zona, comando1, comando2, comando3, checksumONOFF2, 0xaa, 0xaa]);\n\tnode.status({fill:\"green\",shape:\"dot\",text:global.get(nomeluceintensita)});\n\tmsg1={payload:buffer}; msg2=null; return [msg1,msg2,msg3,msg4,msg5,msg6];}\n\t  \nif (comando===false) {\n\tvar comando1=2;var comando2=0x0a; var comando3=0x92;  //accendo\n\tvar checksumONOFF=(1+zona+comando1+comando2+comando3);\n\tvar checksumONOFF2 = parseInt(checksumONOFF,10) & 255;\n\tvar buffer = new Uint8Array (24);\n\tbuffer= Buffer.from([0x55, id1, id2, id3,0x01, zona, comando1, comando2, comando3, checksumONOFF2, 0xaa, 0xaa,0x55, id1, id2, id3,0x01, zona, comando1, comando2, comando3, checksumONOFF2, 0xaa, 0xaa]);\n\tnode.status({fill:\"red\",shape:\"dot\",text:global.get(nomeluceintensita)});\n\tmsg1={payload:buffer}; msg2=null; return [msg1,msg2,msg3,msg4,msg5,msg6];}}\n\t\n\telse {return [msg1,msg2,msg3,msg4,msg5,msg6];}\n\t","outputs":6,"noerr":0,"initialize":"global.set(\"Camera_intensita\",100);","finalize":"","libs":[],"x":4080,"y":1800,"wires":[["de842516.57d218"],["bc7eeb43.653ca"],["61af4795.7c1798"],["811e065a.a837e"],["d812be7e.4af7b"],["9e69cdf7.bde5e"]]},{"id":"74ff5f28.f69a2","type":"vsh-connection","name":"AlexaFranco","port":"8883","accessTokenExpiry":"1628520773024","debug":false,"backendUrl":"https://kfd5m4a21f.execute-api.eu-west-1.amazonaws.com/dev","lwaClientId":"amzn1.application-oa2-client.3f1bb07133854b078261ad43f2484c18"},{"id":"da480cdc.493608","type":"noraf-config","name":"DomoticaFranco Nora","group":"","twofactor":"off","twofactorpin":"","localexecution":true,"structure":"Domotica Franco"},{"id":"bd1c7136.ba96d","type":"homekit-bridge","bridgeName":"Homekit-Franco","pinCode":"290-51-967","port":"","advertiser":"bonjour-hap","allowInsecureRequest":false,"manufacturer":"NRCHKB","model":"1.3.6","serialNo":"Default Serial Number","firmwareRev":"1.3.6","hardwareRev":"1.3.6","softwareRev":"1.3.6","customMdnsConfig":false,"mdnsMulticast":true,"mdnsInterface":"","mdnsPort":"","mdnsIp":"","mdnsTtl":"","mdnsLoopback":true,"mdnsReuseAddr":true,"allowMessagePassthrough":false}]
crxporter commented 3 years ago

I'm back. I've looked at your flow.

Checking your function, we are watching output 5 on that node. It appears some places in your function you are setting it like:

msg5 = {
        payload: {
            On: true,
            Brightness: msg.brightness
        }

But other places you set it like:

msg5 = {
        payload: {
            On: true
        }

The recommendation would be to always send "On":bool and "Brightness":int - every time. I save my "Brightness" level in context storage.

I'm asking you kindly help to make you module work like others, maybe you can add an option on the light bulb to accept On and Brightness at the same time, thank you a lot!

I've verified on 2 separate nodered instances running 2 different versions of nrchkb - sending on and brightness together works just as expected. Here is a little video.

https://user-images.githubusercontent.com/38265886/133809451-3161c6d0-7fad-4bb9-9768-a9657ae99447.mov

My flow from this video:

[{"id":"ded9c15a5cfebf69","type":"homekit-service","z":"cdd9b9c6d3ab668d","isParent":true,"hostType":"0","bridge":"58245787ea6ec607","accessoryId":"","parentService":"","name":"Testing One","serviceName":"Lightbulb","topic":"","filter":false,"manufacturer":"NRCHKB","model":"0.140.10","serialNo":"Default Serial Number","firmwareRev":"0.140.10","hardwareRev":"0.140.10","softwareRev":"0.140.10","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":"{\"Brightness\":true}","waitForSetupMsg":false,"outputs":2,"x":310,"y":200,"wires":[["74ae6d3c804d3b8d"],[]]},{"id":"74ae6d3c804d3b8d","type":"debug","z":"cdd9b9c6d3ab668d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":350,"y":260,"wires":[]},{"id":"c715348f2a27d9ce","type":"inject","z":"cdd9b9c6d3ab668d","name":"on with 50","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"On\":true,\"Brightness\":50}","payloadType":"json","x":140,"y":120,"wires":[["ded9c15a5cfebf69"]]},{"id":"6682d31c1449f641","type":"inject","z":"cdd9b9c6d3ab668d","name":"on with 75","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"On\":true,\"Brightness\":75}","payloadType":"json","x":140,"y":180,"wires":[["ded9c15a5cfebf69"]]},{"id":"ee6f09a6466cc8ae","type":"inject","z":"cdd9b9c6d3ab668d","name":"on with 4","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"On\":true,\"Brightness\":4}","payloadType":"json","x":140,"y":240,"wires":[["ded9c15a5cfebf69"]]},{"id":"c61ffdab167842d6","type":"inject","z":"cdd9b9c6d3ab668d","name":"off","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"On\":false}","payloadType":"json","x":130,"y":300,"wires":[["ded9c15a5cfebf69"]]},{"id":"58245787ea6ec607","type":"homekit-bridge","bridgeName":"Nebraska","pinCode":"461-44-559","port":"","advertiser":"bonjour-hap","allowInsecureRequest":false,"manufacturer":"NRCHKB","model":"0.140.10","serialNo":"Default Serial Number","firmwareRev":"0.140.10","hardwareRev":"0.140.10","softwareRev":"0.140.10","customMdnsConfig":false,"mdnsMulticast":true,"mdnsInterface":"","mdnsPort":"","mdnsIp":"","mdnsTtl":"","mdnsLoopback":true,"mdnsReuseAddr":true,"allowMessagePassthrough":true}]
Barabba11 commented 3 years ago

thank you for your kind answer and video, please let me test it deeper. As you admited the node couldn't accepted both commands then I believed you. SOmething went wrong and I'll debug it more. Yes I've 2 different outputs, it depends if the brightness has been changed from the previous command, if not or the command was just "turno on/off" then it just sends On. I was changing brightness from other systems, Alexa and Google went updated but Homekit no, I'll check deeply on that and report you

TheNON75 commented 3 years ago

Hi @Barabba11

Few things came to my mind:

Barabba11 commented 3 years ago

Hi, thanks again for support/suggestions, yesterday I've check it and it works. In the same message I'm senging ON and brightness. I don't now what was going wrong before, seems I haven't manipulated code on that part. Anyway, it's not important now, thanks