Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hibernation switch entity #202

Merged
merged 5 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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