diff --git a/homeassistant/components/adguard/manifest.json b/homeassistant/components/adguard/manifest.json index bdfec1f254b..c77e0b3254d 100644 --- a/homeassistant/components/adguard/manifest.json +++ b/homeassistant/components/adguard/manifest.json @@ -3,7 +3,7 @@ "name": "AdGuard Home", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/adguard", - "requirements": ["adguardhome==0.4.0"], + "requirements": ["adguardhome==0.4.1"], "dependencies": [], "codeowners": ["@frenck"] } diff --git a/homeassistant/components/august/__init__.py b/homeassistant/components/august/__init__.py index 0bb0d639896..a52df5e361c 100644 --- a/homeassistant/components/august/__init__.py +++ b/homeassistant/components/august/__init__.py @@ -36,8 +36,15 @@ AUGUST_CONFIG_FILE = ".august.conf" DATA_AUGUST = "august" DOMAIN = "august" DEFAULT_ENTITY_NAMESPACE = "august" -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=5) -DEFAULT_SCAN_INTERVAL = timedelta(seconds=5) + +# Limit battery and hardware updates to 1800 seconds +# in order to reduce the number of api requests and +# avoid hitting rate limits +MIN_TIME_BETWEEN_LOCK_DETAIL_UPDATES = timedelta(seconds=1800) + +DEFAULT_SCAN_INTERVAL = timedelta(seconds=10) +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=10) + LOGIN_METHODS = ["phone", "email"] CONFIG_SCHEMA = vol.Schema( @@ -180,7 +187,9 @@ class AugustData: self._access_token = access_token self._doorbells = self._api.get_doorbells(self._access_token) or [] self._locks = self._api.get_operable_locks(self._access_token) or [] - self._house_ids = [d.house_id for d in self._doorbells + self._locks] + self._house_ids = set() + for device in self._doorbells + self._locks: + self._house_ids.add(device.house_id) self._doorbell_detail_by_id = {} self._lock_status_by_id = {} @@ -284,58 +293,51 @@ class AugustData: This is the status from the door sensor. """ - self._update_doors() + self._update_locks_status() return self._door_state_by_id.get(lock_id) + def _update_locks(self): + self._update_locks_status() + self._update_locks_detail() + @Throttle(MIN_TIME_BETWEEN_UPDATES) - def _update_doors(self): + def _update_locks_status(self): + status_by_id = {} state_by_id = {} - _LOGGER.debug("Start retrieving door status") + _LOGGER.debug("Start retrieving lock and door status") for lock in self._locks: - _LOGGER.debug("Updating door status for %s", lock.device_name) - + _LOGGER.debug("Updating lock and door status for %s", lock.device_name) try: - state_by_id[lock.device_id] = self._api.get_lock_door_status( - self._access_token, lock.device_id + ( + status_by_id[lock.device_id], + state_by_id[lock.device_id], + ) = self._api.get_lock_status( + self._access_token, lock.device_id, door_status=True ) except RequestException as ex: _LOGGER.error( - "Request error trying to retrieve door status for %s. %s", + "Request error trying to retrieve lock and door status for %s. %s", lock.device_name, ex, ) + status_by_id[lock.device_id] = None state_by_id[lock.device_id] = None except Exception: + status_by_id[lock.device_id] = None state_by_id[lock.device_id] = None raise - _LOGGER.debug("Completed retrieving door status") + _LOGGER.debug("Completed retrieving lock and door status") + self._lock_status_by_id = status_by_id self._door_state_by_id = state_by_id - @Throttle(MIN_TIME_BETWEEN_UPDATES) - def _update_locks(self): - status_by_id = {} + @Throttle(MIN_TIME_BETWEEN_LOCK_DETAIL_UPDATES) + def _update_locks_detail(self): detail_by_id = {} - _LOGGER.debug("Start retrieving locks status") + _LOGGER.debug("Start retrieving locks detail") for lock in self._locks: - _LOGGER.debug("Updating lock status for %s", lock.device_name) - try: - status_by_id[lock.device_id] = self._api.get_lock_status( - self._access_token, lock.device_id - ) - except RequestException as ex: - _LOGGER.error( - "Request error trying to retrieve door status for %s. %s", - lock.device_name, - ex, - ) - status_by_id[lock.device_id] = None - except Exception: - status_by_id[lock.device_id] = None - raise - try: detail_by_id[lock.device_id] = self._api.get_lock_detail( self._access_token, lock.device_id @@ -351,8 +353,7 @@ class AugustData: detail_by_id[lock.device_id] = None raise - _LOGGER.debug("Completed retrieving locks status") - self._lock_status_by_id = status_by_id + _LOGGER.debug("Completed retrieving locks detail") self._lock_detail_by_id = detail_by_id def lock(self, device_id): diff --git a/homeassistant/components/august/binary_sensor.py b/homeassistant/components/august/binary_sensor.py index 14d03189c92..f840d3db532 100644 --- a/homeassistant/components/august/binary_sensor.py +++ b/homeassistant/components/august/binary_sensor.py @@ -11,7 +11,7 @@ from . import DATA_AUGUST _LOGGER = logging.getLogger(__name__) -SCAN_INTERVAL = timedelta(seconds=5) +SCAN_INTERVAL = timedelta(seconds=10) def _retrieve_door_state(data, lock): diff --git a/homeassistant/components/august/camera.py b/homeassistant/components/august/camera.py index 2492eb75418..885ee444c6b 100644 --- a/homeassistant/components/august/camera.py +++ b/homeassistant/components/august/camera.py @@ -7,7 +7,7 @@ from homeassistant.components.camera import Camera from . import DATA_AUGUST, DEFAULT_TIMEOUT -SCAN_INTERVAL = timedelta(seconds=5) +SCAN_INTERVAL = timedelta(seconds=10) def setup_platform(hass, config, add_entities, discovery_info=None): diff --git a/homeassistant/components/august/lock.py b/homeassistant/components/august/lock.py index a541be67097..d336e21653b 100644 --- a/homeassistant/components/august/lock.py +++ b/homeassistant/components/august/lock.py @@ -12,7 +12,7 @@ from . import DATA_AUGUST _LOGGER = logging.getLogger(__name__) -SCAN_INTERVAL = timedelta(seconds=5) +SCAN_INTERVAL = timedelta(seconds=10) def setup_platform(hass, config, add_entities, discovery_info=None): @@ -88,7 +88,12 @@ class AugustLock(LockDevice): if self._lock_detail is None: return None - return {ATTR_BATTERY_LEVEL: self._lock_detail.battery_level} + attributes = {ATTR_BATTERY_LEVEL: self._lock_detail.battery_level} + + if self._lock_detail.keypad is not None: + attributes["keypad_battery_level"] = self._lock_detail.keypad.battery_level + + return attributes @property def unique_id(self) -> str: diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index e3e417d20e0..bacd7346ca7 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -2,7 +2,7 @@ "domain": "august", "name": "August", "documentation": "https://www.home-assistant.io/integrations/august", - "requirements": ["py-august==0.7.0"], + "requirements": ["py-august==0.8.1"], "dependencies": ["configurator"], "codeowners": [] } diff --git a/homeassistant/components/garmin_connect/const.py b/homeassistant/components/garmin_connect/const.py index e38bd72c1ee..b5faeab77b4 100644 --- a/homeassistant/components/garmin_connect/const.py +++ b/homeassistant/components/garmin_connect/const.py @@ -256,21 +256,21 @@ GARMIN_ENTITY_LIST = { "brpm", "mdi:progress-clock", None, - True, + False, ], "lowestRespirationValue": [ "Lowest Respiration", "brpm", "mdi:progress-clock", None, - True, + False, ], "latestRespirationValue": [ "Latest Respiration", "brpm", "mdi:progress-clock", None, - True, + False, ], "latestRespirationTimeGMT": [ "Latest Respiration Update", diff --git a/homeassistant/components/garmin_connect/sensor.py b/homeassistant/components/garmin_connect/sensor.py index 154f7010db4..0ebd39e78d4 100644 --- a/homeassistant/components/garmin_connect/sensor.py +++ b/homeassistant/components/garmin_connect/sensor.py @@ -165,12 +165,16 @@ class GarminConnectSensor(Entity): return data = self._data.data - if "Duration" in self._type and data[self._type]: - self._state = data[self._type] // 60 - elif "Seconds" in self._type and data[self._type]: - self._state = data[self._type] // 60 - else: - self._state = data[self._type] + try: + if "Duration" in self._type and data[self._type]: + self._state = data[self._type] // 60 + elif "Seconds" in self._type and data[self._type]: + self._state = data[self._type] // 60 + else: + self._state = data[self._type] + except KeyError: + _LOGGER.debug("Entity type %s not found in fetched data", self._type) + return _LOGGER.debug( "Entity %s set to state %s %s", self._type, self._state, self._unit diff --git a/homeassistant/components/mikrotik/hub.py b/homeassistant/components/mikrotik/hub.py index 2243b6cc5ce..6e64c443d8b 100644 --- a/homeassistant/components/mikrotik/hub.py +++ b/homeassistant/components/mikrotik/hub.py @@ -126,7 +126,7 @@ class MikrotikData: def get_info(self, param): """Return device model name.""" cmd = IDENTITY if param == NAME else INFO - data = list(self.command(MIKROTIK_SERVICES[cmd])) + data = self.command(MIKROTIK_SERVICES[cmd]) return data[0].get(param) if data else None def get_hub_details(self): @@ -148,7 +148,7 @@ class MikrotikData: def get_list_from_interface(self, interface): """Get devices from interface.""" - result = list(self.command(MIKROTIK_SERVICES[interface])) + result = self.command(MIKROTIK_SERVICES[interface]) return self.load_mac(result) if result else {} def restore_device(self, mac): @@ -224,7 +224,7 @@ class MikrotikData: "address": ip_address, } cmd = "/ping" - data = list(self.command(cmd, params)) + data = self.command(cmd, params) if data is not None: status = 0 for result in data: @@ -242,9 +242,9 @@ class MikrotikData: try: _LOGGER.info("Running command %s", cmd) if params: - response = self.api(cmd=cmd, **params) + response = list(self.api(cmd=cmd, **params)) else: - response = self.api(cmd=cmd) + response = list(self.api(cmd=cmd)) except ( librouteros.exceptions.ConnectionClosed, socket.error, diff --git a/homeassistant/components/mill/climate.py b/homeassistant/components/mill/climate.py index 8f880c74c6e..d904538451c 100644 --- a/homeassistant/components/mill/climate.py +++ b/homeassistant/components/mill/climate.py @@ -6,6 +6,8 @@ import voluptuous as vol from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateDevice from homeassistant.components.climate.const import ( + CURRENT_HVAC_HEAT, + CURRENT_HVAC_IDLE, FAN_ON, HVAC_MODE_HEAT, HVAC_MODE_OFF, @@ -167,13 +169,20 @@ class MillHeater(ClimateDevice): """Return the maximum temperature.""" return MAX_TEMP + @property + def hvac_action(self): + """Return current hvac i.e. heat, cool, idle.""" + if self._heater.is_gen1 or self._heater.is_heating == 1: + return CURRENT_HVAC_HEAT + return CURRENT_HVAC_IDLE + @property def hvac_mode(self) -> str: """Return hvac operation ie. heat, cool mode. Need to be one of HVAC_MODE_*. """ - if self._heater.is_gen1 or self._heater.is_heating == 1: + if self._heater.is_gen1 or self._heater.power_status == 1: return HVAC_MODE_HEAT return HVAC_MODE_OFF diff --git a/homeassistant/components/netatmo/sensor.py b/homeassistant/components/netatmo/sensor.py index 82c3748d19b..afdb7c053f3 100644 --- a/homeassistant/components/netatmo/sensor.py +++ b/homeassistant/components/netatmo/sensor.py @@ -217,7 +217,7 @@ class NetatmoSensor(Entity): if data is None: _LOGGER.info("No data found for %s (%s)", self.module_name, self._module_id) - _LOGGER.error("data: %s", self.netatmo_data.data) + _LOGGER.debug("data: %s", self.netatmo_data.data) self._state = None return diff --git a/homeassistant/components/nws/manifest.json b/homeassistant/components/nws/manifest.json index 5bb4cb46ee0..2bb77c2d95b 100644 --- a/homeassistant/components/nws/manifest.json +++ b/homeassistant/components/nws/manifest.json @@ -4,5 +4,5 @@ "documentation": "https://www.home-assistant.io/integrations/nws", "dependencies": [], "codeowners": ["@MatthewFlamm"], - "requirements": ["pynws==0.10.1"] + "requirements": ["pynws==0.10.4"] } diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index f7f70db590a..f5ec96690bc 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -4,10 +4,10 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/zha", "requirements": [ - "bellows-homeassistant==0.13.1", + "bellows-homeassistant==0.13.2", "zha-quirks==0.0.32", "zigpy-deconz==0.7.0", - "zigpy-homeassistant==0.13.0", + "zigpy-homeassistant==0.13.2", "zigpy-xbee-homeassistant==0.9.0", "zigpy-zigate==0.5.1" ], diff --git a/homeassistant/const.py b/homeassistant/const.py index c2d59eb2833..4ca501b1d23 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 105 -PATCH_VERSION = "2" +PATCH_VERSION = "3" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 0) diff --git a/requirements_all.txt b/requirements_all.txt index 627481a8d40..79d7d694f82 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -117,7 +117,7 @@ adafruit-circuitpython-mcp230xx==1.1.2 adb-shell==0.1.1 # homeassistant.components.adguard -adguardhome==0.4.0 +adguardhome==0.4.1 # homeassistant.components.frontier_silicon afsapi==0.0.4 @@ -299,7 +299,7 @@ beautifulsoup4==4.8.2 beewi_smartclim==0.0.7 # homeassistant.components.zha -bellows-homeassistant==0.13.1 +bellows-homeassistant==0.13.2 # homeassistant.components.bmw_connected_drive bimmer_connected==0.6.2 @@ -1067,7 +1067,7 @@ pushetta==1.0.15 pwmled==1.4.1 # homeassistant.components.august -py-august==0.7.0 +py-august==0.8.1 # homeassistant.components.canary py-canary==0.5.0 @@ -1399,7 +1399,7 @@ pynuki==1.3.3 pynut2==2.1.2 # homeassistant.components.nws -pynws==0.10.1 +pynws==0.10.4 # homeassistant.components.nx584 pynx584==0.4 @@ -2130,7 +2130,7 @@ ziggo-mediabox-xl==1.1.0 zigpy-deconz==0.7.0 # homeassistant.components.zha -zigpy-homeassistant==0.13.0 +zigpy-homeassistant==0.13.2 # homeassistant.components.zha zigpy-xbee-homeassistant==0.9.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index c974743c516..3c4e17ac465 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -32,7 +32,7 @@ abodepy==0.17.0 adb-shell==0.1.1 # homeassistant.components.adguard -adguardhome==0.4.0 +adguardhome==0.4.1 # homeassistant.components.geonetnz_quakes aio_geojson_geonetnz_quakes==0.11 @@ -112,7 +112,7 @@ av==6.1.2 axis==25 # homeassistant.components.zha -bellows-homeassistant==0.13.1 +bellows-homeassistant==0.13.2 # homeassistant.components.bom bomradarloop==0.1.3 @@ -487,7 +487,7 @@ pymodbus==1.5.2 pymonoprice==0.3 # homeassistant.components.nws -pynws==0.10.1 +pynws==0.10.4 # homeassistant.components.nx584 pynx584==0.4 @@ -702,7 +702,7 @@ zha-quirks==0.0.32 zigpy-deconz==0.7.0 # homeassistant.components.zha -zigpy-homeassistant==0.13.0 +zigpy-homeassistant==0.13.2 # homeassistant.components.zha zigpy-xbee-homeassistant==0.9.0