OpenEPaperLink / Home_Assistant_Integration

Home assistant Integration for the OpenEPaperLink project
Apache License 2.0
131 stars 32 forks source link

"does not generate unique ID" errors #111

Open jterrace opened 5 months ago

jterrace commented 5 months ago

On startup, I get lots of these errors in the log:

2024-02-04 11:45:05.302 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_ip already exists - ignoring sensor.ap_ip
2024-02-04 11:45:05.303 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_systime already exists - ignoring sensor.ap_systime
2024-02-04 11:45:05.303 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_heap already exists - ignoring sensor.ap_free_heap
2024-02-04 11:45:05.303 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_recordcount already exists - ignoring sensor.ap_recordcount
2024-02-04 11:45:05.304 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_dbsize already exists - ignoring sensor.ap_dbsize
2024-02-04 11:45:05.304 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_littlefsfree already exists - ignoring sensor.ap_free_space
2024-02-04 11:45:05.304 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_wifirssi already exists - ignoring sensor.ap_wifi_rssi
2024-02-04 11:45:05.305 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_state already exists - ignoring sensor.ap_state
2024-02-04 11:45:05.305 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_runstate already exists - ignoring sensor.ap_run_state
2024-02-04 11:45:05.306 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_wifistate already exists - ignoring sensor.ap_wifi_state
2024-02-04 11:45:05.306 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_wifissid already exists - ignoring sensor.ap_wifi_ssid
2024-02-04 11:45:05.306 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 0000021A0D173B1B_lastseen already exists - ignoring sensor.weathertoday2_9_last_seen
2024-02-04 11:45:05.307 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 0000021A0D173B1B_nextupdate already exists - ignoring sensor.weathertoday2_9_next_update
2024-02-04 11:45:05.307 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 0000021A0D173B1B_nextcheckin already exists - ignoring sensor.weathertoday2_9_next_checkin
2024-02-04 11:45:05.307 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 0000021A0D173B1B_pending already exists - ignoring sensor.weathertoday2_9_pending_transfer
2024-02-04 11:45:05.309 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 0000021A0D173B1B_wakeupReason already exists - ignoring sensor.weathertoday2_9_wakeup_reason
2024-02-04 11:45:05.309 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 0000021A0D173B1B_capabilities already exists - ignoring sensor.weathertoday2_9_capabilities
2024-02-04 11:45:05.310 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 0000021A0D173B1B_temp already exists - ignoring sensor.weathertoday2_9_temperature
2024-02-04 11:45:05.310 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 0000021A0D173B1B_rssi already exists - ignoring sensor.weathertoday2_9_rssi

In #109 , @DrBlokmeister had some ideas for how to fix this.

DrBlokmeister commented 5 months ago

Thanks for the mention. I changed the sensor.py to:

from __future__ import annotations
from .const import DOMAIN
import logging
import datetime
_LOGGER: Final = logging.getLogger(__name__)

from homeassistant.components.sensor import (
    SensorDeviceClass,
    SensorEntity,
    SensorStateClass,
)
from homeassistant.const import UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType

async def async_setup_entry(hass, config_entry, async_add_entities):
    hub = hass.data[DOMAIN][config_entry.entry_id]
    new_devices = []
    new_devices.append(IPSensor(hub))
    new_devices.append(SystimeSensor(hub))
    new_devices.append(HeapSensor(hub))
    new_devices.append(RecordcountSensor(hub))
    new_devices.append(DBsizeSensor(hub))
    new_devices.append(LitefsfreeSensor(hub))
    new_devices.append(APWifiRssiSensor(hub))
    new_devices.append(APStateSensor(hub))
    new_devices.append(APRunStateSensor(hub))
    new_devices.append(APWifiStatusSensor(hub))
    new_devices.append(APWifiSssidSensor(hub))
    for esls in hub.esls:
        new_devices.append(LastSeenSensor(esls,hub))
        new_devices.append(NextUpdateSensor(esls,hub))
        new_devices.append(NextCheckinSensor(esls,hub))
        new_devices.append(PendingSensor(esls,hub))
        new_devices.append(WakeupReasonSensor(esls,hub))
        new_devices.append(CapabilitiesSensor(esls,hub))
        if (hub.data[esls]["lqi"] != 100 or hub.data[esls]["rssi"] != 100) and hub.data[esls]["hwtype"] != 224 and hub.data[esls]["hwtype"] != 240:
            new_devices.append(TempSensor(esls,hub))
            new_devices.append(RssiSensor(esls,hub))
            new_devices.append(BatteryVoltageSensor(esls,hub))
            new_devices.append(BatteryPercentageSensor(esls,hub))
            new_devices.append(LqiSensor(esls,hub))
    async_add_entities(new_devices)

class IPSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_ip_{hub.data['ap']['ip']}"
        self._attr_name = "AP IP"
        self._hub = hub
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")},
            "configuration_url": "http://" + self._hub.data["ap"]["ip"],
            "name": "OpenEpaperLink AP",
            "model": "esp32",
            "manufacturer": "OpenEpaperLink",
        }

    def update(self) -> None:
        self._attr_native_value = self._hub.data["ap"]["ip"]

class APWifiRssiSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_wifirssi_{hub.data['ap']['ip']}"
        self._attr_name = "AP Wifi RSSI"
        self._hub = hub
        self._attr_native_unit_of_measurement = "dB"
        self._attr_device_class = SensorDeviceClass.SIGNAL_STRENGTH
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        self._attr_native_value = self._hub.data["ap"]["rssi"]

class APStateSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_state_{hub.data['ap']['ip']}"
        self._attr_name = "AP State"
        self._hub = hub
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        lut = {0: "offline",1: "online",2: "flashing",3: "wait for reset",4: "requires power cycle",5: "failed",6: "coming online"}
        self._attr_native_value = lut[self._hub.data["ap"]["apstate"]]

class APRunStateSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_runstate_{hub.data['ap']['ip']}"
        self._attr_name = "AP Run State"
        self._hub = hub
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        lut = {0: "stopped",1: "pause",2: "running",3: "init"}
        self._attr_native_value = lut[self._hub.data["ap"]["runstate"]]

class APTempSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_temp_{hub.data['ap']['ip']}"
        self._attr_name = "AP Temp"
        self._hub = hub
        self._attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS
        self._attr_device_class = SensorDeviceClass.TEMPERATURE
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        temp = self._hub.data["ap"]["temp"]
        if temp:
            self._attr_native_value = round(temp,1)

class APWifiStatusSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_wifistate_{hub.data['ap']['ip']}"
        self._attr_name = "AP Wifi State"
        self._hub = hub
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        lut = {3: "connected"}
        self._attr_native_value = lut[self._hub.data["ap"]["wifistatus"]]

class APWifiSssidSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_wifissid_{hub.data['ap']['ip']}"
        self._attr_name = "AP Wifi SSID"
        self._hub = hub
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        self._attr_native_value = self._hub.data["ap"]["wifissid"]

class SystimeSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_systime_{hub.data['ap']['ip']}"
        self._attr_name = "AP Systime"
        self._hub = hub
        self._attr_device_class = SensorDeviceClass.TIMESTAMP
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        self._attr_native_value = datetime.datetime.fromtimestamp(self._hub.data["ap"]["systime"], datetime.timezone.utc)

class HeapSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_heap_{hub.data['ap']['ip']}"
        self._attr_name = "AP free Heap"
        self._hub = hub
        self._attr_native_unit_of_measurement = "kB"
        self._attr_device_class = SensorDeviceClass.DATA_SIZE
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        self._attr_native_value = round(int(self._hub.data["ap"]["heap"]) / 1024,1)

class RecordcountSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_recordcount_{hub.data['ap']['ip']}"
        self._attr_name = "AP Recordcount"
        self._hub = hub
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        self._attr_native_value = self._hub.data["ap"]["recordcount"]

class DBsizeSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_dbsize_{hub.data['ap']['ip']}"
        self._attr_name = "AP DBSize"
        self._hub = hub
        self._attr_native_unit_of_measurement = "kB"
        self._attr_device_class = SensorDeviceClass.DATA_SIZE
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        self._attr_native_value = round(int(self._hub.data["ap"]["dbsize"]) / 1024,1)

class LitefsfreeSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_littlefsfree_{hub.data['ap']['ip']}"
        self._attr_name = "AP Free Space"
        self._hub = hub
        self._attr_native_unit_of_measurement = "kB"
        self._attr_device_class = SensorDeviceClass.DATA_SIZE
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, "ap")}
        }
    def update(self) -> None:
        self._attr_native_value = round(int(self._hub.data["ap"]["littlefsfree"]) / 1024,1)

class TempSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_temp"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Temperature"
        self._hub = hub
        self._attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS
        self._attr_device_class = SensorDeviceClass.TEMPERATURE
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        self._attr_native_value = self._hub.data[eslid]["temperature"]

class RssiSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_rssi"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Rssi"
        self._hub = hub
        self._attr_native_unit_of_measurement = "dB"
        self._attr_device_class = SensorDeviceClass.SIGNAL_STRENGTH
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        self._attr_native_value = self._hub.data[eslid]["rssi"]

class BatteryVoltageSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_batteryvoltage"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Battery Voltage"
        self._hub = hub
        self._attr_native_unit_of_measurement = "V"
        self._attr_device_class = SensorDeviceClass.VOLTAGE
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        self._attr_native_value = self._hub.data[eslid]["battery"] / 1000

class LqiSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_lqi"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Link Quality Index"
        self._hub = hub
        self._attr_native_unit_of_measurement = ""
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        self._attr_native_value = self._hub.data[eslid]["lqi"]

class ContentModeSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_contentmode"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Content Mode"
        self._hub = hub
        self._attr_native_unit_of_measurement = ""
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        self._attr_native_value = self._hub.data[eslid]["contentmode"]

class LastSeenSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_lastseen"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Last Seen"
        self._hub = hub
        self._attr_device_class = SensorDeviceClass.TIMESTAMP
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
            "name": self._hub.data[self._eslid]["tagname"],
            "sw_version": hex(self._hub.data[self._eslid]["ver"]),
            "serial_number": self._eslid,
            "model": self._hub.data[self._eslid]["hwstring"],
            "manufacturer": "OpenEpaperLink",
            "via_device": (DOMAIN, "ap")
        }
    def update(self) -> None:
        eslid = self._eslid
        self._attr_native_value = datetime.datetime.fromtimestamp(self._hub.data[eslid]["lastseen"],datetime.timezone.utc)

class NextUpdateSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_nextupdate"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Next Update"
        self._hub = hub
        self._attr_device_class = SensorDeviceClass.TIMESTAMP
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        self._attr_native_value = datetime.datetime.fromtimestamp(self._hub.data[eslid]["nextupdate"],datetime.timezone.utc)

class NextCheckinSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_nextcheckin"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Next Checkin"
        self._hub = hub
        self._attr_device_class = SensorDeviceClass.TIMESTAMP
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        self._attr_native_value = datetime.datetime.fromtimestamp(self._hub.data[eslid]["nextcheckin"],datetime.timezone.utc)

class PendingSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_pending"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Pending Transfer"
        self._hub = hub
        self._attr_native_unit_of_measurement = ""
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        self._attr_native_value = self._hub.data[eslid]["pending"]

class WakeupReasonSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_wakeupReason"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Wakeup Reason"
        self._hub = hub
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        lut = {0: "TIMED",1: "BOOT",2: "GPIO",3: "NFC",4: "BUTTON1",5: "BUTTON2",252: "FIRSTBOOT",253: "NETWORK_SCAN",254: "WDT_RESET"}
        wr = lut[self._hub.data[eslid]["wakeupReason"]]
        self._attr_native_value = wr

class CapabilitiesSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_capabilities"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Capabilities"
        self._hub = hub
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        self._attr_native_value = self._hub.data[eslid]["capabilities"]

