Skip to content

Commit

Permalink
Merge pull request #102 from basbruss/update-adaptive-cover-coordinator
Browse files Browse the repository at this point in the history
Add manual override
  • Loading branch information
basbruss authored Apr 11, 2024
2 parents fa8046d + 2e464fc commit cc5b80c
Show file tree
Hide file tree
Showing 11 changed files with 405 additions and 115 deletions.
2 changes: 1 addition & 1 deletion custom_components/adaptive_cover/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
)
from .coordinator import AdaptiveDataUpdateCoordinator

PLATFORMS = [Platform.SENSOR, Platform.SWITCH, Platform.BINARY_SENSOR]
PLATFORMS = [Platform.SENSOR, Platform.SWITCH, Platform.BINARY_SENSOR, Platform.BUTTON]
CONF_SUN = ["sun.sun"]


Expand Down
26 changes: 23 additions & 3 deletions custom_components/adaptive_cover/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

from __future__ import annotations

from collections.abc import Mapping
from typing import Any

from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
Expand Down Expand Up @@ -31,10 +34,20 @@ async def async_setup_entry(
config_entry.entry_id,
"Sun Infront",
False,
"sun_motion",
BinarySensorDeviceClass.MOTION,
coordinator,
)
async_add_entities([binary_sensor])
manual_override = AdaptiveCoverBinarySensor(
config_entry,
config_entry.entry_id,
"Manual Override",
False,
"manual_override",
BinarySensorDeviceClass.RUNNING,
coordinator,
)
async_add_entities([binary_sensor, manual_override])


class AdaptiveCoverBinarySensor(
Expand All @@ -44,14 +57,14 @@ class AdaptiveCoverBinarySensor(

_attr_has_entity_name = True
_attr_should_poll = False
_attr_translation_key = "sun_motion"

def __init__(
self,
config_entry,
unique_id: str,
binary_name: str,
state: bool,
key: str,
device_class: BinarySensorDeviceClass,
coordinator: AdaptiveDataUpdateCoordinator,
) -> None:
Expand All @@ -62,6 +75,8 @@ def __init__(
"cover_awning": "Horizontal",
"cover_tilt": "Tilt",
}
self._key = key
self._attr_translation_key = key
self._name = config_entry.data["name"]
self._device_name = self.type[config_entry.data[CONF_SENSOR_TYPE]]
self._binary_name = binary_name
Expand All @@ -82,4 +97,9 @@ def name(self):
@property
def is_on(self) -> bool:
"""Return true if the binary sensor is on."""
return self.coordinator.data.states["binary"]
return self.coordinator.data.states[self._key]

@property
def extra_state_attributes(self) -> Mapping[str, Any] | None: # noqa: D102
if self._key == "manual_override":
return {"manual_controlled": self.coordinator.data.states["manual_list"]}
90 changes: 90 additions & 0 deletions custom_components/adaptive_cover/button.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""Button platform for the Adaptive Cover integration."""

from __future__ import annotations

from homeassistant.components.button import ButtonEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import _LOGGER, CONF_ENTITIES, CONF_SENSOR_TYPE, DOMAIN
from .coordinator import AdaptiveDataUpdateCoordinator


async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the button platform."""
coordinator: AdaptiveDataUpdateCoordinator = hass.data[DOMAIN][
config_entry.entry_id
]

reset_manual = AdaptiveCoverButton(
config_entry, config_entry.entry_id, "Reset Manual Override", coordinator
)

buttons = []

entities = config_entry.options.get(CONF_ENTITIES, [])
if len(entities) >= 1:
buttons = [reset_manual]

async_add_entities(buttons)


class AdaptiveCoverButton(
CoordinatorEntity[AdaptiveDataUpdateCoordinator], ButtonEntity
):
"""Representation of a adaptive cover button."""

_attr_has_entity_name = True
_attr_should_poll = False
_attr_icon = "mdi:cog-refresh-outline"

def __init__(
self,
config_entry,
unique_id: str,
button_name: str,
coordinator: AdaptiveDataUpdateCoordinator,
) -> None:
"""Initialize the button."""
super().__init__(coordinator=coordinator)
self.type = {
"cover_blind": "Vertical",
"cover_awning": "Horizontal",
"cover_tilt": "Tilt",
}
self._name = config_entry.data["name"]
self._device_name = self.type[config_entry.data[CONF_SENSOR_TYPE]]
self._attr_unique_id = f"{unique_id}_{button_name}"
self._device_id = unique_id
self._button_name = button_name
self._entities = config_entry.options.get(CONF_ENTITIES, [])
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, self._device_id)},
name=self._device_name,
)

@property
def name(self):
"""Name of the entity."""
return f"{self._button_name} {self._name}"

async def async_press(self) -> None:
"""Handle the button press."""
for entity in self._entities:
if self.coordinator.manager.is_cover_manual(entity):
_LOGGER.debug("Resetting manual override for: %s", entity)
await self.coordinator.async_set_position(entity)
self.coordinator.manager.reset(entity)
else:
_LOGGER.debug(
"Resetting manual override for %s is not needed since it is already auto-cotrolled",
entity,
)
await self.coordinator.async_refresh()
8 changes: 8 additions & 0 deletions custom_components/adaptive_cover/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@
vol.Optional(CONF_START_ENTITY): selector.EntitySelector(
selector.EntitySelectorConfig(domain=["sensor", "input_datetime"])
),
vol.Required(
CONF_MANUAL_OVERRIDE_DURATION, default={"minutes": 15}
): selector.DurationSelector(),
vol.Required(CONF_MANUAL_OVERRIDE_RESET, default=False): bool,
}
)

Expand Down Expand Up @@ -405,6 +409,10 @@ async def async_step_update(self, user_input: dict[str, Any] | None = None):
CONF_DELTA_TIME: self.config.get(CONF_DELTA_TIME),
CONF_START_TIME: self.config.get(CONF_START_TIME),
CONF_START_ENTITY: self.config.get(CONF_START_ENTITY),
CONF_MANUAL_OVERRIDE_DURATION: self.config.get(
CONF_MANUAL_OVERRIDE_DURATION
),
CONF_MANUAL_OVERRIDE_RESET: self.config.get(CONF_MANUAL_OVERRIDE_RESET),
},
)

Expand Down
4 changes: 4 additions & 0 deletions custom_components/adaptive_cover/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

DOMAIN = "adaptive_cover"
LOGGER = logging.getLogger(__package__)
_LOGGER = logging.getLogger(__name__)

ATTR_POSITION = "position"
ATTR_TILT_POSITION = "tilt_position"
Expand Down Expand Up @@ -40,10 +41,13 @@
CONF_MAX_POSITION = "max_position"
CONF_OUTSIDETEMP_ENTITY = "outside_temp"


CONF_DELTA_POSITION = "delta_position"
CONF_DELTA_TIME = "delta_time"
CONF_START_TIME = "start_time"
CONF_START_ENTITY = "start_entity"
CONF_MANUAL_OVERRIDE_DURATION = "manual_override_duration"
CONF_MANUAL_OVERRIDE_RESET = "manual_override_reset"

STRATEGY_MODE_BASIC = "basic"
STRATEGY_MODE_CLIMATE = "climate"
Expand Down
Loading

0 comments on commit cc5b80c

Please sign in to comment.