Skip to content

Commit

Permalink
fix: fix status register decoding
Browse files Browse the repository at this point in the history
add minimal testing
  • Loading branch information
tomleglaunec committed Dec 21, 2024
1 parent 0523b14 commit f2ce2f4
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 19 deletions.
46 changes: 27 additions & 19 deletions custom_components/linkytic/status_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def get_status(self, register: str) -> str | bool:
int_register = int(register, base=16)
except TypeError:
return False
val = (int_register >> self.lsb) & (1 << (self.len - 1))
val = (int_register >> self.lsb) & ((1 << self.len) - 1)

if self.options is None:
return bool(val)
Expand All @@ -43,10 +43,16 @@ def get_status(self, register: str) -> str | bool:
etat_euridis = {
0: "Désactivée",
1: "Activée sans sécurité",
2: "Activée avec sécurité",
2: "Valeur non valide", # codespell:ignore
3: "Activée avec sécurité",
}

statut_cpl = {0: "New/Unlock", 1: "New/Lock", 2: "Registered"}
statut_cpl = {
0: "New/Unlock",
1: "New/Lock",
2: "Registered",
3: "Valeur non valide", # codespell:ignore
}

tempo_color = {
0: "Pas d'annonce",
Expand Down Expand Up @@ -77,19 +83,21 @@ class StatusRegister(Enum):

CONTACT_SEC = StatusRegisterEnumValueType(0)
ORGANE_DE_COUPURE = StatusRegisterEnumValueType(1, 3, organe_coupure)
ETAT_DU_CACHE_BORNE_DISTRIBUTEUR = StatusRegisterEnumValueType(3)
SURTENSION_SUR_UNE_DES_PHASES = StatusRegisterEnumValueType(5)
DEPASSEMENT_PUISSANCE_REFERENCE = StatusRegisterEnumValueType(6)
PRODUCTEUR_CONSOMMATEUR = StatusRegisterEnumValueType(7)
SENS_ENERGIE_ACTIVE = StatusRegisterEnumValueType(8)
TARIF_CONTRAT_FOURNITURE = StatusRegisterEnumValueType(9, 3, tarif_en_cours)
TARIF_CONTRAT_DISTRIBUTEUR = StatusRegisterEnumValueType(13, 2, tarif_en_cours)
MODE_DEGRADE_HORLOGE = StatusRegisterEnumValueType(15)
MODE_TIC = StatusRegisterEnumValueType(16)
ETAT_SORTIE_COMMUNICATION_EURIDIS = StatusRegisterEnumValueType(18, 2, etat_euridis)
STATUS_CPL = StatusRegisterEnumValueType(20, 2, statut_cpl)
SYNCHRO_CPL = StatusRegisterEnumValueType(22)
COULEUR_JOUR_CONTRAT_TEMPO = StatusRegisterEnumValueType(23, 2, tempo_color)
COULEUR_LENDEMAIN_CONTRAT_TEMPO = StatusRegisterEnumValueType(25, 2, tempo_color)
PREAVIS_POINTES_MOBILES = StatusRegisterEnumValueType(27, 2, preavis_pm)
POINTE_MOBILE = StatusRegisterEnumValueType(29, 2, pointe_mobile)
ETAT_DU_CACHE_BORNE_DISTRIBUTEUR = StatusRegisterEnumValueType(4)
# bit 5 is reserved
SURTENSION_SUR_UNE_DES_PHASES = StatusRegisterEnumValueType(6)
DEPASSEMENT_PUISSANCE_REFERENCE = StatusRegisterEnumValueType(7)
PRODUCTEUR_CONSOMMATEUR = StatusRegisterEnumValueType(8)
SENS_ENERGIE_ACTIVE = StatusRegisterEnumValueType(9)
TARIF_CONTRAT_FOURNITURE = StatusRegisterEnumValueType(10, 4, tarif_en_cours)
TARIF_CONTRAT_DISTRIBUTEUR = StatusRegisterEnumValueType(14, 2, tarif_en_cours)
MODE_DEGRADE_HORLOGE = StatusRegisterEnumValueType(16)
MODE_TIC = StatusRegisterEnumValueType(17)
# bit 18 is reserved
ETAT_SORTIE_COMMUNICATION_EURIDIS = StatusRegisterEnumValueType(19, 2, etat_euridis)
STATUS_CPL = StatusRegisterEnumValueType(21, 2, statut_cpl)
SYNCHRO_CPL = StatusRegisterEnumValueType(23)
COULEUR_JOUR_CONTRAT_TEMPO = StatusRegisterEnumValueType(24, 2, tempo_color)
COULEUR_LENDEMAIN_CONTRAT_TEMPO = StatusRegisterEnumValueType(26, 2, tempo_color)
PREAVIS_POINTES_MOBILES = StatusRegisterEnumValueType(28, 2, preavis_pm)
POINTE_MOBILE = StatusRegisterEnumValueType(30, 2, pointe_mobile)
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for the linkytic custom component."""
104 changes: 104 additions & 0 deletions tests/test_status_register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"""Test the status register decoding."""

from custom_components.linkytic.status_register import (
StatusRegister,
etat_euridis,
organe_coupure,
pointe_mobile,
preavis_pm,
statut_cpl,
tarif_en_cours,
tempo_color,
)


def test_parse():
STGE = "013AC501"

EXPECTED = {
StatusRegister.CONTACT_SEC: 1,
StatusRegister.ORGANE_DE_COUPURE: organe_coupure[0],
StatusRegister.ETAT_DU_CACHE_BORNE_DISTRIBUTEUR: 0,
StatusRegister.SURTENSION_SUR_UNE_DES_PHASES: 0,
StatusRegister.DEPASSEMENT_PUISSANCE_REFERENCE: 0,
StatusRegister.PRODUCTEUR_CONSOMMATEUR: 1,
StatusRegister.SENS_ENERGIE_ACTIVE: 0,
StatusRegister.TARIF_CONTRAT_FOURNITURE: tarif_en_cours[1],
StatusRegister.TARIF_CONTRAT_DISTRIBUTEUR: tarif_en_cours[3],
StatusRegister.MODE_DEGRADE_HORLOGE: 0,
StatusRegister.MODE_TIC: 1,
StatusRegister.ETAT_SORTIE_COMMUNICATION_EURIDIS: etat_euridis[3],
StatusRegister.STATUS_CPL: statut_cpl[1],
StatusRegister.SYNCHRO_CPL: 0,
StatusRegister.COULEUR_JOUR_CONTRAT_TEMPO: tempo_color[1],
StatusRegister.COULEUR_LENDEMAIN_CONTRAT_TEMPO: tempo_color[0],
StatusRegister.PREAVIS_POINTES_MOBILES: preavis_pm[0],
StatusRegister.POINTE_MOBILE: pointe_mobile[0],
}

for element in StatusRegister:
assert EXPECTED[element] == element.value.get_status(STGE)

STGE = "003AC000"

EXPECTED = {
StatusRegister.CONTACT_SEC: 0,
StatusRegister.ORGANE_DE_COUPURE: organe_coupure[0],
StatusRegister.ETAT_DU_CACHE_BORNE_DISTRIBUTEUR: 0,
StatusRegister.SURTENSION_SUR_UNE_DES_PHASES: 0,
StatusRegister.DEPASSEMENT_PUISSANCE_REFERENCE: 0,
StatusRegister.PRODUCTEUR_CONSOMMATEUR: 0,
StatusRegister.SENS_ENERGIE_ACTIVE: 0,
StatusRegister.TARIF_CONTRAT_FOURNITURE: tarif_en_cours[0],
StatusRegister.TARIF_CONTRAT_DISTRIBUTEUR: tarif_en_cours[3],
StatusRegister.MODE_DEGRADE_HORLOGE: 0,
StatusRegister.MODE_TIC: 1,
StatusRegister.ETAT_SORTIE_COMMUNICATION_EURIDIS: etat_euridis[3],
StatusRegister.STATUS_CPL: statut_cpl[1],
StatusRegister.SYNCHRO_CPL: 0,
StatusRegister.COULEUR_JOUR_CONTRAT_TEMPO: tempo_color[0],
StatusRegister.COULEUR_LENDEMAIN_CONTRAT_TEMPO: tempo_color[0],
StatusRegister.PREAVIS_POINTES_MOBILES: preavis_pm[0],
StatusRegister.POINTE_MOBILE: pointe_mobile[0],
}

for element in StatusRegister:
assert EXPECTED[element] == element.value.get_status(STGE)

STGE = "FFDFE7FD"

EXPECTED = {
StatusRegister.CONTACT_SEC: 1,
StatusRegister.ORGANE_DE_COUPURE: organe_coupure[6],
StatusRegister.ETAT_DU_CACHE_BORNE_DISTRIBUTEUR: 1,
StatusRegister.SURTENSION_SUR_UNE_DES_PHASES: 1,
StatusRegister.DEPASSEMENT_PUISSANCE_REFERENCE: 1,
StatusRegister.PRODUCTEUR_CONSOMMATEUR: 1,
StatusRegister.SENS_ENERGIE_ACTIVE: 1,
StatusRegister.TARIF_CONTRAT_FOURNITURE: tarif_en_cours[9],
StatusRegister.TARIF_CONTRAT_DISTRIBUTEUR: tarif_en_cours[3],
StatusRegister.MODE_DEGRADE_HORLOGE: 1,
StatusRegister.MODE_TIC: 1,
StatusRegister.ETAT_SORTIE_COMMUNICATION_EURIDIS: etat_euridis[3],
StatusRegister.STATUS_CPL: statut_cpl[2],
StatusRegister.SYNCHRO_CPL: 1,
StatusRegister.COULEUR_JOUR_CONTRAT_TEMPO: tempo_color[3],
StatusRegister.COULEUR_LENDEMAIN_CONTRAT_TEMPO: tempo_color[3],
StatusRegister.PREAVIS_POINTES_MOBILES: preavis_pm[3],
StatusRegister.POINTE_MOBILE: pointe_mobile[3],
}

for element in StatusRegister:
assert EXPECTED[element] == element.value.get_status(STGE)

def parse_stge(stge: str):
for element in StatusRegister:
print(element.name, element.value.get_status(stge))

if __name__ == "__main__":
# Parse STGE, call this file as a module (python -m tests.test_status_register <STGE>)
import sys
if len(sys.argv) <= 1:
print("No stge to parse.")
sys.exit(1)
parse_stge(sys.argv[1])

0 comments on commit f2ce2f4

Please sign in to comment.