Skip to content

Commit

Permalink
Use new Time entity
Browse files Browse the repository at this point in the history
Rewrote the component to support the new time entity.
  • Loading branch information
theneweinstein committed Jun 4, 2023
1 parent 71635e3 commit 979ddec
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 281 deletions.
3 changes: 2 additions & 1 deletion custom_components/somneo/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
""" Support for Philips Somneo devices."""
from __future__ import annotations

from datetime import timedelta, datetime
from datetime import timedelta
import logging
import asyncio

Expand All @@ -23,6 +23,7 @@
Platform.SELECT,
Platform.SENSOR,
Platform.SWITCH,
Platform.TIME,
]
SCAN_INTERVAL = timedelta(seconds=60)

Expand Down
80 changes: 43 additions & 37 deletions custom_components/somneo/const.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,52 @@

from homeassistant.const import (UnitOfTemperature, PERCENTAGE, LIGHT_LUX, UnitOfSoundPressure)
from homeassistant.const import (
UnitOfTemperature,
PERCENTAGE,
LIGHT_LUX,
UnitOfSoundPressure,
)
from typing import Final

DOMAIN: Final = 'somneo'
DOMAIN: Final = "somneo"
VERSION: Final = "0.3"

DEFAULT_NAME: Final = "Somneo"

CONF_SENS: Final = 'sensors'
CONF_SESSION: Final = 'session'

ALARM: Final = 'alarm'
PW: Final = 'powerwake'
ALARMS: Final = 'alarms'
HOURS: Final = 'hours'
MINUTES: Final = 'minutes'
WORKDAYS: Final = 'workdays'
WEEKEND: Final = 'weekend'
TOMORROW: Final = 'tomorrow'
EVERYDAY: Final = 'daily'
UNKNOWN: Final = 'unknown'
PW_DELTA: Final = 'powerwake_delta'

ALARMS_ICON: Final = 'hass:alarm'
PW_ICON: Final = 'hass:alarm-plus'
HOURS_ICON: Final = 'hass:counter'
MINUTES_ICON: Final = 'hass:counter'
WORKDAYS_ICON: Final = 'hass:calendar-range'
WEEKEND_ICON: Final = 'hass:calendar-range'

ATTR_ALARM: Final = 'alarm'
ATTR_CURVE: Final = 'curve'
ATTR_LEVEL: Final = 'level'
ATTR_DURATION: Final = 'duration'
ATTR_SOURCE: Final = 'source'
ATTR_CHANNEL: Final = 'channel'


SENSORS: Final = {'temperature': UnitOfTemperature.CELSIUS, 'humidity': PERCENTAGE, 'luminance': LIGHT_LUX, 'noise': UnitOfSoundPressure.DECIBEL}
CONF_SENS: Final = "sensors"
CONF_SESSION: Final = "session"

ALARM: Final = "alarm"
PW: Final = "powerwake"
ALARMS: Final = "alarms"
HOURS: Final = "hours"
MINUTES: Final = "minutes"
WORKDAYS: Final = "workdays"
WEEKEND: Final = "weekend"
TOMORROW: Final = "tomorrow"
EVERYDAY: Final = "daily"
UNKNOWN: Final = "unknown"
PW_DELTA: Final = "powerwake_delta"

ALARMS_ICON: Final = "hass:alarm"
PW_ICON: Final = "hass:alarm-plus"
TIME_ICON: Final = "hass:clock-digital"
SNOOZE_ICON: Final = "hass:alarm-snooze"
WORKDAYS_ICON: Final = "hass:calendar-range"
WEEKEND_ICON: Final = "hass:calendar-range"

ATTR_ALARM: Final = "alarm"
ATTR_CURVE: Final = "curve"
ATTR_LEVEL: Final = "level"
ATTR_DURATION: Final = "duration"
ATTR_SOURCE: Final = "source"
ATTR_CHANNEL: Final = "channel"


SENSORS: Final = {
"temperature": UnitOfTemperature.CELSIUS,
"humidity": PERCENTAGE,
"luminance": LIGHT_LUX,
"noise": UnitOfSoundPressure.DECIBEL,
}

NOTIFICATION_ID: Final = "somneosensor_notification"
NOTIFICATION_TITLE: Final = "SomneoSensor Setup"



4 changes: 2 additions & 2 deletions custom_components/somneo/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
"requirements": [
"pysomneo==2.5.2"
],
"version": "3.2.0"
}
"version": "4.0.0"
}
63 changes: 17 additions & 46 deletions custom_components/somneo/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import DOMAIN, HOURS, MINUTES, HOURS_ICON, MINUTES_ICON, PW_DELTA
from .const import DOMAIN, PW_ICON, SNOOZE_ICON
from .entity import SomneoEntity

