Skip to content

custom component switch gets unavailable after changing the state in HA #1721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tmp-e opened this issue Dec 26, 2024 · 2 comments
Open

custom component switch gets unavailable after changing the state in HA #1721

tmp-e opened this issue Dec 26, 2024 · 2 comments

Comments

@tmp-e
Copy link

tmp-e commented Dec 26, 2024

Describe the bug

Creating a switch with API: nodered/discovery works as expected.
Also changing the state in nodered through API: nodered/entity works well, the switch is shown in homeassistant dashboards and the state is reflected correctly.

But when changing the switch state in homeassistant, it immediately gets "unavailable".
Then, also any further change through API: nodered/entity has no effect.

To Reproduce

  1. Create a switch with API: nodered/discovery:
msg.payload = {
    data: {
        type: "nodered/discovery",
        component: "switch",
        server_id: "home",
        node_id: "my_test_switch",
        
        config: {
            name: "My Test Switch"
        }
    }
}
  1. Change switch state in homeassistant

Expected behavior

The switch should schange the state and be available

Screenshots

Switch in homeassistant after registering with nodered/discovery
on

Switch after trying to change state in HA
Note: "German "nicht verfügbar" = "not available"
off

Example Flow

[
    {
        "id": "3e8d201af9b3ab92",
        "type": "function",
        "z": "fe6d6eb28ba94acb",
        "name": "register \"My Test Switch\"",
        "func": "\nmsg.payload = {\n    data: {\n        type: \"nodered/discovery\",\n        component: \"switch\",\n        server_id: \"home\",\n        node_id: \"my_test_switch\",\n        \n        config: {\n            name: \"My Test Switch\"\n        }\n    }\n}\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 370,
        "y": 1920,
        "wires": [
            [
                "f2f11101b98595ba"
            ]
        ]
    },
    {
        "id": "f2f11101b98595ba",
        "type": "ha-api",
        "z": "fe6d6eb28ba94acb",
        "name": "",
        "server": "acfbfb24.12e808",
        "version": 1,
        "debugenabled": false,
        "protocol": "websocket",
        "method": "get",
        "path": "",
        "data": "",
        "dataType": "jsonata",
        "responseType": "json",
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "results"
            }
        ],
        "x": 590,
        "y": 1920,
        "wires": [
            [
                "1fc2b3eef146b652"
            ]
        ]
    },
    {
        "id": "f4c278ef467f984b",
        "type": "inject",
        "z": "fe6d6eb28ba94acb",
        "name": "",
        "props": [],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 150,
        "y": 1920,
        "wires": [
            [
                "3e8d201af9b3ab92"
            ]
        ]
    },
    {
        "id": "1fc2b3eef146b652",
        "type": "debug",
        "z": "fe6d6eb28ba94acb",
        "name": "output",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 750,
        "y": 1920,
        "wires": []
    },
    {
        "id": "acfbfb24.12e808",
        "type": "server",
        "name": "Home Assistant",
        "addon": true
    }
]

Environment Information

Version: 0.74.2

Home Assistant version: 2024.12.5
Companion version: 4.1.2

Node-RED version: 4.0.3
Docker: yes
Add-on: 18.1.1

Node.js version: v18.20.4 arm64 linux
OS: Linux 6.6.62-haos-raspi arm64

Additional context

No response

@zachowj
Copy link
Owner

zachowj commented Dec 26, 2024

Is there a reason you're not using the switch node which will handle all the background tasks for you?

The issue with the switch entity lies in the communication protocol. The discovery call, intended to be a subscription call, should establish a two-way path. This path would allow Home Assistant to send data back to Node-RED, such as updates on the switch's state. However, the API node in Node-RED can only make one-way calls and cannot receive subscriptions.

Consequently, when the switch's state changes in Home Assistant and this information is sent to Node-RED, Node-RED expects a response. Since the two-way communication was never established and Node-RED never received the update from Home Assistant, it cannot update Home Assistant accordingly. Home Assistant then interprets this lack of response as the switch becoming unavailable.

@tmp-e
Copy link
Author

tmp-e commented Dec 27, 2024

Hi @zachowj , thank you for your quick response. I really appreciate your detailed explanations.

I'm using the switch node a lot, as well as the other nodes (binary sensor, sensor, number ...), for instance to process data from my entities within nodered and have the possibility to view the result and interact from HA dashboards.

At some point in time, as flows got bigger, I started to generalize the functionality by introducing a dummy subflow that handles any input datatype (numeric, binary, strings), optionally allows to configure a measurement type and exposes the data as a HA entity. That works well for viewing data, but not for switches.

As a core functionality for my dummy I needed a way to create the HA entities from the flow and env context data, e.g. the data type, name, unit etc. In old discussions I've seen the possibility to use the nodered/discovery API for that.

In principle I'm trying to re-produce the ha-entity-config on my own, as I was not able to use/call it within my dummy subflow, having parameters passed to it.
If there would be a way to re-use ha-entity-config and populate the parameters from my flow and env context data,
I guess that would also solve my issue.

Anoher solution could be to listen for switch changes by the call-service event, which shows the turn_off event (I suppose it's from HA). But I did not find out how to forward this event back to Node-RED / back to HA, as you explained.

{"event_type":"call_service","event":{"domain":"switch","service":"turn_off","service_data":{"entity_id":"switch.my_test_switch"}},"origin":"LOCAL","time_fired":"2024-12-27T08:25:42.643794+00:00","context":{"id":"01JG3KHBFKCY9TYFDYTWWPAZRC","parent_id":null,"user_id":"c8e4c9953ad04f4c9fc85274b99b9790"}}

Do you see any workaround that I could implement?

Thank you a lot in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants