Skip to content

Commit

Permalink
Merge pull request #1 from jbouwh/fix-update-from-unknown-status
Browse files Browse the repository at this point in the history
Only update on known status, never delete
  • Loading branch information
jbouwh authored May 12, 2022
2 parents 82d41b3 + 1780cea commit 1c6ac99
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 17 deletions.
23 changes: 22 additions & 1 deletion custom_components/elro_connects/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"""The Elro Connects integration."""
from __future__ import annotations

import copy
from datetime import timedelta
import logging

from elro.api import K1
from elro.device import ATTR_DEVICE_STATE, STATE_OFFLINE, STATE_UNKNOWN

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import SERVICE_RELOAD, Platform
Expand All @@ -27,8 +29,27 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def _async_update_data() -> dict[int, dict]:
"""Update data via API."""
nonlocal current_device_set
# get state from coordinator cash in case the current state is unknown
coordinator_update: dict[int, dict] = copy.deepcopy(coordinator.data or {})
# set initial state to offline
for device_id, state_base in coordinator_update.items():
state_base[ATTR_DEVICE_STATE] = STATE_OFFLINE
try:
await elro_connects_api.async_update()
device_update = copy.deepcopy(elro_connects_api.data)
for device_id, device_data in device_update.items():
if device_id not in coordinator_update:
# new device, or known state
coordinator_update[device_id] = device_data
elif device_data[ATTR_DEVICE_STATE] == STATE_UNKNOWN:
# update device state only, other data is not valid
coordinator_update[device_id][ATTR_DEVICE_STATE] = device_data[
ATTR_DEVICE_STATE
]
else:
# update full state
coordinator_update[device_id] = device_data

except K1.K1ConnectionError as err:
raise UpdateFailed(err) from err
new_set = set(elro_connects_api.data.keys())
Expand All @@ -43,7 +64,7 @@ async def _async_update_data() -> dict[int, dict]:
{},
blocking=False,
)
return elro_connects_api.data
return coordinator_update

async def async_reload(call: ServiceCall) -> None:
"""Reload the integration."""
Expand Down
16 changes: 3 additions & 13 deletions custom_components/elro_connects/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_NAME, CONF_HOST, CONF_PORT
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import DeviceInfo, EntityDescription
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
Expand Down Expand Up @@ -66,7 +66,6 @@ async def async_update(self) -> None:
"""Synchronize with the K1 connector."""
new_data: dict[int, dict] = {}
try:
self._retry_count += 1
# Only connect the first time or if there were recent issues
if not self._connected:
await self.async_connect()
Expand All @@ -78,6 +77,7 @@ async def async_update(self) -> None:
self._retry_count = 0
self._data = new_data
except K1.K1ConnectionError as err:
self._retry_count += 1
self._connected = False
if not self._data or self._retry_count >= MAX_RETRIES:
raise K1.K1ConnectionError(err) from err
Expand Down Expand Up @@ -139,17 +139,7 @@ def name(self) -> str:
@callback
def _handle_coordinator_update(self):
"""Fetch state from the device."""
if self._device_id in self.coordinator.data:
self.data = self.coordinator.data[self._device_id]
else:
# device removed, remove entity
_LOGGER.debug(
"Entity %s was removed from the connector, cleaning up", self.entity_id
)
entity_registry = er.async_get(self.hass)
if entity_registry.async_get(self.entity_id):
entity_registry.async_remove(self.entity_id)

self.data = self.coordinator.data[self._device_id]
self.async_write_ha_state()

@property
Expand Down
2 changes: 1 addition & 1 deletion custom_components/elro_connects/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"requirements": ["lib-elro-connects==0.4.1"],
"codeowners": ["@jbouwh"],
"iot_class": "local_polling",
"version": "0.1.1"
"version": "0.1.2"
}
4 changes: 2 additions & 2 deletions tests/elro_connects/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ async def test_configure_platforms_dynamically(
assert hass.states.get("siren.eerste_etage") is not None
assert hass.states.get("siren.zolder") is not None

# Remove device 1 from api data, entity should be removed
# Remove device 1 from api data, entity should appear offline with an unknown state
updated_status_data.pop(1)

mock_k1_connector["result"].return_value = updated_status_data
time = time + timedelta(seconds=30)
async_fire_time_changed(hass, time)
await hass.async_block_till_done()

assert hass.states.get("siren.beganegrond") is None
assert hass.states.get("siren.beganegrond").state == "unknown"
assert hass.states.get("siren.eerste_etage") is not None
assert hass.states.get("siren.zolder") is not None

0 comments on commit 1c6ac99

Please sign in to comment.