Skip to content

Commit 6eb597d

Browse files
committed
init: refactor DeviceData.run so it reconnects automatically
1 parent ef88bf0 commit 6eb597d

1 file changed

Lines changed: 57 additions & 37 deletions

File tree

__init__.py

Lines changed: 57 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,7 @@ def setup(hass: HomeAssistant, base_config: ConfigType) -> bool:
4545

4646
config = base_config[DOMAIN]
4747

48-
host = config[CONF_HOST]
49-
50-
device_client = device.Device(host)
51-
try:
52-
if not device_client.run(once=True):
53-
_LOGGER.error("Device found but no measuremetn was received")
54-
return False
55-
except TimeoutError:
56-
_LOGGER.error("Could no connect ot device")
57-
return False
58-
59-
hass.data[DOMAIN] = DeviceData(hass, device_client)
48+
hass.data[DOMAIN] = DeviceData(hass, config)
6049
hass.data[DOMAIN].start()
6150

6251
discovery.load_platform(hass, Platform.SENSOR, DOMAIN, {}, config)
@@ -72,17 +61,30 @@ class DeviceData(threading.Thread):
7261
for every new data, could work for the pH and ORP data but for the
7362
switches a more direct feedback is wanted."""
7463

75-
def __init__(self, hass, device_client: device.Device) -> None:
64+
def __init__(self, hass, config) -> None:
7665
super().__init__()
7766
self.name = "Ph803wThread"
7867
self.hass = hass
79-
self.device_client = device_client
80-
self.device_client.register_callback(self.dispatcher_new_data)
81-
self.device_client.register_callback(self.reset_fail_counter)
82-
self.host = self.device_client.host
68+
self.host = config[CONF_HOST]
69+
self.device_client = None
8370
self._shutdown = False
8471
self._fails = 0
8572

73+
def passcode(self):
74+
if self.device_client is not None:
75+
return self.device_client.passcode
76+
return "unknown"
77+
78+
def unique_name(self):
79+
if self.device_client is not None:
80+
return self.device_client.get_unique_name()
81+
return "unknown"
82+
83+
def measurement(self):
84+
if self.device_client is not None:
85+
return self.device_client.get_latest_measurement()
86+
return None
87+
8688
def run(self):
8789
"""Thread run loop."""
8890

@@ -92,9 +94,10 @@ def register():
9294

9395
def shutdown(event):
9496
"""Shutdown the thread."""
95-
_LOGGER.debug("Signaled to shutdown")
97+
_LOGGER.info("Signaled to shutdown")
9698
self._shutdown = True
97-
self.device_client.abort()
99+
if self.device_client is not None:
100+
self.device_client.abort()
98101
self.join()
99102

100103
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, shutdown)
@@ -108,25 +111,42 @@ def shutdown(event):
108111
# least every 4 seconds the device side closes the
109112
# connection.
110113
while True:
111-
if self._shutdown:
112-
_LOGGER.debug("Graceful shutdown")
113-
return
114-
114+
_LOGGER.info(f"Attempting to connect to device at {self.host}")
115+
self.device_client = device.Device(self.host)
115116
try:
116-
self.device_client.run(once=False)
117-
except (device.DeviceError, RecursionError, ConnectionError):
118-
_LOGGER.exception("Failed to read data, attempting to recover")
119-
self.device_client.close()
120-
self._fails += 1
121-
error_mapping = self._fails
122-
if error_mapping >= len(ERROR_ITERVAL_MAPPING):
123-
error_mapping = len(ERROR_ITERVAL_MAPPING) - 1
124-
sleep_time = ERROR_ITERVAL_MAPPING[error_mapping]
125-
_LOGGER.debug(
126-
"Sleeping for fail #%s, in %s seconds", self._fails, sleep_time
127-
)
128-
self.device_client.reset_socket()
129-
time.sleep(sleep_time)
117+
if not self.device_client.run(once=True):
118+
_LOGGER.info("Device found but no measurement was received, reconnecting in 1min")
119+
time.sleep(60)
120+
continue
121+
except Exception as e:
122+
_LOGGER.info(f"Error connecting to device at {self.host}: {str(e)}")
123+
_LOGGER.info("Retrying connection in 1min")
124+
time.sleep(60)
125+
continue
126+
127+
_LOGGER.debug("Registering callbacks")
128+
self.device_client.register_callback(self.dispatcher_new_data)
129+
self.device_client.register_callback(self.reset_fail_counter)
130+
131+
while True:
132+
if self._shutdown:
133+
_LOGGER.debug("Graceful shutdown")
134+
return
135+
136+
try:
137+
_LOGGER.info("Starting device client loop")
138+
self.device_client.run(once=False)
139+
except (device.DeviceError, RecursionError, ConnectionError) as e:
140+
_LOGGER.exception(f"Failed to read data: {str(e)}")
141+
self.device_client.close()
142+
self._fails += 1
143+
error_mapping = self._fails
144+
if error_mapping >= len(ERROR_ITERVAL_MAPPING):
145+
error_mapping = len(ERROR_ITERVAL_MAPPING) - 1
146+
sleep_time = ERROR_ITERVAL_MAPPING[error_mapping]
147+
_LOGGER.info(f"Sleeping {str(sleep_time)}s for failure #{str(self._fails)}")
148+
self.device_client.reset_socket()
149+
time.sleep(sleep_time)
130150

131151
@callback
132152
def reset_fail_counter(self):

0 commit comments

Comments
 (0)