mjwwit / node-red-contrib-ikea-tradfri

Node-RED nodes to get updates from and control devices connected to an IKEA TRADFRI gateway
3 stars 3 forks source link

send moods to light control node #25

Closed Jan21493 closed 2 years ago

Jan21493 commented 2 years ago

I've just started with node red, so maybe there is something I have missed or overlooked, but when I've created my first nodes to connect Loxone home automation with some IKEA tradfri lights it did not fully worked as expected. To narrow down the problem, I've created a simple test flow (see below) to reproduce the issue:

If I only change color (EDIT: must be brightness) OR color temperature, everything works fine. If I change BOTH at the same time with the moods provided in the example, the first push only changes the color temperature and I have to push the inject node again to change the brightness.

Example code to replicate problem ```yaml [ { "id": "99b13acd3b287f48", "type": "tab", "label": "Test tunable white light bulb", "disabled": false, "info": "", "env": [] }, { "id": "3f69107eea63e2a1", "type": "tradfri-light-control", "z": "99b13acd3b287f48", "gateway": "06a0a469d683c2d3", "name": "Tradfri Spot", "action": "{}", "accessories": [ "" ], "groups": [ "", "" ], "logInputErrors": true, "x": 770, "y": 320, "wires": [] }, { "id": "323819df4f510759", "type": "debug", "z": "99b13acd3b287f48", "name": "send to light control node", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 810, "y": 420, "wires": [] }, { "id": "28377b52576fbbbb", "type": "inject", "z": "99b13acd3b287f48", "name": "cold, bright", "props": [ { "p": "payload" }, { "p": "topic", "v": "1", "vt": "num" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"colorTemperature\":0,\"brightness\":100}", "payloadType": "json", "x": 190, "y": 180, "wires": [ [ "c6185d3a89119f97" ] ] }, { "id": "b23a1465e1424640", "type": "inject", "z": "99b13acd3b287f48", "name": "neutral, middle", "props": [ { "p": "payload" }, { "p": "topic", "v": "1", "vt": "num" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"colorTemperature\":41,\"brightness\":50}", "payloadType": "json", "x": 200, "y": 220, "wires": [ [ "c6185d3a89119f97" ] ] }, { "id": "702b283c5334c8e3", "type": "inject", "z": "99b13acd3b287f48", "name": "warm, soft", "props": [ { "p": "payload" }, { "p": "topic", "v": "1", "vt": "num" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"colorTemperature\":100,\"brightness\":25}", "payloadType": "json", "x": 180, "y": 260, "wires": [ [ "c6185d3a89119f97" ] ] }, { "id": "e0bc6cfe257805c2", "type": "inject", "z": "99b13acd3b287f48", "name": "dark", "props": [ { "p": "payload" }, { "p": "topic", "v": "1", "vt": "num" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"onOff\":false}", "payloadType": "json", "x": 170, "y": 660, "wires": [ [ "c6185d3a89119f97" ] ] }, { "id": "c6185d3a89119f97", "type": "change", "z": "99b13acd3b287f48", "name": "Spot A1-A5", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "[65550,65551,65552,65553,65554]", "tot": "json" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 570, "y": 320, "wires": [ [ "3f69107eea63e2a1", "323819df4f510759" ] ] }, { "id": "2226b3c30cf753c4", "type": "inject", "z": "99b13acd3b287f48", "name": "bright", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"brightness\":100}", "payloadType": "json", "x": 170, "y": 540, "wires": [ [ "c6185d3a89119f97" ] ] }, { "id": "2e0c9fda893f7869", "type": "inject", "z": "99b13acd3b287f48", "name": "middle", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"brightness\":50}", "payloadType": "json", "x": 170, "y": 580, "wires": [ [ "c6185d3a89119f97" ] ] }, { "id": "098e5d1e3c6f9134", "type": "inject", "z": "99b13acd3b287f48", "name": "soft", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"brightness\":25}", "payloadType": "json", "x": 170, "y": 620, "wires": [ [ "c6185d3a89119f97" ] ] }, { "id": "1d71db24a31d5707", "type": "comment", "z": "99b13acd3b287f48", "name": "Moods", "info": "", "x": 150, "y": 140, "wires": [] }, { "id": "e32c7de46d42906f", "type": "comment", "z": "99b13acd3b287f48", "name": "brightness", "info": "", "x": 160, "y": 500, "wires": [] }, { "id": "a1ca401374303005", "type": "inject", "z": "99b13acd3b287f48", "name": "cold", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"colorTemperature\":0}", "payloadType": "json", "x": 170, "y": 360, "wires": [ [ "c6185d3a89119f97" ] ] }, { "id": "0e4442bd7e5a13c8", "type": "inject", "z": "99b13acd3b287f48", "name": "neutral", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"colorTemperature\":41}", "payloadType": "json", "x": 170, "y": 400, "wires": [ [ "c6185d3a89119f97" ] ] }, { "id": "4a5260c092651ff3", "type": "inject", "z": "99b13acd3b287f48", "name": "warm", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"colorTemperature\":100}", "payloadType": "json", "x": 170, "y": 440, "wires": [ [ "c6185d3a89119f97" ] ] }, { "id": "6ea94f08409e8335", "type": "comment", "z": "99b13acd3b287f48", "name": "color temperature", "info": "", "x": 190, "y": 320, "wires": [] }, { "id": "06a0a469d683c2d3", "type": "tradfri-config", "name": "MyHome", "gatewayHost": "my-TRADFRI-Gateway.local", "identity": "my_tradfri_ID", "preSharedKey": "my_key" } ] ```

