Skip to content

Commit

Permalink
fix: handle re-registering if invalid
Browse files Browse the repository at this point in the history
  • Loading branch information
muniter committed Jul 25, 2024
1 parent b62f22a commit 8d04614
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 11 deletions.
24 changes: 23 additions & 1 deletion halinuxcompanion/companion.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from pydantic import BaseModel
from typing import Dict, List, Optional, Tuple, TYPE_CHECKING

SC_INTEGRATION_DELETED = 410

if TYPE_CHECKING:
from halinuxcompanion.api import API

Expand Down Expand Up @@ -153,6 +155,22 @@ def registration_payload(self) -> dict:
"app_data": self.app_data,
}

async def check_registration(self, api: "API", data: dict) -> bool:
"""
Check if the current registration is still valid
"""
logger.info("Checking if device is already registered")
api.process_registration_data(data)
res = await api.webhook_post("get_config", data=json.dumps({"type": "get_config"}))
if res.status == 200:
return True
elif res.status == SC_INTEGRATION_DELETED:
logger.info("Device registration has been deleted, need to register again")
return False
else:
logger.error("Device registration failed with status code %s", res.status)
raise Exception("Device registration failed " + str(res.status))

async def register(self, api: "API") -> Tuple[bool, dict]:
"""Register the companion with Home Assisntat
If the registration fails it's a critical error and the program should exit.
Expand Down Expand Up @@ -184,7 +202,11 @@ async def load_or_register(self, api: "API") -> Tuple[bool, dict]:
registration_data = self.load_registration_data()
if registration_data:
logger.info("Loaded existing registration data from disk %s", registration_data)
return True, registration_data
if await self.check_registration(api, registration_data):
logger.info("Device already registered")
return True, registration_data
else:
logger.info("Device registration data is invalid, re-registering")
return await self.register(api)

def save_registration_data(self, data: dict):
Expand Down
38 changes: 28 additions & 10 deletions halinuxcompanion/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

class Sensor:
"""Standard sensor class"""

instances = []

def __init__(self):
Expand Down Expand Up @@ -87,6 +88,7 @@ def update(self) -> dict:

class SensorManager:
"""Manages sensors registration, and updates to Home Assistant"""

api: API
update_counter: int = 0
sensors: List[Sensor] = []
Expand Down Expand Up @@ -126,7 +128,7 @@ async def _register_sensor(self, sensor: Sensor) -> bool:
logger.info("Sensor registration successful: %s", sname)
return True
else:
logger.error('Sensor registration failed with status code:%s sensor:%s', res.status, sid)
logger.error('Sensor registration failed with status code:%s sensor:%s', res.status, sensor.unique_id)
return False

async def update_sensors(self, sensors: List[Sensor] = []) -> bool:
Expand All @@ -138,23 +140,39 @@ async def update_sensors(self, sensors: List[Sensor] = []) -> bool:
"""
sensors = sensors or self.sensors
self.update_counter += 1
data = {"type": "update_sensor_states", "data": [sensor.update() for sensor in sensors]}
data = {
"type": "update_sensor_states",
"data": [sensor.update() for sensor in sensors],
}
snames = [sensor.config_name for sensor in sensors]
logger.info('Sensors update %s with sensors: %s', self.update_counter, snames)
logger.debug('Sensors update %s with sensors: %s payload: %s', self.update_counter, snames, data)
logger.info("Sensors update %s with sensors: %s", self.update_counter, snames)
logger.debug(
"Sensors update %s with sensors: %s payload: %s",
self.update_counter,
snames,
data,
)
try:
res = await self.api.webhook_post('update_sensors', data=json.dumps(data))
res = await self.api.webhook_post("update_sensors", data=json.dumps(data))
if res.ok or res.status == SC_REGISTER_SENSOR:
logger.info('Sensors update %s successful', self.update_counter)
logger.info("Sensors update %s successful", self.update_counter)
return True
else:
logger.error('Sensors update %s failed with status code:%s', self.update_counter, res.status)
logger.error(
"Sensors update %s failed with status code:%s",
self.update_counter,
res.status,
)
except ClientError as e:
logger.error('Sensors update %s failed with error:%s', self.update_counter, e)
logger.error(
"Sensors update %s failed with error:%s", self.update_counter, e
)

return False

async def _signal_handler(self, signal_alias: str, signal_handler: Callable, sensor: Sensor, *args) -> None:
async def _signal_handler(
self, signal_alias: str, signal_handler: Callable, sensor: Sensor, *args
) -> None:
"""Signal handler for the sensor manager
Each sensor can have multiple signals, at the moment defined in halinuxcompanion.dbus, the callback provided for
the signal is this function wrapped in a functools.partial this allows for the SensorManager to be in charge of
Expand All @@ -165,7 +183,7 @@ async def _signal_handler(self, signal_alias: str, signal_handler: Callable, sen
:param signal_handler: The signal handler (defined by the sensor in sensor.signals)
:param args: The arguments to pass to the signal handler (coming from the dbus signal)
"""
logger.info('Signal %s received for sensor:%s', signal_alias, sensor.unique_id)
logger.info("Signal %s received for sensor:%s", signal_alias, sensor.unique_id)
await signal_handler(sensor, *args)
await self.update_sensors([sensor])

Expand Down

0 comments on commit 8d04614

Please sign in to comment.