Core: (0.111) Starting Frontend Sooner: Causes Automation Issues with Web Sockets

Created on 13 Jun 2020  路  9Comments  路  Source: home-assistant/core

The problem


Since 0.111, I've noticed that starting the front-end sooner has an unintended consequence. Web sockets are available sooner, so any applications that connects to Home Assistant via web sockets receives state_changed events.

If you're using something like Node-RED, this can mean automations are being fired during startup. The state_changed events being sent as Home Assistant starts up contain valid new_state and old_state values, i.e. the exact same change that occurred last time the state changed on the entity.

So, for example, if I a sensor was turned on prior to HomeAssistant restarting, you'll get an event like this:

{
  "topic": "binary_sensor.someone_home",
  "payload": "on",
  "data": {
    "event_type": "state_changed",
    "entity_id": "binary_sensor.someone_home",
    "event": {
      "entity_id": "binary_sensor.someone_home",
      "old_state": {
        "entity_id": "binary_sensor.someone_home",
        "state": "off",
        "attributes": {
          "probability": 0.17,
          "probability_threshold": 0.8,
          "friendly_name": "Someone Home"
        },
        "last_changed": "2020-06-13T15:31:33.879660+00:00",
        "last_updated": "2020-06-13T15:31:33.879660+00:00",
        "context": {
          "id": "949dd4133c884cd09e93049ffc09c434",
          "parent_id": null,
          "user_id": null
        }
      },
      "new_state": {
        "entity_id": "binary_sensor.someone_home",
        "state": "on",
        "attributes": 
          "probability": 0.98,
          "probability_threshold": 0.8,
          "friendly_name": "Someone Home"
        },
        "last_changed": "2020-06-13T15:31:39.192936+00:00",
        "last_updated": "2020-06-13T15:31:39.192936+00:00",
        "context": {
          "id": "3f729bd68fab49afa135cd2456d58ab3",
          "parent_id": null,
          "user_id": null
        },
        "timeSinceChangedMs": 541
      }
    }
  },
  "_msgid": "38c11063.1dc8f"
}

The state_changed event contains the current state of on and the previous state of off, even though the change occurred prior to Home Assistant restarting. To make things further confusing, the last_changed and last_updated values contain the current time, so no logic could be written to determine if the state change is recent.

Under a restart scenario where the frontend comes online sooner, I would expect one of the following as Home Assistant starts up:

  • For state_changed events, the new_state and old_state are the same, since the state hasn't really changed (just the last event is being resent).
  • For state_changed events, the new_state contains the current state and old_state contains unavailable or some other value.
  • There is an additional value in the state_changed payload to indicate it's a result of the frontend starting up and could potentially be ignored.
  • Only the frontend is able to connect to the web sockets during a restart and additional clients like Node-RED are prevented from connecting until Home Assistant is done restarting.
  • New startup events are fired that can be used in automations to ignore state_changed events. For example, perhaps core_initializing and core_initialized events?

Environment

  • Home Assistant Core release with the issue: 0.111.1
  • Last working Home Assistant Core release (if known): 0.110.x
  • Operating environment (Home Assistant/Supervised/Docker/venv): Docker
  • Integration causing this issue: Web Sockets
  • Link to integration documentation on our website: https://developers.home-assistant.io/docs/api/websocket/

Problem-relevant configuration.yaml


Traceback/Error logs


Additional information

websocket_api stale

Most helpful comment

Fetch the config of Home Assistant and see if config.state="running". If not, listen for homeassistant_started or core_config_updated and fetch config again.

All 9 comments

Doing more debugging, I'm finding it's not every entity that this is occurring for. The state changes are valid, but they're state changes as a result of startup.

For example, here are a few that's I've found so far:

  • device_tracker entities initialize as not_home then change to correct state a few seconds later
  • light entities through lutron_caesta initialize as off then change to correct state a few seconds later
  • vacuum entities through roomba initialize as docked then change to correct state a few seconds later

Hey there @home-assistant/core, mind taking a look at this issue as its been labeled with a integration (websocket_api) you are listed as a codeowner for? Thanks!
(message by CodeOwnersMention)

That is not an issue on the Supervisord system because the API proxy is aware of we first initialize the connection if HA Core is started.

However, You need to open an issue on the NoteRed HA plugin, that they check if ha is a startup or not.

I agree that ultimate solution lies with the Node-RED HA plugin, but shouldn't this be listed as a breaking change and guidance be given for any system using the WebSocket API?

What should the Node-RED plugin (or any WebSocket integration) be looking for? What events are emitted from HA or what entities can be checked to verify HA is now in a safe state to consider state_changed events legitimate?

Fetch the config of Home Assistant and see if config.state="running". If not, listen for homeassistant_started or core_config_updated and fetch config again.

Perfect, thank you for the guidance. I logged an issue against the Node-RED plugin.

In the meantime, I came up with a workaround for my Node-RED flows. I created an input_boolean that initializes to false on startup:

homeassistant_started:
  name: HomeAssistant Started
  icon: mdi:home-assistant
  initial: false

Then, I created an automation that flips the boolean to on after HomeAssistant starts up:

- alias: HomeAssistant - Startup Boolean
  trigger:
    - platform: homeassistant
      event: start
  action:
    service: input_boolean.turn_on
    entity_id: input_boolean.homeassistant_started

I added an extra check to all of my Node-RED flows to verify input_boolean.homeassistant_started is on and that seems to resolve my issue with flows being triggered during startup.

@ronaldheft can you link the issue you submitted to nodered plugin? I would like to follow as i am also having a lot of flows fire on homeassistant restart and it is causing all sorts of problems. Having to add an input_boolean to every automation in there is not a feasible solution imo and should have been listed as a breaking change.

@damusmf Should be referenced up above, but here is the issue I submitted: https://github.com/zachowj/node-red-contrib-home-assistant-websocket/issues/246

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.
Please make sure to update to the latest Home Assistant version and check if that solves the issue. Let us know if that works for you by adding a comment 馃憤
This issue now has been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings