mirror of https://github.com/home-assistant/core
Update in 1 minute on unavailable Motion blinds (#47800)
* if unavailable request update in 1 minute * fix styling * improve changing update interval * remove unused import * try to fix * remove unused pass * add const * fix missing timedelta * update to motionblinds 0.4.10 * improve update coordinator * fix linting errors * remove unused import * move update functions within the DataUpdateCoordinator * fix white space
This commit is contained in:
parent
d5afd0afb3
commit
b4d39d517f
|
@ -1,11 +1,11 @@
|
|||
"""The motion_blinds component."""
|
||||
import asyncio
|
||||
from contextlib import suppress
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from socket import timeout
|
||||
|
||||
from motionblinds import MotionMulticast
|
||||
from motionblinds.motion_blinds import ParseException
|
||||
|
||||
from homeassistant import config_entries, core
|
||||
from homeassistant.const import CONF_API_KEY, CONF_HOST, EVENT_HOMEASSISTANT_STOP
|
||||
|
@ -14,18 +14,87 @@ from homeassistant.helpers import device_registry as dr
|
|||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
||||
from .const import (
|
||||
ATTR_AVAILABLE,
|
||||
DOMAIN,
|
||||
KEY_COORDINATOR,
|
||||
KEY_GATEWAY,
|
||||
KEY_MULTICAST_LISTENER,
|
||||
MANUFACTURER,
|
||||
PLATFORMS,
|
||||
UPDATE_INTERVAL,
|
||||
UPDATE_INTERVAL_FAST,
|
||||
)
|
||||
from .gateway import ConnectMotionGateway
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DataUpdateCoordinatorMotionBlinds(DataUpdateCoordinator):
|
||||
"""Class to manage fetching data from single endpoint."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass,
|
||||
logger,
|
||||
gateway,
|
||||
*,
|
||||
name,
|
||||
update_interval=None,
|
||||
update_method=None,
|
||||
):
|
||||
"""Initialize global data updater."""
|
||||
super().__init__(
|
||||
hass,
|
||||
logger,
|
||||
name=name,
|
||||
update_method=update_method,
|
||||
update_interval=update_interval,
|
||||
)
|
||||
|
||||
self._gateway = gateway
|
||||
|
||||
def update_gateway(self):
|
||||
"""Call all updates using one async_add_executor_job."""
|
||||
data = {}
|
||||
|
||||
try:
|
||||
self._gateway.Update()
|
||||
except (timeout, ParseException):
|
||||
# let the error be logged and handled by the motionblinds library
|
||||
data[KEY_GATEWAY] = {ATTR_AVAILABLE: False}
|
||||
return data
|
||||
else:
|
||||
data[KEY_GATEWAY] = {ATTR_AVAILABLE: True}
|
||||
|
||||
for blind in self._gateway.device_list.values():
|
||||
try:
|
||||
blind.Update()
|
||||
except (timeout, ParseException):
|
||||
# let the error be logged and handled by the motionblinds library
|
||||
data[blind.mac] = {ATTR_AVAILABLE: False}
|
||||
else:
|
||||
data[blind.mac] = {ATTR_AVAILABLE: True}
|
||||
|
||||
return data
|
||||
|
||||
async def _async_update_data(self):
|
||||
"""Fetch the latest data from the gateway and blinds."""
|
||||
data = await self.hass.async_add_executor_job(self.update_gateway)
|
||||
|
||||
all_available = True
|
||||
for device in data.values():
|
||||
if not device[ATTR_AVAILABLE]:
|
||||
all_available = False
|
||||
break
|
||||
|
||||
if all_available:
|
||||
self.update_interval = timedelta(seconds=UPDATE_INTERVAL)
|
||||
else:
|
||||
self.update_interval = timedelta(seconds=UPDATE_INTERVAL_FAST)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def setup(hass: core.HomeAssistant, config: dict):
|
||||
"""Set up the Motion Blinds component."""
|
||||
return True
|
||||
|
@ -61,26 +130,14 @@ async def async_setup_entry(
|
|||
raise ConfigEntryNotReady
|
||||
motion_gateway = connect_gateway_class.gateway_device
|
||||
|
||||
def update_gateway():
|
||||
"""Call all updates using one async_add_executor_job."""
|
||||
motion_gateway.Update()
|
||||
for blind in motion_gateway.device_list.values():
|
||||
with suppress(timeout):
|
||||
blind.Update()
|
||||
|
||||
async def async_update_data():
|
||||
"""Fetch data from the gateway and blinds."""
|
||||
with suppress(timeout): # Let the error be handled by the motionblinds
|
||||
await hass.async_add_executor_job(update_gateway)
|
||||
|
||||
coordinator = DataUpdateCoordinator(
|
||||
coordinator = DataUpdateCoordinatorMotionBlinds(
|
||||
hass,
|
||||
_LOGGER,
|
||||
motion_gateway,
|
||||
# Name of the data. For logging purposes.
|
||||
name=entry.title,
|
||||
update_method=async_update_data,
|
||||
# Polling interval. Will only be polled if there are subscribers.
|
||||
update_interval=timedelta(seconds=600),
|
||||
update_interval=timedelta(seconds=UPDATE_INTERVAL),
|
||||
)
|
||||
|
||||
# Fetch initial data so we have data when entities subscribe
|
||||
|
|
|
@ -11,5 +11,9 @@ KEY_MULTICAST_LISTENER = "multicast_listener"
|
|||
|
||||
ATTR_WIDTH = "width"
|
||||
ATTR_ABSOLUTE_POSITION = "absolute_position"
|
||||
ATTR_AVAILABLE = "available"
|
||||
|
||||
SERVICE_SET_ABSOLUTE_POSITION = "set_absolute_position"
|
||||
|
||||
UPDATE_INTERVAL = 600
|
||||
UPDATE_INTERVAL_FAST = 60
|
||||
|
|
|
@ -21,6 +21,7 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|||
|
||||
from .const import (
|
||||
ATTR_ABSOLUTE_POSITION,
|
||||
ATTR_AVAILABLE,
|
||||
ATTR_WIDTH,
|
||||
DOMAIN,
|
||||
KEY_COORDINATOR,
|
||||
|
@ -160,7 +161,13 @@ class MotionPositionDevice(CoordinatorEntity, CoverEntity):
|
|||
@property
|
||||
def available(self):
|
||||
"""Return True if entity is available."""
|
||||
return self._blind.available
|
||||
if self.coordinator.data is None:
|
||||
return False
|
||||
|
||||
if not self.coordinator.data[KEY_GATEWAY][ATTR_AVAILABLE]:
|
||||
return False
|
||||
|
||||
return self.coordinator.data[self._blind.mac][ATTR_AVAILABLE]
|
||||
|
||||
@property
|
||||
def current_cover_position(self):
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
"name": "Motion Blinds",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/motion_blinds",
|
||||
"requirements": ["motionblinds==0.4.8"],
|
||||
"requirements": ["motionblinds==0.4.10"],
|
||||
"codeowners": ["@starkillerOG"]
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DOMAIN, KEY_COORDINATOR, KEY_GATEWAY
|
||||
from .const import ATTR_AVAILABLE, DOMAIN, KEY_COORDINATOR, KEY_GATEWAY
|
||||
|
||||
ATTR_BATTERY_VOLTAGE = "battery_voltage"
|
||||
TYPE_BLIND = "blind"
|
||||
|
@ -70,7 +70,13 @@ class MotionBatterySensor(CoordinatorEntity, SensorEntity):
|
|||
@property
|
||||
def available(self):
|
||||
"""Return True if entity is available."""
|
||||
return self._blind.available
|
||||
if self.coordinator.data is None:
|
||||
return False
|
||||
|
||||
if not self.coordinator.data[KEY_GATEWAY][ATTR_AVAILABLE]:
|
||||
return False
|
||||
|
||||
return self.coordinator.data[self._blind.mac][ATTR_AVAILABLE]
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
|
@ -174,7 +180,13 @@ class MotionSignalStrengthSensor(CoordinatorEntity, SensorEntity):
|
|||
@property
|
||||
def available(self):
|
||||
"""Return True if entity is available."""
|
||||
return self._device.available
|
||||
if self.coordinator.data is None:
|
||||
return False
|
||||
|
||||
if not self.coordinator.data[KEY_GATEWAY][ATTR_AVAILABLE]:
|
||||
return False
|
||||
|
||||
return self.coordinator.data[self._device.mac][ATTR_AVAILABLE]
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
|
|
|
@ -946,7 +946,7 @@ minio==4.0.9
|
|||
mitemp_bt==0.0.3
|
||||
|
||||
# homeassistant.components.motion_blinds
|
||||
motionblinds==0.4.8
|
||||
motionblinds==0.4.10
|
||||
|
||||
# homeassistant.components.mullvad
|
||||
mullvad-api==1.0.0
|
||||
|
|
|
@ -491,7 +491,7 @@ millheater==0.4.0
|
|||
minio==4.0.9
|
||||
|
||||
# homeassistant.components.motion_blinds
|
||||
motionblinds==0.4.8
|
||||
motionblinds==0.4.10
|
||||
|
||||
# homeassistant.components.mullvad
|
||||
mullvad-api==1.0.0
|
||||
|
|
Loading…
Reference in New Issue