mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Add reconnect logic and proper reporting to MotionMount integration (#125670)
* Add reconnect logic and proper reporting * Use snake_case * Log on warning, not on info * Reduce line length * Refactor non-raising code out of try blocks * Remove `_ensure_connected()` from action functions
This commit is contained in:
parent
18e2c2f6dd
commit
e6b86b662a
@ -1,5 +1,7 @@
|
|||||||
"""Support for MotionMount sensors."""
|
"""Support for MotionMount sensors."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import socket
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import motionmount
|
import motionmount
|
||||||
@ -12,6 +14,8 @@ from homeassistant.helpers.entity import Entity
|
|||||||
|
|
||||||
from .const import DOMAIN, EMPTY_MAC
|
from .const import DOMAIN, EMPTY_MAC
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class MotionMountEntity(Entity):
|
class MotionMountEntity(Entity):
|
||||||
"""Representation of a MotionMount entity."""
|
"""Representation of a MotionMount entity."""
|
||||||
@ -70,3 +74,23 @@ class MotionMountEntity(Entity):
|
|||||||
self.mm.remove_listener(self.async_write_ha_state)
|
self.mm.remove_listener(self.async_write_ha_state)
|
||||||
self.mm.remove_listener(self.update_name)
|
self.mm.remove_listener(self.update_name)
|
||||||
await super().async_will_remove_from_hass()
|
await super().async_will_remove_from_hass()
|
||||||
|
|
||||||
|
async def _ensure_connected(self) -> bool:
|
||||||
|
"""Make sure there is a connection with the MotionMount.
|
||||||
|
|
||||||
|
Returns false if the connection failed to be ensured.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if self.mm.is_connected:
|
||||||
|
return True
|
||||||
|
try:
|
||||||
|
await self.mm.connect()
|
||||||
|
except (ConnectionError, TimeoutError, socket.gaierror):
|
||||||
|
# We're not interested in exceptions here. In case of a failed connection
|
||||||
|
# the try/except from the caller will report it.
|
||||||
|
# The purpose of `_ensure_connected()` is only to make sure we try to
|
||||||
|
# reconnect, where failures should not be logged each time
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
_LOGGER.warning("Successfully reconnected to MotionMount")
|
||||||
|
return True
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
"""Support for MotionMount numeric control."""
|
"""Support for MotionMount numeric control."""
|
||||||
|
|
||||||
|
import socket
|
||||||
|
|
||||||
import motionmount
|
import motionmount
|
||||||
|
|
||||||
from homeassistant.components.number import NumberEntity
|
from homeassistant.components.number import NumberEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import PERCENTAGE
|
from homeassistant.const import PERCENTAGE
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
@ -46,7 +49,10 @@ class MotionMountExtension(MotionMountEntity, NumberEntity):
|
|||||||
|
|
||||||
async def async_set_native_value(self, value: float) -> None:
|
async def async_set_native_value(self, value: float) -> None:
|
||||||
"""Set the new value for extension."""
|
"""Set the new value for extension."""
|
||||||
await self.mm.set_extension(int(value))
|
try:
|
||||||
|
await self.mm.set_extension(int(value))
|
||||||
|
except (TimeoutError, socket.gaierror) as ex:
|
||||||
|
raise HomeAssistantError("Failed to communicate with MotionMount") from ex
|
||||||
|
|
||||||
|
|
||||||
class MotionMountTurn(MotionMountEntity, NumberEntity):
|
class MotionMountTurn(MotionMountEntity, NumberEntity):
|
||||||
@ -69,4 +75,7 @@ class MotionMountTurn(MotionMountEntity, NumberEntity):
|
|||||||
|
|
||||||
async def async_set_native_value(self, value: float) -> None:
|
async def async_set_native_value(self, value: float) -> None:
|
||||||
"""Set the new value for turn."""
|
"""Set the new value for turn."""
|
||||||
await self.mm.set_turn(int(value * -1))
|
try:
|
||||||
|
await self.mm.set_turn(int(value * -1))
|
||||||
|
except (TimeoutError, socket.gaierror) as ex:
|
||||||
|
raise HomeAssistantError("Failed to communicate with MotionMount") from ex
|
||||||
|
@ -1,15 +1,23 @@
|
|||||||
"""Support for MotionMount numeric control."""
|
"""Support for MotionMount numeric control."""
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
|
import socket
|
||||||
|
|
||||||
import motionmount
|
import motionmount
|
||||||
|
|
||||||
from homeassistant.components.select import SelectEntity
|
from homeassistant.components.select import SelectEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .const import DOMAIN, WALL_PRESET_NAME
|
from .const import DOMAIN, WALL_PRESET_NAME
|
||||||
from .entity import MotionMountEntity
|
from .entity import MotionMountEntity
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
SCAN_INTERVAL = timedelta(seconds=60)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
@ -23,6 +31,7 @@ async def async_setup_entry(
|
|||||||
class MotionMountPresets(MotionMountEntity, SelectEntity):
|
class MotionMountPresets(MotionMountEntity, SelectEntity):
|
||||||
"""The presets of a MotionMount."""
|
"""The presets of a MotionMount."""
|
||||||
|
|
||||||
|
_attr_should_poll = True
|
||||||
_attr_translation_key = "motionmount_preset"
|
_attr_translation_key = "motionmount_preset"
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -44,8 +53,15 @@ class MotionMountPresets(MotionMountEntity, SelectEntity):
|
|||||||
|
|
||||||
async def async_update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
"""Get latest state from MotionMount."""
|
"""Get latest state from MotionMount."""
|
||||||
self._presets = await self.mm.get_presets()
|
if not await self._ensure_connected():
|
||||||
self._update_options(self._presets)
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._presets = await self.mm.get_presets()
|
||||||
|
except (TimeoutError, socket.gaierror) as ex:
|
||||||
|
_LOGGER.warning("Failed to communicate with MotionMount: %s", ex)
|
||||||
|
else:
|
||||||
|
self._update_options(self._presets)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_option(self) -> str | None:
|
def current_option(self) -> str | None:
|
||||||
@ -72,8 +88,9 @@ class MotionMountPresets(MotionMountEntity, SelectEntity):
|
|||||||
async def async_select_option(self, option: str) -> None:
|
async def async_select_option(self, option: str) -> None:
|
||||||
"""Set the new option."""
|
"""Set the new option."""
|
||||||
index = int(option[:1])
|
index = int(option[:1])
|
||||||
await self.mm.go_to_preset(index)
|
try:
|
||||||
self._attr_current_option = option
|
await self.mm.go_to_preset(index)
|
||||||
|
except (TimeoutError, socket.gaierror) as ex:
|
||||||
# Perform an update so we detect changes to the presets (changes are not pushed)
|
raise HomeAssistantError("Failed to communicate with MotionMount") from ex
|
||||||
self.async_schedule_update_ha_state(True)
|
else:
|
||||||
|
self._attr_current_option = option
|
||||||
|
Loading…
x
Reference in New Issue
Block a user