class BatteryPercentageSensor(SensorEntity):
    def __init__(self, esls,hub):
        self._attr_unique_id = f"{esls}_battery"
        self._eslid = esls
        self._attr_name = hub.data[esls]["tagname"] + " Battery"
        self._hub = hub
        self._attr_native_unit_of_measurement = "%"
        self._attr_device_class = SensorDeviceClass.BATTERY
        self._attr_state_class = SensorStateClass.MEASUREMENT
    @property
    def device_info(self) -> DeviceInfo:
        return {
            "identifiers": {(DOMAIN, self._eslid)},
        }
    def update(self) -> None:
        eslid = self._eslid
        bperc = ((self._hub.data[eslid]["battery"] / 1000) - 2.20) * 250
        if bperc > 100:
            bperc = 100
        if bperc < 0:
            bperc = 0
        bperc = int(bperc)
        self._attr_native_value = bperc

In case that was edited/changed in the meantime, these are the unique_ids needed for each function:

class IPSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_ip_{hub.data['ap']['ip']}"

class APWifiRssiSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_wifirssi_{hub.data['ap']['ip']}"

class APStateSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_state_{hub.data['ap']['ip']}"

class APRunStateSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_runstate_{hub.data['ap']['ip']}"

class APTempSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_temp_{hub.data['ap']['ip']}"

class APWifiStatusSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_wifistate_{hub.data['ap']['ip']}"

class APWifiSssidSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_wifissid_{hub.data['ap']['ip']}"

class SystimeSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_systime_{hub.data['ap']['ip']}"

class HeapSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_heap_{hub.data['ap']['ip']}"

class RecordcountSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_recordcount_{hub.data['ap']['ip']}"

class DBsizeSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_dbsize_{hub.data['ap']['ip']}"

class LitefsfreeSensor(SensorEntity):
    def __init__(self, hub):
        self._attr_unique_id = f"ap_littlefsfree_{hub.data['ap']['ip']}"

# For device-specific sensors, it seems you're already using a dynamic identifier (esls).
# Ensure that 'esls' itself provides uniqueness across devices. No change needed if 'esls' is unique.

I have had this running for over 1.5 weeks, and no additional issues. The unique_id error is gone.

jonasniesner commented 4 months ago

@DrBlokmeister Can you open a PR for this?

DrBlokmeister commented 4 months ago

@DrBlokmeister Can you open a PR for this?

That might take some time. I'm not familiar enough with Github to quickly create a PR. Moreover, I do see that after updating and adding these unique_id lines again, I again get errors that this component is not generating unique ids. So something else might be going on.

jterrace commented 4 months ago

Yeah, I'm not convinced that's the right fix. It almost seems like it's reloading or something. But actually, I stopped seeing this error in the logs now on startup.

jonasniesner commented 4 months ago

I tried a lot but can not reproduce the error. I know it happened a longer time ago. Does anyone else still get this error?

dimitrystd commented 4 months ago

Yes, the error is still here. In logs

2024-03-05 19:27:09.789 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_ip already exists - ignoring sensor.ap_ip
2024-03-05 19:27:09.790 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_state already exists - ignoring sensor.ap_state
2024-03-05 19:27:09.790 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_runstate already exists - ignoring sensor.ap_run_state
2024-03-05 19:27:09.790 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_wifistate already exists - ignoring sensor.ap_wifi_state
2024-03-05 19:27:09.790 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_wifissid already exists - ignoring sensor.ap_wifi_ssid
2024-03-05 19:27:09.791 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 000002BD5EC73B1D_temp already exists - ignoring sensor.000002bd5ec73b1d_temperature
2024-03-05 19:27:09.791 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 000002BD5EC73B1D_rssi already exists - ignoring sensor.000002bd5ec73b1d_rssi
...

My setup:

jterrace commented 4 months ago

Same for me, e.g.

2024-03-05 17:29:37.494 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_ip already exists - ignoring sensor.ap_ip
2024-03-05 17:29:37.499 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 0000021A0D173B1B_lastseen already exists - ignoring sensor.weathertoday2_9_last_seen
kelchm commented 2 months ago

