node-red-contrib-home-assistant-websocket icon indicating copy to clipboard operation
node-red-contrib-home-assistant-websocket copied to clipboard

Events: State node not updating when state changes quickly

Open corentincam opened this issue 1 year ago • 4 comments

Describe the bug

I set up a events: state node to track a media player entity and detect when it is off for 30s. This entity has several states and often go very quickly through playing -> idle -> off (when I turn it off without pausing first, which happens all the time).

When this happens, the node gets stuck on detecting the idle state.

To Reproduce

image

This flow triggers the behavior every time (when the events: state node is freshly created).

When triggering the on/off rapid change, the node gets stuck on on as in the picture. If I modify the node (eg. adding one second to the condition timer) the problem seems to disappear.

Expected behavior

The events: state node should update with every new entity state, it should not get stuck on a previous spurious state.

Screenshots

See "To Reproduce"

Example Flow

[
    {
        "id": "b7e4849481078ecb",
        "type": "inject",
        "z": "6ddd43f722a7d8c4",
        "name": "state: on",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"state\": \"on\"}",
        "payloadType": "json",
        "x": 500,
        "y": 400,
        "wires": [
            [
                "d7eeb7532c702b40",
                "a8f4683f61c7875c"
            ]
        ]
    },
    {
        "id": "d7eeb7532c702b40",
        "type": "ha-binary-sensor",
        "z": "6ddd43f722a7d8c4",
        "name": "Test",
        "entityConfig": "c42a1064b34f56ba",
        "version": 0,
        "state": "payload",
        "stateType": "msg",
        "attributes": [],
        "inputOverride": "allow",
        "outputProperties": [],
        "x": 990,
        "y": 400,
        "wires": [
            []
        ]
    },
    {
        "id": "70dfb9d8cbb44cef",
        "type": "change",
        "z": "6ddd43f722a7d8c4",
        "name": "state: off",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"state\": \"off\"}",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 840,
        "y": 440,
        "wires": [
            [
                "d7eeb7532c702b40"
            ]
        ]
    },
    {
        "id": "a8f4683f61c7875c",
        "type": "delay",
        "z": "6ddd43f722a7d8c4",
        "name": "",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 670,
        "y": 440,
        "wires": [
            [
                "70dfb9d8cbb44cef"
            ]
        ]
    },
    {
        "id": "f31abd21194efb76",
        "type": "debug",
        "z": "6ddd43f722a7d8c4",
        "name": "debug 1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 640,
        "y": 500,
        "wires": []
    },
    {
        "id": "1d627caad77bbc1b",
        "type": "server-state-changed",
        "z": "6ddd43f722a7d8c4",
        "name": "Test",
        "server": "698955f7329cbccb",
        "version": 6,
        "outputs": 2,
        "exposeAsEntityConfig": "",
        "entities": {
            "entity": [
                "binary_sensor.nodered_c42a1064b34f56ba"
            ],
            "substring": [],
            "regex": []
        },
        "outputInitially": false,
        "stateType": "str",
        "ifState": "off",
        "ifStateType": "str",
        "ifStateOperator": "is",
        "outputOnlyOnStateChange": true,
        "for": "4",
        "forType": "num",
        "forUnits": "seconds",
        "ignorePrevStateNull": false,
        "ignorePrevStateUnknown": false,
        "ignorePrevStateUnavailable": false,
        "ignoreCurrentStateUnknown": false,
        "ignoreCurrentStateUnavailable": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            }
        ],
        "x": 490,
        "y": 500,
        "wires": [
            [
                "f31abd21194efb76"
            ],
            []
        ]
    },
    {
        "id": "c42a1064b34f56ba",
        "type": "ha-entity-config",
        "server": "698955f7329cbccb",
        "deviceConfig": "962f037da5ef28aa",
        "name": "Test",
        "version": "6",
        "entityType": "binary_sensor",
        "haConfig": [
            {
                "property": "name",
                "value": "Test"
            },
            {
                "property": "icon",
                "value": ""
            },
            {
                "property": "entity_picture",
                "value": ""
            },
            {
                "property": "entity_category",
                "value": ""
            },
            {
                "property": "device_class",
                "value": ""
            }
        ],
        "resend": false,
        "debugEnabled": false
    },
    {
        "id": "698955f7329cbccb",
        "type": "server",
        "name": "Home Assistant",
        "version": 5,
        "addon": false,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30",
        "areaSelector": "friendlyName",
        "deviceSelector": "friendlyName",
        "entitySelector": "friendlyName",
        "statusSeparator": "at: ",
        "statusYear": "hidden",
        "statusMonth": "short",
        "statusDay": "numeric",
        "statusHourCycle": "h23",
        "statusTimeFormat": "h:m",
        "enableGlobalContextStore": true
    },
    {
        "id": "962f037da5ef28aa",
        "type": "ha-device-config",
        "name": "Test",
        "hwVersion": "",
        "manufacturer": "Node-RED",
        "model": "",
        "swVersion": ""
    }
]

Environment Information

Version: 0.73.0

Home Assistant version: 2024.10.2 Companion version: 4.1.1

Node-RED version: 4.0.5 Docker: yes Add-on: no

Node.js version: v18.20.4 x64 linux OS: Linux 6.1.0-23-amd64 x64

Additional context

No response

corentincam avatar Oct 15 '24 13:10 corentincam

Is the state change being detected by Home Assistant from the media player? You can confirm this by listening for the state_changed event in Home Assistant:

  1. Go to Developer Tools > Events.
  2. Under Listen to events, type state_changed and click Start Listening.

You can also verify this in Node-RED by using an events: all node to see if the event is being picked up there as well.

zachowj avatar Oct 17 '24 21:10 zachowj

I can see the event is detected by Home Assistant in the developer tools, the events: all node catches it, as well as the events: state if I remove the timed condition.

The only way to reproduce seems to be by adding a timed condition on the events: state node

corentincam avatar Oct 24 '24 13:10 corentincam

When the 'for' condition is set in the events: state node, the entity's state must remain unchanged for the specified duration. Since you're mentioning the state changes rapidly and within the 4-second window, it won't capture the intermediate states.

zachowj avatar Oct 26 '24 04:10 zachowj

As I understand it, the node's output is triggered if the state matches the required state during the given period, so it doesn't matter if the state changes from an unmatched state to a matched state within this period, does it?

For example, if I set the node to wait for the entity to be in state1 during 30s I'm expecting the node to:

  • output something if the entity goes rapidly through anything->state2->state1 then stays in state1 during 30s
  • output nothing if the entity goes rapidly through anything->state1->state2 (as it will stay less than 30s in the state1 state)

Am I understanding it wrong?

corentincam avatar Nov 14 '24 13:11 corentincam