mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 18:57:06 +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.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.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_MODEL, ATTR_NAME, ATTR_SW_VERSION, CONF_HOST
|
||||
@ -31,6 +32,7 @@ SCAN_INTERVAL = timedelta(seconds=5)
|
||||
PLATFORMS = [
|
||||
LIGHT_DOMAIN,
|
||||
FAN_DOMAIN,
|
||||
SENSOR_DOMAIN,
|
||||
SWITCH_DOMAIN,
|
||||
]
|
||||
_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
|
||||
|
||||
|
||||
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(
|
||||
hass: HomeAssistant,
|
||||
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