I think @DrBlokmeister has the right general approach, but ideally we would take this a step further and use the MAC address of the AP rather than the IP address. As far as I know, the OEPL web server doesn't implement any mechanism to retrieve the MAC address, but I think that is something that could be solved for easily enough.

For those that are still seeing this issue -- how long have you been running this integration? I'm wondering if the way these sensors were handled in earlier versions is causing the conflict.

EDIT: I think I managed to reproduce this in my development environment by deleting an AP, then attempting to re-add the same AP with the same IP address:

2024-04-08 01:15:33.534 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_ip already exists - ignoring sensor.ap_ip
2024-04-08 01:15:33.536 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_systime already exists - ignoring sensor.ap_systime
2024-04-08 01:15:33.537 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_heap already exists - ignoring sensor.ap_free_heap
2024-04-08 01:15:33.537 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_recordcount already exists - ignoring sensor.ap_recordcount
2024-04-08 01:15:33.537 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_dbsize already exists - ignoring sensor.ap_dbsize
2024-04-08 01:15:33.537 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_littlefsfree already exists - ignoring sensor.ap_free_space
2024-04-08 01:15:33.538 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_wifirssi already exists - ignoring sensor.ap_wifi_rssi
2024-04-08 01:15:33.538 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_state already exists - ignoring sensor.ap_state
2024-04-08 01:15:33.538 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_runstate already exists - ignoring sensor.ap_run_state
2024-04-08 01:15:33.538 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_wifistate already exists - ignoring sensor.ap_wifi_state
2024-04-08 01:15:33.538 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID ap_wifissid already exists - ignoring sensor.ap_wifi_ssid
2024-04-08 01:15:33.539 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_lastseen already exists - ignoring sensor.00000603a51caeb8_last_seen
2024-04-08 01:15:33.539 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_nextupdate already exists - ignoring sensor.00000603a51caeb8_next_update
2024-04-08 01:15:33.540 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_nextcheckin already exists - ignoring sensor.00000603a51caeb8_next_checkin
2024-04-08 01:15:33.540 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_pending already exists - ignoring sensor.00000603a51caeb8_pending_transfer
2024-04-08 01:15:33.540 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_wakeupReason already exists - ignoring sensor.00000603a51caeb8_wakeup_reason
2024-04-08 01:15:33.540 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_capabilities already exists - ignoring sensor.00000603a51caeb8_capabilities
2024-04-08 01:15:33.541 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_temp already exists - ignoring sensor.00000603a51caeb8_temperature
2024-04-08 01:15:33.541 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_rssi already exists - ignoring sensor.00000603a51caeb8_rssi
2024-04-08 01:15:33.542 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_batteryvoltage already exists - ignoring sensor.00000603a51caeb8_battery_voltage
2024-04-08 01:15:33.542 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_battery already exists - ignoring sensor.00000603a51caeb8_battery
2024-04-08 01:15:33.542 ERROR (MainThread) [homeassistant.components.sensor] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_lqi already exists - ignoring sensor.00000603a51caeb8_link_quality_index
2024-04-08 01:15:33.543 ERROR (MainThread) [homeassistant.components.camera] Platform open_epaper_link does not generate unique IDs. ID 00000603A51CAEB8_cam already exists - ignoring camera.00000603a51caeb8_content
DrBlokmeister commented 2 months ago

I think @DrBlokmeister has the right general approach, but ideally we would take this a step further and use the MAC address of the AP rather than the IP address. As far as I know, the OEPL web server doesn't implement any mechanism to retrieve the MAC address, but I think that is something that could be solved for easily enough.

I think the MAC address is already used instead of the IP.

user45876 commented 3 weeks ago

Is it possible that the inability to delete Tags and their entities is also related to this?

DrBlokmeister commented 2 weeks ago

Is it possible that the inability to delete Tags and their entities is also related to this?

As far as I understand, the ability to delete devices/entities in Home Assistant requires a remove service to be defined in the integration. So I don't think that this is related. However I'm not an expert on this subject.