palazzem / ha-econnect-alarm

Home Assistant integration that provides a full-fledged Alarm Panel to control your Elmo/IESS alarm systems.
BSD 3-Clause "New" or "Revised" License
10 stars 5 forks source link

Integration state switches frequently to "Unavailable" when there is a blip with the Cloud API polling #148

Closed palazzem closed 6 months ago

palazzem commented 7 months ago

Describe the bug Under certain circumstances, there are blips in the Cloud API polling (e.g. the API doesn't return a value in time and the integration goes in timeout). When that happens, the integration moves from any state to "Unavailable" and then back to the original state. The following is an example where only marked states with arrows are the actual triggered states:

image

This issue triggers randomly automations and forces users to write their integrations in a "defensive way", such as checking that the previous state wasn't "Unavailable".

Error message No errors, but automations are triggered when they should not.

Expected behavior Blips should not change the actual behavior.

Additional context This issue may be connected somehow to the followings:

These changes will not solve this issue, but we may want to combine them together as it's probably a comprehensive resolution.

To Reproduce Wait for blips to see these frequent changes.

Environment

palazzem commented 7 months ago

cc @andr3a88

palazzem commented 6 months ago

Reopening the issue as the "Unavailable" state has been fixed in #150, but automations are still triggered when the reconnection happens. In that case, we have the following situation:

State -> Disarmed -> State

This blip happens after the reconnection when the integration, while keeping the previous state correctly, sends an incorrect update to Home Assistant, triggering automations when another update happens.

palazzem commented 6 months ago

The fact that the device goes in Disarmed state, is because when there is a reconnection the Cloud API provides an empty state regardless of what are the actual armed sectors. After the reconnection, this is an example of what the backend returns:

{
  "last_id":1,
  "sectors":{
    "0":{
      "id":1,
      "index":0,
      "element":1,
      "name":"S1",
      "activable":false,
      "status":false
    },
    "1":{
      "id":1,
      "index":1,
      "element":2,
      "name":"S2",
      "activable":false,
      "status":false
    },
    "2":{
      "id":1,
      "index":2,
      "element":3,
      "name":"S3",
      "activable":false,
      "status":false
    },
    "3":{
      "id":1,
      "index":3,
      "element":4,
      "name":"S4",
      "activable":false,
      "status":false
    }
  }
}

In this example, S4 should had status: true. At this point we can assume that when last_id == 1, the backend returns the actual empty state (connection reset).