Skip to content

Commit

Permalink
Merge pull request #43 from tbarnekov/mtrab_merge
Browse files Browse the repository at this point in the history
Improvements mostly from jnxxx
  • Loading branch information
MTrab committed Oct 24, 2022
2 parents b753a34 + 5c603e4 commit e6d83fc
Show file tree
Hide file tree
Showing 12 changed files with 440 additions and 100 deletions.
41 changes: 34 additions & 7 deletions custom_components/danfoss_ally/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Adds support for Danfoss Ally Gateway."""
import asyncio
import logging
from datetime import timedelta
from datetime import datetime, timedelta

import voluptuous as vol
from homeassistant.components.climate.const import PRESET_AWAY, PRESET_HOME
Expand Down Expand Up @@ -89,11 +89,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
_LOGGER.error("Error authorizing")
return False

await hass.async_add_executor_job(allyconnector.update)
async def _update(now):
"""Periodic update."""
await allyconnector.async_update()
await _update(None)

update_track = async_track_time_interval(
hass,
lambda now: allyconnector.update(),
_update,
timedelta(seconds=SCAN_INTERVAL),
)

Expand Down Expand Up @@ -148,6 +151,8 @@ def __init__(self, hass, key, secret):
self._secret = secret
self.ally = DanfossAlly()
self._authorized = False
self._latest_write_time = datetime.min
self._latest_poll_time = datetime.min

def setup(self) -> None:
"""Setup API connection."""
Expand All @@ -156,10 +161,20 @@ def setup(self) -> None:
self._authorized = auth

@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self) -> None:
async def async_update(self) -> None:
"""Update API data."""
_LOGGER.debug("Updating Danfoss Ally devices")
self.ally.getDeviceList()

# Postpone poll if a recent change were made - Attempt to avoid UI glitches
seconds_since_write = (datetime.utcnow() - self._latest_write_time).total_seconds()
if (seconds_since_write < 1):
_LOGGER.debug("Seconds since last write %f. Postponing update for 1 sec.", seconds_since_write)
await asyncio.sleep(1)

# Poll API
await self.hass.async_add_executor_job(self.ally.getDeviceList) #self.ally.getDeviceList()
self._latest_poll_time = datetime.utcnow()

for device in self.ally.devices: # pylint: disable=consider-using-dict-items
_LOGGER.debug("%s: %s", device, self.ally.devices[device])
dispatcher_send(self.hass, SIGNAL_ALLY_UPDATE_RECEIVED)
Expand All @@ -169,14 +184,26 @@ def devices(self):
"""Return device list from API."""
return self.ally.devices

def set_temperature(self, device_id: str, temperature: float) -> None:
def set_temperature(self, device_id: str, temperature: float, code = "manual_mode_fast") -> None:
"""Set temperature for device_id."""
self.ally.setTemperature(device_id, temperature)
self._latest_write_time = datetime.utcnow()
self.ally.setTemperature(device_id, temperature, code)

# Debug info - log if update was done approximately as the same time as write
seconds_since_poll = (datetime.utcnow() - self._latest_poll_time).total_seconds()
if (seconds_since_poll < 0.5):
_LOGGER.warn("set_temperature: Time since last poll %f sec.", seconds_since_poll)

def set_mode(self, device_id: str, mode: str) -> None:
"""Set operating mode for device_id."""
self._latest_write_time = datetime.utcnow()
self.ally.setMode(device_id, mode)

# Debug info - log if update was done approximately as the same time as write
seconds_since_poll = (datetime.utcnow() - self._latest_poll_time).total_seconds()
if (seconds_since_poll < 0.5):
_LOGGER.warn("set_mode: Time since last poll %f sec.", seconds_since_poll)

@property
def authorized(self) -> bool:
"""Return authorized state."""
Expand Down
34 changes: 26 additions & 8 deletions custom_components/danfoss_ally/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from homeassistant.components.binary_sensor import (
DEVICE_CLASS_CONNECTIVITY,
DEVICE_CLASS_LOCK,
DEVICE_CLASS_TAMPER,
DEVICE_CLASS_WINDOW,
BinarySensorEntity,
)
Expand Down Expand Up @@ -31,7 +32,7 @@ async def async_setup_entry(
entities.extend(
[
AllyBinarySensor(
ally, ally.devices[device]["name"], device, "open window"
ally, ally.devices[device]["name"], device, "open window", ally.devices[device]["model"]
)
]
)
Expand All @@ -42,7 +43,7 @@ async def async_setup_entry(
entities.extend(
[
AllyBinarySensor(
ally, ally.devices[device]["name"], device, "child lock"
ally, ally.devices[device]["name"], device, "child lock", ally.devices[device]["model"]
)
]
)
Expand All @@ -53,7 +54,18 @@ async def async_setup_entry(
entities.extend(
[
AllyBinarySensor(
ally, ally.devices[device]["name"], device, "connectivity"
ally, ally.devices[device]["name"], device, "connectivity", ally.devices[device]["model"]
)
]
)
if 'banner_ctrl' in ally.devices[device]:
_LOGGER.debug(
"Found banner_ctrl detector for %s", ally.devices[device]["name"]
)
entities.extend(
[
AllyBinarySensor(
ally, ally.devices[device]["name"], device, 'banner control', ally.devices[device]["model"]
)
]
)
Expand All @@ -65,13 +77,13 @@ async def async_setup_entry(
class AllyBinarySensor(AllyDeviceEntity, BinarySensorEntity):
"""Representation of an Ally binary_sensor."""

def __init__(self, ally, name, device_id, device_type):
def __init__(self, ally, name, device_id, device_type, model):
"""Initialize Ally binary_sensor."""
self._ally = ally
self._device = ally.devices[device_id]
self._device_id = device_id
self._type = device_type
super().__init__(name, device_id, device_type)
super().__init__(name, device_id, device_type, model)

_LOGGER.debug("Device_id: %s --- Device: %s", self._device_id, self._device)

Expand All @@ -86,9 +98,11 @@ def __init__(self, ally, name, device_id, device_type):
elif self._type == "open window":
self._state = bool(self._device["window_open"])
elif self._type == "child lock":
self._state = bool(self._device["child_lock"])
self._state = not bool(self._device["child_lock"])
elif self._type == "connectivity":
self._state = bool(self._device["online"])
elif self._type == "banner control":
self._state = bool(self._device["banner_ctrl"])

async def async_added_to_hass(self):
"""Register for sensor updates."""
Expand Down Expand Up @@ -123,10 +137,12 @@ def device_class(self):
return DEVICE_CLASS_CONNECTIVITY
elif self._type == "open window":
return DEVICE_CLASS_WINDOW
elif self._type == "child_lock":
elif self._type == "child lock":
return DEVICE_CLASS_LOCK
elif self._type == "connectivity":
return DEVICE_CLASS_CONNECTIVITY
elif self._type == "banner control":
return DEVICE_CLASS_TAMPER
return None

@callback
Expand All @@ -146,6 +162,8 @@ def _async_update_data(self):
elif self._type == "open window":
self._state = bool(self._device["window_open"])
elif self._type == "child lock":
self._state = bool(self._device["child_lock"])
self._state = not bool(self._device["child_lock"])
elif self._type == "connectivity":
self._state = bool(self._device["online"])
elif self._type == "banner control":
self._state = bool(self._device['banner_ctrl'])
Loading

0 comments on commit e6d83fc

Please sign in to comment.