I'm also looking for some examples how to use the different nodes from this node library.

Jan21493 commented 2 years ago

As a workaround I've added a parallel path with delay before sending the message to light control node. It contains two node: at first a change node that has set msg.delay to the value J: payload.transitionTime * 1200 and a delay node with option override delay with msg.delay (in ms!). Not really good, but at least the state is reflecting the command I've send to the bulbs.

Jan21493 commented 2 years ago

It turned out that the workaround above was not that good for my setup, when I send more changes in a short amount of time, but found another workaround: msg.payload.transitionTime = 0; With that setting I don't have the smooth transitions that are quite nice, but it's working well. Maybe there is a bug in the way transitions are handled, if brightness and temperature are changed at the same time?

mjwwit commented 2 years ago

I'm assuming you mean setting the brightness and colorTemperature, as setting color and colorTemperature would obviously be a conflict.

Anyway, I've noticed that you're using a list of IDs. Have you tried to do this with a single bulb? The gateway can be very quirky when controlling a bunch of accessories and may confirm commands that it's not actually executing... If this is the case then there's no real way around it other than to add a delay between updating each device (which may end up looking very awkward).

You could also try to use scenes to pre-define the "moods" and activate these scenes instead of directly controlling the bulbs.

Jan21493 commented 2 years ago

Hi Michael, yes, you're right it meant brightness as you have assumed. The problem has nothing to do with the number of IDs and you may reproduce the problem with a single ID, but it only occurs if transitionTime is >0, and both brightness and colorTemperature are send at the same time, e.g.: {"transitionTime":1,"colorTemperature":100,"brightness":10} and then {"transitionTime":1,"colorTemperature":0,"brightness":50} It only happens if both values are changed. I'll have a look into the code to find out if transitionTime is handled in your code, the underlying library or in the gateway itself. Maybe I'm able to get further information about the source of the problem.

In my situation "moods" are not a solution, because I have integrated the Tradfri lights into my existing home automation system called "Loxone" that is using moods/scenes internally, but only sending actual values to the lights. Loxone has a "tunable white" light object, so I'm getting a brightness and colorTemperature change at the same time. The workaround is to set transitionTime to 0. The dimming is not that nice, but it's working.

Jan21493 commented 2 years ago

Now I had a look into the code of this node as well as on the underlying code from AlCalzone to find out that transitionTime is a native property of the light bulbs.

However it does NOT work as expected if transitionTime is >0, and both brightness and colorTemperature need to be changed at the same time. The words need to be changed are important, because it works if both are send at the same time, but only one property needs to be adjusted. If both need to be adjusted, then colorTemperature looks to have priority and a change of brightness is ignored. If colorTemperature has the desired value already, then brightness is adjusted as expected.

To verify the results, I've used coap-client, so I'm on a very low level and have send the following 4 commands:

// properties send: {"5712":transitionTime in 10th of second ?, "5851":brightness from 0 to 254,"5850":0=off and 1=on,"5711":colorTemperature from 250=warm to 454=cold}

// send soft warm white with smooth transition to a single light 
coap-client -m PUT -u my_tradfri_name -k "my_tradfri_key" -e '{"3311":[{"5712":20,"5851":64,"5850":1,"5711":454}]}' "coaps://192.168.128.73:5684/15001/65554" | sed "1,3d" | jq

// send it again to be sure that the light is set to these values
coap-client -m PUT -u my_tradfri_name -k "my_tradfri_key" -e '{"3311":[{"5712":20,"5851":64,"5850":1,"5711":454}]}' "coaps://192.168.128.73:5684/15001/65554" | sed "1,3d" | jq

// now send **bright** cold white with smooth transition 
coap-client -m PUT -u my_tradfri_name -k "my_tradfri_key" -e '{"3311":[{"5712":20,"5851":254,"5850":1,"5711":250}]}' "coaps://192.168.128.73:5684/15001/65554" | sed "1,3d" | jq

// -> returns soft cold white ! So it's a bug or unsupported feature!

// send bright cold white with smooth transition **again** (the same values)
coap-client -m PUT -u my_tradfri_name -k "my_tradfri_key" -e '{"3311":[{"5712":20,"5851":254,"5850":1,"5711":250}]}' "coaps://192.168.128.73:5684/15001/65554" | sed "1,3d" | jq
// -> returns bright cold white as expected

It looks that this is a bug in the IKEA Tradfri gateway itself, so I must have to live with it :-( I believe that there isn't any proper way to tell IKEA that there is such a bug as they don't have published the API. Even if, they may not see it as a bug, but just as a non-supported combination?

Anyway, I'll set transitionTime to 0 as a workaround.

Btw: I've written a guide Debugging COAPS with IKEA Tradfri gateway - my first work on Github!

In the last part of that guide there is a section that explains how to get the pre-shared key from the IKEA Smart Home app to be able to read all CoAP communication between the IKEA Smart Home app and the Tradfri gateway with Wireshark in clear text.

mjwwit commented 2 years ago

Yeah, the gateway can be very quirky like that. I'll close this issue, but maybe I'll link to your debugging project from the README as this probably won't be the last gateway quirk users of this module will encounter...