Home Assistant + Yeelight + Node-red

Hello,

I'm experiencing an issue where updates to my Node-RED flow are not being applied correctly, specifically with nodes controlling the brightness of lights in my home automation setup. The expected behavior is for the light's brightness to adjust automatically, but this is not occurring.

Key details of the flow include:

  • Nodes designed to auto-adjust light brightness.
  • Nodes to read the current state of a specific light entity, which should inform brightness adjustments.
  • Function nodes to change the brightness value, which should trigger a service call node to turn the lights on or off based on the new value.

Troubleshooting steps taken so far without resolution:

  • Double-checked all node configurations without finding any errors.
  • Confirmed that the Home Assistant server connection is stable.
  • Enabled debug nodes to track the message flow, which revealed that messages are not progressing past a certain point.

I would appreciate any advice on how to resolve this issue or further diagnostic steps I might take.

Thank you.

[
    {
        "id": "d12a5a1662e003af",
        "type": "debug",
        "z": "c1caadbec1b1a6ed",
        "name": "Current",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1280,
        "y": 300,
        "wires": []
    },
    {
        "id": "d5ba2121847a1e40",
        "type": "function",
        "z": "c1caadbec1b1a6ed",
        "name": "Brightness",
        "func": "if (msg.data && msg.data.attributes && msg.data.attributes.brightness) {\n    msg.payload = msg.data.attributes.brightness;\n} else {\n    msg.payload = 0;\n}\nmsg.topic = \"brightness\";\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 530,
        "y": 140,
        "wires": [
            [
                "5ac13cce74afd635",
                "44a3c7ec8351fde9"
            ]
        ]
    },
    {
        "id": "8476482e50c10184",
        "type": "api-current-state",
        "z": "c1caadbec1b1a6ed",
        "name": "Lx[2]",
        "server": "d2dbca488334e1f5",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "sensor.illuminance_2",
        "state_type": "num",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "Illuminance2",
                "valueType": "str"
            }
        ],
        "for": "",
        "forType": "num",
        "x": 330,
        "y": 260,
        "wires": [
            [
                "9926e79c1ea0aa3d"
            ]
        ]
    },
    {
        "id": "1dff93d2e218dd08",
        "type": "api-current-state",
        "z": "c1caadbec1b1a6ed",
        "name": "Lx[1]",
        "server": "d2dbca488334e1f5",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "sensor.lumi_lumi_sen_ill_agl01_illuminance",
        "state_type": "num",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "Illuminance1",
                "valueType": "str"
            }
        ],
        "for": "",
        "forType": "num",
        "x": 330,
        "y": 200,
        "wires": [
            [
                "9926e79c1ea0aa3d"
            ]
        ]
    },
    {
        "id": "c6a6b09c6228f567",
        "type": "inject",
        "z": "c1caadbec1b1a6ed",
        "name": "targetLux",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "10",
        "crontab": "",
        "once": true,
        "onceDelay": "1",
        "topic": "targetLux",
        "payload": "600",
        "payloadType": "num",
        "x": 530,
        "y": 260,
        "wires": [
            [
                "ef1d8d194b3fd7c2",
                "5ac13cce74afd635"
            ]
        ]
    },
    {
        "id": "11f985fbbcce3a10",
        "type": "inject",
        "z": "c1caadbec1b1a6ed",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "10",
        "crontab": "",
        "once": true,
        "onceDelay": "1",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 130,
        "y": 140,
        "wires": [
            [
                "8476482e50c10184",
                "1dff93d2e218dd08",
                "1e235b51479854da"
            ]
        ]
    },
    {
        "id": "api-call-service",
        "type": "api-call-service",
        "z": "c1caadbec1b1a6ed",
        "name": "Adjust Brightness",
        "server": "d2dbca488334e1f5",
        "version": 5,
        "debugenabled": false,
        "domain": "light",
        "service": "turn_on",
        "areaId": [
            "univ"
        ],
        "deviceId": [
            "5d552989c1687463a59634a3cebb4b4e"
        ],
        "entityId": [
            "light.yeelight_cta"
        ],
        "data": "{\"brightness\": {{payload}}}",
        "dataType": "json",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [
            {
                "property": "brightness",
                "propertyType": "msg",
                "value": "",
                "valueType": "data"
            }
        ],
        "queue": "none",
        "x": 1090,
        "y": 300,
        "wires": [
            [
                "d12a5a1662e003af"
            ]
        ]
    },
    {
        "id": "ef1d8d194b3fd7c2",
        "type": "debug",
        "z": "c1caadbec1b1a6ed",
        "name": "Target",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 730,
        "y": 260,
        "wires": []
    },
    {
        "id": "9926e79c1ea0aa3d",
        "type": "function",
        "z": "c1caadbec1b1a6ed",
        "name": "Average",
        "func": "let illuminance1 = msg.payload.illuminance1;\nlet illuminance2 = msg.payload.illuminance2;\nlet averageLux = (illuminance1 + illuminance2) / 2;\n\nmsg.topic = \"averageLux\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 540,
        "y": 200,
        "wires": [
            [
                "5ac13cce74afd635"
            ]
        ]
    },
    {
        "id": "ba36f07674b7f27d",
        "type": "debug",
        "z": "c1caadbec1b1a6ed",
        "name": "Join",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 870,
        "y": 140,
        "wires": []
    },
    {
        "id": "5ac13cce74afd635",
        "type": "join",
        "z": "c1caadbec1b1a6ed",
        "name": "",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "3",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 730,
        "y": 200,
        "wires": [
            [
                "ba36f07674b7f27d",
                "b28ac008890a7777"
            ]
        ]
    },
    {
        "id": "slider_node",
        "type": "ui_slider",
        "z": "c1caadbec1b1a6ed",
        "name": "Brightness Control",
        "label": "Brightness",
        "tooltip": "",
        "group": "8cf48b5c5520472e",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": true,
        "outs": "all",
        "topic": "brightness",
        "topicType": "str",
        "min": 0,
        "max": "255",
        "step": "1",
        "className": "",
        "x": 1090,
        "y": 180,
        "wires": [
            []
        ]
    },
    {
        "id": "b28ac008890a7777",
        "type": "function",
        "z": "c1caadbec1b1a6ed",
        "name": "Adjust",
        "func": "var current = msg.payload.brightness;\nvar averageLux = msg.payload.averageLux;\nvar targetLux = msg.payload.targetLux;\n\nif (averageLux < targetLux) {\n    current = Math.min(current + 1, 255);\n    \n} else if (averageLux > targetLux) {\n    current = Math.max(current - 1, 0);\n}\n\nmsg.payload = current;\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 870,
        "y": 200,
        "wires": [
            [
                "slider_node",
                "1dbce4a272b06f32",
                "db4a41e0b6ae2251",
                "api-call-service"
            ]
        ]
    },
    {
        "id": "1dbce4a272b06f32",
        "type": "debug",
        "z": "c1caadbec1b1a6ed",
        "name": "Current",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1060,
        "y": 140,
        "wires": []
    },
    {
        "id": "44a3c7ec8351fde9",
        "type": "debug",
        "z": "c1caadbec1b1a6ed",
        "name": "Join",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 710,
        "y": 140,
        "wires": []
    },
    {
        "id": "db4a41e0b6ae2251",
        "type": "ui_numeric",
        "z": "c1caadbec1b1a6ed",
        "name": "",
        "label": "numeric",
        "tooltip": "",
        "group": "8cf48b5c5520472e",
        "order": 2,
        "width": 0,
        "height": 0,
        "wrap": false,
        "passthru": true,
        "topic": "topic",
        "topicType": "msg",
        "format": "{{value}}",
        "min": 0,
        "max": 10,
        "step": 1,
        "className": "",
        "x": 1060,
        "y": 240,
        "wires": [
            []
        ]
    },
    {
        "id": "1e235b51479854da",
        "type": "api-current-state",
        "z": "c1caadbec1b1a6ed",
        "name": "Yeelight",
        "server": "d2dbca488334e1f5",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "light.yeelight_cta",
        "state_type": "str",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            }
        ],
        "for": "0",
        "forType": "num",
        "forUnits": "minutes",
        "override_topic": false,
        "state_location": "payload",
        "override_payload": "msg",
        "entity_location": "data",
        "override_data": "msg",
        "x": 340,
        "y": 140,
        "wires": [
            [
                "d5ba2121847a1e40"
            ]
        ]
    },
    {
        "id": "d2dbca488334e1f5",
        "type": "server",
        "name": "Home Assistant",
        "version": 5,
        "addon": false,
        "rejectUnauthorizedCerts": false,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30",
        "areaSelector": "friendlyName",
        "deviceSelector": "friendlyName",
        "entitySelector": "friendlyName",
        "statusSeparator": ": ",
        "statusYear": "hidden",
        "statusMonth": "short",
        "statusDay": "numeric",
        "statusHourCycle": "default",
        "statusTimeFormat": "h:m",
        "enableGlobalContextStore": false
    },
    {
        "id": "8cf48b5c5520472e",
        "type": "ui_group",
        "name": "Light",
        "tab": "9878f0c8e89c7659",
        "order": 2,
        "disp": false,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "9878f0c8e89c7659",
        "type": "ui_tab",
        "name": "Emotional Lighting",
        "icon": "dashboard",
        "order": 3,
        "disabled": false,
        "hidden": false
    }
]

Your Average node sets msg.topic, but it doesn't set msg.payload

let illuminance1 = msg.payload.illuminance1;
let illuminance2 = msg.payload.illuminance2;
let averageLux = (illuminance1 + illuminance2) / 2;

msg.topic = "averageLux";
return msg;

Using a join node to feed the three parameters into a common payload won't work as you expect: There's no guarantee that those 3 incoming messages (that join is configured to wait for) are from the three branches of your flow. Consequentially you might end with a payload that doesn't carry the data necessary to perform your calculations (in Adjust).

The standard pattern to achieve what you intended is to put the latest read of any parameter into a context and perform the calculation (some nodes later) by getting the whole parameter set back from context, e.g.:

Average:

let illuminance1 = msg.payload.illuminance1;
let illuminance2 = msg.payload.illuminance2;
let averageLux = (illuminance1 + illuminance2) / 2;
context.set("averageLux", averageLux);
return msg;

Adjust:

let current = context.get("brightness");
let averageLux = context.get("averageLux");
let targetLux = context.get("targetLux");

if (averageLux < targetLux) {
    current = Math.min(current + 1, 255);
    
} else if (averageLux > targetLux) {
    current = Math.max(current - 1, 0);
}

msg.payload = current;
return msg;