Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,15 @@ _The DPWS service configuration_
2. Depending on where you added your PowerTags, press _ADD DEVICE_ or _ADD_SOLAR_PRODUCTION_.
3. Select the PowerTag entity you want to add (ends with _'total energy'_)
4. _SAVE_

### Removing old devices

When a wireless device is removed from the gateway or replaced by another one
(e.g. a faulty PowerTag swapped for a new unit), its old device stays behind in Home Assistant.

1. Remove it from the gateway first, then reload the integration.
2. Open the old device (_Settings_ > _Devices & Services_ > _PowerTag Link Gateway_).
3. _⋮_ > _Delete_

Deleting is only allowed for devices that the gateway no longer reports: a device that is still
present on the gateway would simply be re-created on the next reload.
23 changes: 23 additions & 0 deletions custom_components/powertag_gateway/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
from homeassistant.const import Platform, CONF_HOST, CONF_PORT, CONF_INTERNAL_URL
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from pymodbus.exceptions import ConnectionException

from .const import (
CONF_CLIENT,
CONF_SETUP_LOCK,
CONF_PRESENT_DEVICES,
DOMAIN,
CONF_TYPE_OF_GATEWAY,
CONF_DEVICE_UNIQUE_ID_VERSION,
Expand Down Expand Up @@ -60,13 +62,34 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
CONF_DEVICE_UNIQUE_ID_VERSION: unique_id_version,
# Platforms scan the gateway one after another, see async_setup_entities.
CONF_SETUP_LOCK: asyncio.Lock(),
# Identifiers of the devices found on the gateway during the last scan,
# see async_remove_config_entry_device.
CONF_PRESENT_DEVICES: set(),
}

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

return True


async def async_remove_config_entry_device(
hass: HomeAssistant, entry: ConfigEntry, device_entry: dr.DeviceEntry
) -> bool:
"""Allow removing a device from the UI once it is no longer on the gateway.

Devices that were removed or replaced in the gateway (e.g. a faulty PowerTag
swapped for a new one) otherwise stay behind in the device registry forever.
A device that the gateway still reports is refused, as it would simply be
re-created on the next reload.
"""
data = hass.data.get(DOMAIN, {}).get(entry.entry_id)
if data is None:
# Entry not loaded: we cannot tell what is on the gateway, be safe.
return False
present = data[CONF_PRESENT_DEVICES]
return not any(identifier in present for identifier in device_entry.identifiers)


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
data = hass.data.get(DOMAIN, {}).get(entry.entry_id)
if data is None:
Expand Down
1 change: 1 addition & 0 deletions custom_components/powertag_gateway/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
DPWS_FRIENDLY_NAME = 'FriendlyName'
DPWS_SERIAL_NUMBER = 'SerialNumber'
CONF_SETUP_LOCK = 'setup_lock'
CONF_PRESENT_DEVICES = 'present_devices'
11 changes: 10 additions & 1 deletion custom_components/powertag_gateway/entity_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@
from homeassistant.helpers import device_registry as dr

from . import UniqueIdVersion
from .const import CONF_CLIENT, DOMAIN, CONF_DEVICE_UNIQUE_ID_VERSION, CONF_SETUP_LOCK
from .const import (
CONF_CLIENT,
DOMAIN,
CONF_DEVICE_UNIQUE_ID_VERSION,
CONF_SETUP_LOCK,
CONF_PRESENT_DEVICES,
)
from .const import GATEWAY_DOMAIN, TAG_DOMAIN
from .device_features import (
FeatureClass,
Expand Down Expand Up @@ -281,6 +287,7 @@ async def _async_setup_entities(
client = data[CONF_CLIENT]
presentation_url = data[CONF_INTERNAL_URL]
device_unique_id_version = data[CONF_DEVICE_UNIQUE_ID_VERSION]
present_devices: set = data[CONF_PRESENT_DEVICES]

entities = []
gateway_device = await gateway_device_info(client, presentation_url)
Expand All @@ -296,6 +303,7 @@ async def _async_setup_entities(
configuration_url=gateway_device.get("configuration_url"),
serial_number=gateway_device.get("serial_number"),
)
present_devices.update(gateway_device["identifiers"])

_LOGGER.debug("Starting to scan for devices...")
for i in range(1, 100):
Expand Down Expand Up @@ -366,6 +374,7 @@ async def _async_setup_entities(
)
if tag_device is None:
continue
present_devices.update(tag_device["identifiers"])

device_name = tag_device["name"]

Expand Down
Loading