Skip to content

Commit

Permalink
Merge pull request #202 from ufozone/hibernation
Browse files Browse the repository at this point in the history
Add hibernation switch entity
  • Loading branch information
ufozone authored Oct 13, 2024
2 parents 2e30ce9 + 0657b3c commit dbf3743
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 3 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,11 @@ _These entities are disabled by default. You have to activate it if you want to
connect_expiration, infinity_state, infinity_expiration
```

### Switch

* hibernation
_This entity only exists once per configuration entry. The configuration affects all lawn mowers set up for this configuration entry._

### Vacuum

_This entity is disabled by default. You have to activate it if you want to use it._
Expand Down
1 change: 1 addition & 0 deletions custom_components/zcsmower/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
Platform.LAWN_MOWER,
Platform.NUMBER,
Platform.SENSOR,
Platform.SWITCH,
Platform.VACUUM,
]

Expand Down
22 changes: 22 additions & 0 deletions custom_components/zcsmower/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ def __init__(

self._loop = asyncio.get_event_loop()
self._scheduled_update_listeners: asyncio.TimerHandle | None = None
self._scheduled_update_entry: asyncio.TimerHandle | None = None

def _convert_datetime_from_api(
self,
Expand Down Expand Up @@ -231,6 +232,27 @@ async def _async_update_listeners(self) -> None:
lambda: self.async_update_listeners(),
)

async def async_set_entry_option(
self,
key: str,
value: any,
) -> None:
"""Set config entry option and update config entry after 3 second."""
_options = dict(self.config_entry.options)
_options.update(
{
key: value
}
)
if self._scheduled_update_entry:
self._scheduled_update_entry.cancel()
self._scheduled_update_entry = self.hass.loop.call_later(
3,
lambda: self.hass.config_entries.async_update_entry(
self.config_entry, options=_options
),
)

def get_mower_attributes(
self,
imei: str,
Expand Down
51 changes: 48 additions & 3 deletions custom_components/zcsmower/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
ATTR_SW_VERSION,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.device_registry import (
DeviceEntryType,
DeviceInfo,
)
from homeassistant.helpers.entity import (
EntityCategory,
EntityDescription,
Expand All @@ -30,12 +33,13 @@
ATTR_ERROR,
ATTR_AVAILABLE,
ATTRIBUTION,
MANUFACTURER_DEFAULT,
)
from .coordinator import ZcsMowerDataUpdateCoordinator


class ZcsMowerEntity(CoordinatorEntity):
"""ZCS Lawn Mower Robot class."""
"""ZCS Lawn Mower Robot entity class."""

_attr_attribution = ATTRIBUTION
_attr_has_entity_name = True
Expand Down Expand Up @@ -133,7 +137,7 @@ def _update_handler(self) -> None:

@property
def unique_id(self) -> str:
"""Return the unique ID of the sensor."""
"""Return the unique ID of the entity."""
return self._unique_id

@property
Expand Down Expand Up @@ -165,3 +169,44 @@ def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._update_handler()
self.async_write_ha_state()


class ZcsConfigEntity(CoordinatorEntity):
"""ZCS Configuration entity class."""

_attr_has_entity_name = True

def __init__(
self,
hass: HomeAssistant,
config_entry: ConfigEntry,
coordinator: ZcsMowerDataUpdateCoordinator,
entity_type: str,
entity_description: EntityDescription,
) -> None:
"""Initialize."""
super().__init__(coordinator)

self.hass = hass
self.config_entry = config_entry
self.entity_description = entity_description

self._name = self.config_entry.title
self._entity_key = entity_description.key
self._unique_id = slugify(f"{self._entity_key}_{config_entry.entry_id}")

self.entity_id = f"{entity_type}.{self._unique_id}"
self._attr_device_info = DeviceInfo(
entry_type=DeviceEntryType.SERVICE,
identifiers={
(DOMAIN, self._unique_id)
},
name=config_entry.title,
manufacturer=MANUFACTURER_DEFAULT,
)
self._config_key = entity_description.config_key

@property
def unique_id(self) -> str:
"""Return the unique ID of the entity."""
return self._unique_id
5 changes: 5 additions & 0 deletions custom_components/zcsmower/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,11 @@
}
}
},
"switch": {
"hibernation": {
"name": "Winter break"
}
},
"vacuum": {
"mower": {
"state": {
Expand Down
106 changes: 106 additions & 0 deletions custom_components/zcsmower/switch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
"""ZCS Lawn Mower Robot switch platform."""

from __future__ import annotations

from dataclasses import dataclass

from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntry
from homeassistant.components.switch import (
SwitchEntity,
SwitchEntityDescription,
)
from homeassistant.helpers.entity import (
Entity,
EntityCategory,
)

from .const import (
CONF_HIBERNATION_ENABLE,
)
from .coordinator import ZcsMowerDataUpdateCoordinator
from .entity import ZcsConfigEntity


@dataclass(frozen=True, kw_only=True)
class ZcsConfigSwitchEntityDescription(SwitchEntityDescription):
"""Describes ZCS Lawn Mower Robot switch entity."""

config_key: str


ENTITY_DESCRIPTIONS = (
ZcsConfigSwitchEntityDescription(
key="mower_hibernation",
translation_key="hibernation",
entity_category=EntityCategory.CONFIG,
config_key=CONF_HIBERNATION_ENABLE,
),
)


async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: Entity,
) -> None:
"""Do setup sensors from a config entry created in the integrations UI."""
coordinator = config_entry.runtime_data
async_add_entities(
[
ZcsConfigSwitchEntity(
hass=hass,
config_entry=config_entry,
coordinator=coordinator,
entity_description=entity_description,
)
for entity_description in ENTITY_DESCRIPTIONS
],
update_before_add=True,
)


class ZcsConfigSwitchEntity(ZcsConfigEntity, SwitchEntity):
"""Representation of a ZCS configuration switch."""

_attr_has_entity_name = True

def __init__(
self,
hass: HomeAssistant,
config_entry: ConfigEntry,
coordinator: ZcsMowerDataUpdateCoordinator,
entity_description: SwitchEntityDescription,
) -> None:
"""Initialize the switch class."""
super().__init__(
hass=hass,
config_entry=config_entry,
coordinator=coordinator,
entity_type="switch",
entity_description=entity_description,
)

@property
def unique_id(self) -> str:
"""Return the unique ID of the sensor."""
return self._unique_id

@property
def is_on(self) -> bool:
"""Return True if entity is on."""
return bool(self.config_entry.options.get(self._config_key, False))

async def async_turn_on(self, **kwargs: any) -> None:
"""Turn the entity on."""
await self.coordinator.async_set_entry_option(
self._config_key,
True,
)

async def async_turn_off(self, **kwargs: any) -> None:
"""Turn the entity off."""
await self.coordinator.async_set_entry_option(
self._config_key,
False,
)
5 changes: 5 additions & 0 deletions custom_components/zcsmower/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,11 @@
}
}
},
"switch": {
"hibernation": {
"name": "Winterpause"
}
},
"vacuum": {
"mower": {
"state": {
Expand Down
5 changes: 5 additions & 0 deletions custom_components/zcsmower/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,11 @@
}
}
},
"switch": {
"hibernation": {
"name": "Winter break"
}
},
"vacuum": {
"mower": {
"state": {
Expand Down
5 changes: 5 additions & 0 deletions custom_components/zcsmower/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,11 @@
}
}
},
"switch": {
"hibernation": {
"name": "Pausa invernale"
}
},
"vacuum": {
"mower": {
"state": {
Expand Down
5 changes: 5 additions & 0 deletions info.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,11 @@ _These entities are disabled by default. You have to activate it if you want to
connect_expiration, infinity_state, infinity_expiration
```

### Switch

* hibernation
_This entity only exists once per configuration entry. The configuration affects all lawn mowers set up for this configuration entry._

### Vacuum

_This entity is disabled by default. You have to activate it if you want to use it._
Expand Down

0 comments on commit dbf3743

Please sign in to comment.