Skip to content

Commit

Permalink
Handle the availability of each A/C on its own.
Browse files Browse the repository at this point in the history
  • Loading branch information
deiger committed Jan 9, 2021
1 parent b4273b4 commit 8afbf4b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 19 deletions.
8 changes: 8 additions & 0 deletions aircon/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@ async def run(parsed_args):
'name': device.name,
'sw_version': device.sw_version
},
'availability': [
{
'topic': mqtt_topics['lwt']
},
{
'topic': mqtt_topics['pub'].format(device.mac_address, 'available')
},
],
'current_temperature_topic': mqtt_topics['pub'].format(device.mac_address, 'f_temp_in'),
'fan_mode_command_topic': mqtt_topics['sub'].format(device.mac_address, 't_fan_speed'),
'fan_mode_state_topic': mqtt_topics['pub'].format(device.mac_address, 't_fan_speed'),
Expand Down
19 changes: 10 additions & 9 deletions aircon/aircon.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def __init__(self, config: Dict[str, str], properties: Properties, notifier: Cal
self._properties = properties
self._properties_lock = threading.RLock()
self._queue_listener = notifier
self._available = False

self._next_command_id = 0

Expand All @@ -49,6 +50,15 @@ def __init__(self, config: Dict[str, str], properties: Properties, notifier: Cal
def is_fahrenheit(self) -> bool:
return self.temp_type == TemperatureUnit.FAHRENHEIT

@property
def available(self) -> bool:
return self._available

@available.setter
def available(self, value: bool):
self._available = value
self._notify_listeners('available', 'online' if value else 'offline')

def add_property_change_listener(self, listener: Callable[[str, Any], None]):
self._property_change_listeners.append(listener)

Expand Down Expand Up @@ -183,15 +193,6 @@ class AcDevice(BaseDevice):
def __init__(self, config: Dict[str, str], notifier: Callable[[None], None]):
super().__init__(config, AcProperties(), notifier)

@property
def available(self) -> bool:
return self._available

@available.setter
def available(self, value: bool):
self._available = value
self._notify_listeners("available", value)

# @override to add special support for t_power.
def update_property(self, name: str, value) -> None:
with self._properties_lock:
Expand Down
23 changes: 13 additions & 10 deletions aircon/notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
class _NotifyConfiguration:
device: BaseDevice
headers: dict
alive: bool
last_timestamp: int


Expand Down Expand Up @@ -60,7 +59,7 @@ def register_device(self, device: BaseDevice):
'Host': device.ip_address,
'Accept-Encoding': 'gzip'
}
self._configurations.append(_NotifyConfiguration(device, headers, False, 0))
self._configurations.append(_NotifyConfiguration(device, headers, 0))

async def _notify(self):
async with self._condition:
Expand All @@ -75,17 +74,20 @@ async def start(self, session: aiohttp.ClientSession):
async with self._condition:
while self._running:
queues_empty = True
for entry in self._configurations:
for config in self._configurations:
try:
now = time.time()
queue_size = entry.device.commands_queue.qsize()
queue_size = config.device.commands_queue.qsize()
if queue_size > 1:
queues_empty = False
if now - entry.last_timestamp >= self._KEEP_ALIVE_INTERVAL or queue_size > 0:
await self._perform_request(session, entry)
entry.last_timestamp = now
if now - config.last_timestamp >= self._KEEP_ALIVE_INTERVAL or queue_size > 0:
await self._perform_request(session, config)
config.last_timestamp = now
except:
logging.exception('[KeepAlive] Failed to send local_reg keep alive to the AC.')
config.device.available = False
else:
config.device.available = True
if queues_empty:
logging.debug('[KeepAlive] Waiting for notification or timeout')
try:
Expand All @@ -104,7 +106,7 @@ async def stop(self):
wait=wait_incrementing(start=0.5, increment=1.5, max=10))
async def _perform_request(self, session: aiohttp.ClientSession,
config: _NotifyConfiguration) -> None:
method = 'PUT' if config.alive else 'POST'
method = 'PUT' if config.device.available else 'POST'
self._json['local_reg']['notify'] = int(config.device.commands_queue.qsize() > 0)
url = 'http://{}/local_reg.json'.format(config.device.ip_address)
try:
Expand All @@ -116,6 +118,7 @@ async def _perform_request(self, session: aiohttp.ClientSession,
resp.status, resp_data))
raise ConnectionError('Sending local_reg failed: {}, {}'.format(resp.status, resp_data))
except:
config.alive = False
config.device.available = False
raise
config.alive = True
else:
config.device.available = True

0 comments on commit 8afbf4b

Please sign in to comment.