mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 19:57:07 +00:00
Add sensor platform to Modern Forms integration (#52249)
* Add sensor platform to Modern Forms integration * Changes to sensors to timestamp class * lint cleanup
This commit is contained in:
parent
6a528acafe
commit
3ab42c50c9
@ -13,6 +13,7 @@ from aiomodernforms.models import Device as ModernFormsDeviceState
|
|||||||
|
|
||||||
from homeassistant.components.fan import DOMAIN as FAN_DOMAIN
|
from homeassistant.components.fan import DOMAIN as FAN_DOMAIN
|
||||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||||
|
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import ATTR_MODEL, ATTR_NAME, ATTR_SW_VERSION, CONF_HOST
|
from homeassistant.const import ATTR_MODEL, ATTR_NAME, ATTR_SW_VERSION, CONF_HOST
|
||||||
@ -31,6 +32,7 @@ SCAN_INTERVAL = timedelta(seconds=5)
|
|||||||
PLATFORMS = [
|
PLATFORMS = [
|
||||||
LIGHT_DOMAIN,
|
LIGHT_DOMAIN,
|
||||||
FAN_DOMAIN,
|
FAN_DOMAIN,
|
||||||
|
SENSOR_DOMAIN,
|
||||||
SWITCH_DOMAIN,
|
SWITCH_DOMAIN,
|
||||||
]
|
]
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
118
homeassistant/components/modern_forms/sensor.py
Normal file
118
homeassistant/components/modern_forms/sensor.py
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
"""Support for Modern Forms switches."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from homeassistant.components.sensor import SensorEntity
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import DEVICE_CLASS_TIMESTAMP
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.helpers.typing import StateType
|
||||||
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
|
from . import ModernFormsDataUpdateCoordinator, ModernFormsDeviceEntity
|
||||||
|
from .const import CLEAR_TIMER, DOMAIN
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up Modern Forms sensor based on a config entry."""
|
||||||
|
coordinator: ModernFormsDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
|
||||||
|
sensors: list[ModernFormsSensor] = [
|
||||||
|
ModernFormsFanTimerRemainingTimeSensor(entry.entry_id, coordinator),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Only setup light sleep timer sensor if light unit installed
|
||||||
|
if coordinator.data.info.light_type:
|
||||||
|
sensors.append(
|
||||||
|
ModernFormsLightTimerRemainingTimeSensor(entry.entry_id, coordinator)
|
||||||
|
)
|
||||||
|
|
||||||
|
async_add_entities(sensors)
|
||||||
|
|
||||||
|
|
||||||
|
class ModernFormsSensor(ModernFormsDeviceEntity, SensorEntity):
|
||||||
|
"""Defines a Modern Forms binary sensor."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
entry_id: str,
|
||||||
|
coordinator: ModernFormsDataUpdateCoordinator,
|
||||||
|
name: str,
|
||||||
|
icon: str,
|
||||||
|
key: str,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize Modern Forms switch."""
|
||||||
|
self._key = key
|
||||||
|
super().__init__(
|
||||||
|
entry_id=entry_id, coordinator=coordinator, name=name, icon=icon
|
||||||
|
)
|
||||||
|
self._attr_unique_id = f"{self.coordinator.data.info.mac_address}_{self._key}"
|
||||||
|
|
||||||
|
|
||||||
|
class ModernFormsLightTimerRemainingTimeSensor(ModernFormsSensor):
|
||||||
|
"""Defines the Modern Forms Light Timer remaining time sensor."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, entry_id: str, coordinator: ModernFormsDataUpdateCoordinator
|
||||||
|
) -> None:
|
||||||
|
"""Initialize Modern Forms Away mode switch."""
|
||||||
|
super().__init__(
|
||||||
|
coordinator=coordinator,
|
||||||
|
entry_id=entry_id,
|
||||||
|
icon="mdi:timer-outline",
|
||||||
|
key="light_timer_remaining_time",
|
||||||
|
name=f"{coordinator.data.info.device_name} Light Sleep Time",
|
||||||
|
)
|
||||||
|
self._attr_device_class = DEVICE_CLASS_TIMESTAMP
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self) -> StateType:
|
||||||
|
"""Return the state of the sensor."""
|
||||||
|
sleep_time: datetime = dt_util.utc_from_timestamp(
|
||||||
|
self.coordinator.data.state.light_sleep_timer
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
self.coordinator.data.state.light_sleep_timer == CLEAR_TIMER
|
||||||
|
or (sleep_time - dt_util.utcnow()).total_seconds() < 0
|
||||||
|
):
|
||||||
|
return None
|
||||||
|
return sleep_time.isoformat()
|
||||||
|
|
||||||
|
|
||||||
|
class ModernFormsFanTimerRemainingTimeSensor(ModernFormsSensor):
|
||||||
|
"""Defines the Modern Forms Light Timer remaining time sensor."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, entry_id: str, coordinator: ModernFormsDataUpdateCoordinator
|
||||||
|
) -> None:
|
||||||
|
"""Initialize Modern Forms Away mode switch."""
|
||||||
|
super().__init__(
|
||||||
|
coordinator=coordinator,
|
||||||
|
entry_id=entry_id,
|
||||||
|
icon="mdi:timer-outline",
|
||||||
|
key="fan_timer_remaining_time",
|
||||||
|
name=f"{coordinator.data.info.device_name} Fan Sleep Time",
|
||||||
|
)
|
||||||
|
self._attr_device_class = DEVICE_CLASS_TIMESTAMP
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self) -> StateType:
|
||||||
|
"""Return the state of the sensor."""
|
||||||
|
sleep_time: datetime = dt_util.utc_from_timestamp(
|
||||||
|
self.coordinator.data.state.fan_sleep_timer
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.coordinator.data.state.fan_sleep_timer == CLEAR_TIMER
|
||||||
|
or (sleep_time - dt_util.utcnow()).total_seconds() < 0
|
||||||
|
):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return sleep_time.isoformat()
|
@ -37,6 +37,18 @@ async def modern_forms_no_light_call_mock(method, url, data):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
async def modern_forms_timers_set_mock(method, url, data):
|
||||||
|
"""Set up the basic returns based on info or status request."""
|
||||||
|
if COMMAND_QUERY_STATIC_DATA in data:
|
||||||
|
fixture = "modern_forms/device_info.json"
|
||||||
|
else:
|
||||||
|
fixture = "modern_forms/device_status_timers_active.json"
|
||||||
|
response = AiohttpClientMockResponse(
|
||||||
|
method=method, url=url, json=json.loads(load_fixture(fixture))
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
async def init_integration(
|
async def init_integration(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
aioclient_mock: AiohttpClientMocker,
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
57
tests/components/modern_forms/test_sensor.py
Normal file
57
tests/components/modern_forms/test_sensor.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
"""Tests for the Modern Forms sensor platform."""
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from homeassistant.const import ATTR_DEVICE_CLASS, ATTR_ICON, DEVICE_CLASS_TIMESTAMP
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
|
from tests.components.modern_forms import init_integration, modern_forms_timers_set_mock
|
||||||
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensors(
|
||||||
|
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
||||||
|
) -> None:
|
||||||
|
"""Test the creation and values of the Modern Forms sensors."""
|
||||||
|
|
||||||
|
# await init_integration(hass, aioclient_mock)
|
||||||
|
await init_integration(hass, aioclient_mock)
|
||||||
|
er.async_get(hass)
|
||||||
|
|
||||||
|
# Light timer remaining time
|
||||||
|
state = hass.states.get("sensor.modernformsfan_light_sleep_time")
|
||||||
|
assert state
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:timer-outline"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TIMESTAMP
|
||||||
|
assert state.state == "unknown"
|
||||||
|
|
||||||
|
# Fan timer remaining time
|
||||||
|
state = hass.states.get("sensor.modernformsfan_fan_sleep_time")
|
||||||
|
assert state
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:timer-outline"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TIMESTAMP
|
||||||
|
assert state.state == "unknown"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_active_sensors(
|
||||||
|
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
||||||
|
) -> None:
|
||||||
|
"""Test the creation and values of the Modern Forms sensors."""
|
||||||
|
|
||||||
|
# await init_integration(hass, aioclient_mock)
|
||||||
|
await init_integration(hass, aioclient_mock, mock_type=modern_forms_timers_set_mock)
|
||||||
|
er.async_get(hass)
|
||||||
|
|
||||||
|
# Light timer remaining time
|
||||||
|
state = hass.states.get("sensor.modernformsfan_light_sleep_time")
|
||||||
|
assert state
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:timer-outline"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TIMESTAMP
|
||||||
|
datetime.fromisoformat(state.state)
|
||||||
|
|
||||||
|
# Fan timer remaining time
|
||||||
|
state = hass.states.get("sensor.modernformsfan_fan_sleep_time")
|
||||||
|
assert state
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:timer-outline"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TIMESTAMP
|
||||||
|
datetime.fromisoformat(state.state)
|
17
tests/fixtures/modern_forms/device_status_timers_active.json
vendored
Normal file
17
tests/fixtures/modern_forms/device_status_timers_active.json
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"adaptiveLearning": false,
|
||||||
|
"awayModeEnabled": false,
|
||||||
|
"clientId": "MF_000000000000",
|
||||||
|
"decommission": false,
|
||||||
|
"factoryReset": false,
|
||||||
|
"fanDirection": "forward",
|
||||||
|
"fanOn": true,
|
||||||
|
"fanSleepTimer": 9999999999,
|
||||||
|
"fanSpeed": 3,
|
||||||
|
"lightBrightness": 50,
|
||||||
|
"lightOn": true,
|
||||||
|
"lightSleepTimer": 9999999999,
|
||||||
|
"resetRfPairList": false,
|
||||||
|
"rfPairModeActive": false,
|
||||||
|
"schedule": ""
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user