_LOGGER = logging.getLogger(__name__)
Expand All @@ -27,74 +27,45 @@ async def async_setup_entry(
device_info = config_entry.data["dev_info"]

alarms = []
# Add hour & min number_entity for each alarms
# Add all PowerWake deltas
for alarm in list(coordinator.data["alarms"]):
alarms.append(
SomneoTime(coordinator, unique_id, name, device_info, alarm, HOURS)
)
alarms.append(
SomneoTime(coordinator, unique_id, name, device_info, alarm, MINUTES)
)
alarms.append(
SomneoTime(coordinator, unique_id, name, device_info, alarm, PW_DELTA)
)
alarms.append(SomneoPowerWake(coordinator, unique_id, name, device_info, alarm))

snooze = [SomneoSnooze(coordinator, unique_id, name, device_info, "snooze")]

async_add_entities(alarms, update_before_add=True)
async_add_entities(snooze, update_before_add=True)


class SomneoTime(SomneoEntity, NumberEntity):
class SomneoPowerWake(SomneoEntity, NumberEntity):
_attr_should_poll = True
_attr_assumed_state = False
_attr_available = True
_attr_native_step = 1
_attr_has_entity_name = True
_attr_native_min_value = 0
_attr_native_max_value = 59
_attr_icon = PW_ICON

def __init__(self, coordinator, unique_id, name, dev_info, alarm, type):
def __init__(self, coordinator, unique_id, name, dev_info, alarm):
"""Initialize number entities."""
super().__init__(coordinator, unique_id, name, dev_info, alarm + "_" + type)

self._attr_translation_key = alarm + "_" + type
if type == HOURS:
self._attr_native_min_value = 0
self._attr_native_max_value = 23
self._attr_icon = HOURS_ICON
elif type == MINUTES:
self._attr_native_min_value = 0
self._attr_native_max_value = 59
self._attr_icon = MINUTES_ICON
elif type == PW_DELTA:
self._attr_native_min_value = 0
self._attr_native_max_value = 59
self._attr_icon = MINUTES_ICON
super().__init__(
coordinator, unique_id, name, dev_info, alarm + "_powerwake_delta"
)

self._attr_translation_key = alarm + "_powerwake_delta"

self._alarm = alarm
self._type = type

@callback
def _handle_coordinator_update(self) -> None:
if self._type == MINUTES:
self._attr_native_value = self.coordinator.data["alarms_minute"][
self._alarm
]
elif self._type == HOURS:
self._attr_native_value = self.coordinator.data["alarms_hour"][self._alarm]
elif self._type == PW_DELTA:
self._attr_native_value = self.coordinator.data["powerwake_delta"][
self._alarm
]
"""Handle update"""
self._attr_native_value = self.coordinator.data["powerwake_delta"][self._alarm]
self.async_write_ha_state()

async def async_set_native_value(self, value: float) -> None:
"""Called when user adjust Hours / Minutes in the UI"""
if self._type == MINUTES:
await self.coordinator.async_set_alarm(self._alarm, minutes=int(value))
elif self._type == HOURS:
await self.coordinator.async_set_alarm(self._alarm, hours=int(value))
elif self._type == PW_DELTA:
await self.coordinator.async_set_powerwake(self._alarm, delta=int(value))
await self.coordinator.async_set_powerwake(self._alarm, delta=int(value))


class SomneoSnooze(SomneoEntity, NumberEntity):
Expand All @@ -105,7 +76,7 @@ class SomneoSnooze(SomneoEntity, NumberEntity):
_attr_native_min_value = 1
_attr_native_max_value = 20
_attr_native_step = 1
_attr_icon = "hass:alarm-snooze"
_attr_icon = SNOOZE_ICON
_attr_has_entity_name = True

@callback
Expand Down
67 changes: 67 additions & 0 deletions custom_components/somneo/time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""Platform for number entity to catch hour/minute of alarms."""
import logging
from datetime import time

from homeassistant.config_entries import ConfigEntry
from homeassistant.components.time import TimeEntity
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import DOMAIN, TIME_ICON
from .entity import SomneoEntity

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Add Somneo from config_entry."""

coordinator = hass.data[DOMAIN][config_entry.entry_id]
unique_id = config_entry.unique_id
assert unique_id is not None
name = config_entry.data[CONF_NAME]
device_info = config_entry.data["dev_info"]

alarms = []
# Add hour & min number_entity for each alarms
for alarm in list(coordinator.data["alarms"]):
alarms.append(SomneoTime(coordinator, unique_id, name, device_info, alarm))

async_add_entities(alarms, update_before_add=True)


class SomneoTime(SomneoEntity, TimeEntity):
_attr_should_poll = True
_attr_assumed_state = False
_attr_available = True
_attr_has_entity_name = True
_attr_icon = TIME_ICON
_attr_native_value = None

def __init__(self, coordinator, unique_id, name, dev_info, alarm):
"""Initialize number entities."""
super().__init__(coordinator, unique_id, name, dev_info, alarm + "_time")

self._attr_translation_key = alarm + "_time"

self._alarm = alarm

@callback
def _handle_coordinator_update(self) -> None:
self._attr_native_value = time(
self.coordinator.data["alarms_hour"][self._alarm],
self.coordinator.data["alarms_minute"][self._alarm],
)

self.async_write_ha_state()

async def async_set_value(self, value: time) -> None:
"""Called when user adjust Hours / Minutes in the UI"""
await self.coordinator.async_set_alarm(
self._alarm, hours=value.hour, minutes=value.minute
)
Loading

0 comments on commit 979ddec

Please sign in to comment.