From 3cf6b6440659de539eaaf585df4dbd9e239ecbb6 Mon Sep 17 00:00:00 2001 From: Tom Benezech Date: Fri, 15 Nov 2024 19:04:19 +0100 Subject: [PATCH 1/2] fix: duplicate sensor id management of experimental counters with different tags --- custom_components/linkytic/const.py | 2 + custom_components/linkytic/sensor.py | 78 ++++------------------------ 2 files changed, 12 insertions(+), 68 deletions(-) diff --git a/custom_components/linkytic/const.py b/custom_components/linkytic/const.py index 07d845d..7244aac 100644 --- a/custom_components/linkytic/const.py +++ b/custom_components/linkytic/const.py @@ -156,3 +156,5 @@ "75": "Compteur monophasé 90 A généralisation Linky G3 - arrivée puissance basse", "76": "Compteur triphasé 60 A généralisation Linky G3 - arrivée puissance basse", } + +EXPERIMENTAL_DEVICES = ("67", "68") \ No newline at end of file diff --git a/custom_components/linkytic/sensor.py b/custom_components/linkytic/sensor.py index d58dd78..7293579 100644 --- a/custom_components/linkytic/sensor.py +++ b/custom_components/linkytic/sensor.py @@ -36,6 +36,7 @@ SETUP_THREEPHASE, SETUP_TICMODE, TICMODE_STANDARD, + EXPERIMENTAL_DEVICES, ) from .serial_reader import LinkyTICReader from .status_register import StatusRegister @@ -53,13 +54,17 @@ async def async_setup_entry( _LOGGER.debug("%s: setting up sensor plateform", config_entry.title) # Retrieve the serial reader object try: - serial_reader = hass.data[DOMAIN][config_entry.entry_id] + serial_reader: LinkyTICReader = hass.data[DOMAIN][config_entry.entry_id] except KeyError: _LOGGER.error( "%s: can not init sensors: failed to get the serial reader object", config_entry.title, ) return + + # Flag for experimental counters which have slightly different tags. + is_pilot: bool = serial_reader.device_identification[DID_TYPE_CODE] in EXPERIMENTAL_DEVICES + # Init sensors sensors = [] if config_entry.data.get(SETUP_TICMODE) == TICMODE_STANDARD: @@ -237,7 +242,7 @@ async def async_setup_entry( conversion_function=(lambda x: x * 1000), # kVA conversion ), ApparentPowerSensor( - tag="SINSTS", + tag="SINST1" if is_pilot else "SINSTS", name="Puissance app. instantanée soutirée", config_title=config_entry.title, config_uniq_id=config_entry.entry_id, @@ -246,7 +251,7 @@ async def async_setup_entry( register_callback=True, ), ApparentPowerSensor( - tag="SMAXSN", + tag="SMAXN" if is_pilot else "SMAXSN", name="Puissance app. max. soutirée n", config_title=config_entry.title, config_uniq_id=config_entry.entry_id, @@ -254,7 +259,7 @@ async def async_setup_entry( register_callback=True, ), ApparentPowerSensor( - tag="SMAXSN-1", + tag="SMAXN-1" if is_pilot else "SMAXSN-1", name="Puissance app. max. soutirée n-1", config_title=config_entry.title, config_uniq_id=config_entry.entry_id, @@ -554,69 +559,6 @@ async def async_setup_entry( field=StatusRegister.POINTE_MOBILE, ), ] - # Handle protocol deviation for experimental/pilote modules - if (serial_reader.device_identification[DID_TYPE_CODE]=="67"): - sensors.append( - ApparentPowerSensor( - tag="SINST1", - name="Puissance app. instantanée soutirée", - config_title=config_entry.title, - config_uniq_id=config_entry.entry_id, - serial_reader=serial_reader, - register_callback=True, - ) - ) - sensors.append( - ApparentPowerSensor( - tag="SMAXN", - name="Puissance app. max. soutirée n", - config_title=config_entry.title, - config_uniq_id=config_entry.entry_id, - serial_reader=serial_reader, - register_callback=True, - ) - ) - sensors.append( - ApparentPowerSensor( - tag="SMAXN-1", - name="Puissance app. max. soutirée n-1", - config_title=config_entry.title, - config_uniq_id=config_entry.entry_id, - serial_reader=serial_reader, - register_callback=True, - ) - ) - else: - sensors.append( - ApparentPowerSensor( - tag="SINSTS", - name="Puissance app. instantanée soutirée", - config_title=config_entry.title, - config_uniq_id=config_entry.entry_id, - serial_reader=serial_reader, - register_callback=True, - ) - ) - sensors.append( - ApparentPowerSensor( - tag="SMAXSN", - name="Puissance app. max. soutirée n", - config_title=config_entry.title, - config_uniq_id=config_entry.entry_id, - serial_reader=serial_reader, - register_callback=True, - ) - ) - sensors.append( - ApparentPowerSensor( - tag="SMAXSN-1", - name="Puissance app. max. soutirée n-1", - config_title=config_entry.title, - config_uniq_id=config_entry.entry_id, - serial_reader=serial_reader, - register_callback=True, - ) - ) # Add producer specific sensors if bool(config_entry.data.get(SETUP_PRODUCER)): sensors.append( @@ -1342,7 +1284,7 @@ def update(self): value, _ = self._update() if not value: return - self._last_value = ' '.join(value.split()) + self._last_value = " ".join(value.split()) class RegularIntSensor(LinkyTICSensor[int]): From 36ca0f03cee2ac86c1656809680506fc5b338753 Mon Sep 17 00:00:00 2001 From: Tom Benezech Date: Fri, 15 Nov 2024 21:42:29 +0100 Subject: [PATCH 2/2] chore: cleanup code and lint type --- custom_components/linkytic/__init__.py | 4 +- custom_components/linkytic/sensor.py | 72 ------------------- custom_components/linkytic/status_register.py | 2 +- 3 files changed, 3 insertions(+), 75 deletions(-) diff --git a/custom_components/linkytic/__init__.py b/custom_components/linkytic/__init__.py index 9bef384..f6fb455 100644 --- a/custom_components/linkytic/__init__.py +++ b/custom_components/linkytic/__init__.py @@ -119,8 +119,8 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry): else: new[SETUP_SERIAL] = serial_by_id - #config_entry.minor_version = 2 - hass.config_entries.async_update_entry(config_entry, data=new, minor_version=2) + # config_entry.minor_version = 2 + hass.config_entries.async_update_entry(config_entry, data=new, minor_version=2, version=1) # type: ignore _LOGGER.info( "Migration to version %d.%d successful", diff --git a/custom_components/linkytic/sensor.py b/custom_components/linkytic/sensor.py index 7293579..635c8ff 100644 --- a/custom_components/linkytic/sensor.py +++ b/custom_components/linkytic/sensor.py @@ -414,14 +414,6 @@ async def async_setup_entry( serial_reader=serial_reader, icon="mdi:list-status", ), - # LinkyTICStatusRegisterSensor( - # name="Statut contact sec", - # config_title=config_entry.title, - # config_uniq_id=config_entry.entry_id, - # serial_reader=serial_reader, - # icon="mdi:electric-switch", - # field=StatusRegister.CONTACT_SEC, - # ), LinkyTICStatusRegisterSensor( name="Statut organe de coupure", config_title=config_entry.title, @@ -430,46 +422,6 @@ async def async_setup_entry( icon="mdi:connection", field=StatusRegister.ORGANE_DE_COUPURE, ), - # LinkyTICStatusRegisterSensor( - # name="Statut état du cache-bornes distributeur", - # config_title=config_entry.title, - # config_uniq_id=config_entry.entry_id, - # serial_reader=serial_reader, - # icon="mdi:toy-brick-outline", - # field=StatusRegister.ETAT_DU_CACHE_BORNE_DISTRIBUTEUR, - # ), - # LinkyTICStatusRegisterSensor( - # name="Statut surtension sur une des phases", - # config_title=config_entry.title, - # config_uniq_id=config_entry.entry_id, - # serial_reader=serial_reader, - # icon="mdi:flash-alert", - # field=StatusRegister.SURTENSION_SUR_UNE_DES_PHASES, - # ), - # LinkyTICStatusRegisterSensor( - # name="Statut dépassement de la puissance de référence", - # config_title=config_entry.title, - # config_uniq_id=config_entry.entry_id, - # serial_reader=serial_reader, - # icon="mdi:flash-alert", - # field=StatusRegister.DEPASSEMENT_PUISSANCE_REFERENCE, - # ), - # LinkyTICStatusRegisterSensor( - # name="Statut producteur/consommateur", - # config_title=config_entry.title, - # config_uniq_id=config_entry.entry_id, - # serial_reader=serial_reader, - # icon="mdi:transmission-tower", - # field=StatusRegister.PRODUCTEUR_CONSOMMATEUR, - # ), - # LinkyTICStatusRegisterSensor( - # name="Statut sens de l’énergie active", - # config_title=config_entry.title, - # config_uniq_id=config_entry.entry_id, - # serial_reader=serial_reader, - # icon="mdi:transmission-tower", - # field=StatusRegister.SENS_ENERGIE_ACTIVE, - # ), LinkyTICStatusRegisterSensor( name="Statut tarif contrat fourniture", config_title=config_entry.title, @@ -486,22 +438,6 @@ async def async_setup_entry( icon="mdi:cash-check", field=StatusRegister.TARIF_CONTRAT_DISTRIBUTEUR, ), - # LinkyTICStatusRegisterSensor( - # name="Statut mode dégradée de l'horloge", - # config_title=config_entry.title, - # config_uniq_id=config_entry.entry_id, - # serial_reader=serial_reader, - # icon="mdi:clock-alert-outline", - # field=StatusRegister.MODE_DEGRADE_HORLOGE, - # ), - # LinkyTICStatusRegisterSensor( - # name="Statut sortie télé-information", - # config_title=config_entry.title, - # config_uniq_id=config_entry.entry_id, - # serial_reader=serial_reader, - # icon="mdi:tag", - # field=StatusRegister.MODE_TIC, - # ), LinkyTICStatusRegisterSensor( name="Statut sortie communication Euridis", config_title=config_entry.title, @@ -518,14 +454,6 @@ async def async_setup_entry( icon="mdi:tag", field=StatusRegister.STATUS_CPL, ), - # LinkyTICStatusRegisterSensor( - # name="Statut synchronisation CPL", - # config_title=config_entry.title, - # config_uniq_id=config_entry.entry_id, - # serial_reader=serial_reader, - # icon="mdi:sync", - # field=StatusRegister.SYNCHRO_CPL, - # ), LinkyTICStatusRegisterSensor( name="Statut couleur du jour tempo", config_title=config_entry.title, diff --git a/custom_components/linkytic/status_register.py b/custom_components/linkytic/status_register.py index 8d93fd5..015c5cd 100644 --- a/custom_components/linkytic/status_register.py +++ b/custom_components/linkytic/status_register.py @@ -60,7 +60,7 @@ def get_status(self, register: str) -> str | bool: } -class StatusRegister(StatusRegisterEnumValueType, Enum): +class StatusRegister(Enum): """Field provided by status register. The value corresponds to the (position, bits). """