-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from sh00t2kill/add-value-entities
Add valve entities
- Loading branch information
Showing
4 changed files
with
214 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
import asyncio | ||
import json | ||
import logging | ||
import random | ||
|
||
import aiohttp | ||
import homeassistant.helpers.config_validation as cv | ||
import voluptuous as vol | ||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN | ||
from homeassistant.components.valve import ValveEntity, ValveEntityFeature | ||
from homeassistant.const import ( | ||
ATTR_ENTITY_ID, | ||
CONF_ENTITY_ID, | ||
SERVICE_TURN_OFF, | ||
SERVICE_TURN_ON, | ||
STATE_OFF, | ||
STATE_ON, | ||
) | ||
from homeassistant.core import callback | ||
from homeassistant.helpers import entity_platform, service, entity_registry as er | ||
from homeassistant.helpers.entity import * | ||
from homeassistant.helpers.entity import DeviceInfo | ||
from homeassistant.helpers.entity_platform import AddEntitiesCallback | ||
from homeassistant.helpers.event import EventStateChangedData | ||
from homeassistant.helpers.typing import EventType | ||
from homeassistant.helpers.update_coordinator import (CoordinatorEntity, | ||
DataUpdateCoordinator) | ||
from homeassistant.util import slugify | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
from .const import (ATTR_STATE, DOMAIN, GW_IP, | ||
MANUFACTURER, NAME, TAP_ID) | ||
|
||
|
||
async def async_setup_entry( | ||
hass, config, async_add_entities, discovery_info=None | ||
): | ||
"""Initialize Valve """ | ||
taps = hass.data[DOMAIN][config.entry_id]["conf"]["taps"] | ||
valves = [] | ||
for tap in taps: | ||
coordinator = tap["coordinator"] | ||
_LOGGER.debug(f"Configuring valve for tap {tap}") | ||
valves.append(LinktapValve(coordinator, hass, tap)) | ||
async_add_entities(valves, True) | ||
|
||
platform = entity_platform.async_get_current_platform() | ||
platform.async_register_entity_service("pause_valve", | ||
{vol.Required("hours", default=1): vol.Coerce(int)}, | ||
"_pause_tap" | ||
) | ||
|
||
class LinktapValve(CoordinatorEntity, ValveEntity): | ||
def __init__(self, coordinator: DataUpdateCoordinator, hass, tap): | ||
super().__init__(coordinator) | ||
self._state = None | ||
self._name = tap[NAME] | ||
#self._id = tap[TAP_ID] | ||
self.tap_id = tap[TAP_ID] | ||
#self.tap_api = coordinator.tap_api | ||
self.platform = "valve" | ||
self.hass = hass | ||
self._attr_supported_features = ValveEntityFeature.OPEN | ValveEntityFeature.CLOSE | ||
self._attr_reports_position = False | ||
self._attr_unique_id = slugify(f"{DOMAIN}_{self.platform}_{self.tap_id}") | ||
#self._attr_icon = "mdi:water-pump" | ||
self._attrs = { | ||
"data": self.coordinator.data, | ||
"switch": self.switch_entity, | ||
# "duration_entity": self.duration_entity, | ||
# "volume_entity": self.volume_entity | ||
} | ||
self._attr_device_info = DeviceInfo( | ||
identifiers={ | ||
(DOMAIN, tap[TAP_ID]) | ||
}, | ||
name=tap[NAME], | ||
manufacturer=MANUFACTURER, | ||
configuration_url="http://" + tap[GW_IP] + "/" | ||
) | ||
|
||
@property | ||
def unique_id(self): | ||
return self._attr_unique_id | ||
|
||
@property | ||
def name(self): | ||
return f"{MANUFACTURER} {self._name}" | ||
|
||
@property | ||
def switch_entity(self): | ||
name = self._name.replace(" ", "_") | ||
name = name.replace("-", "_") | ||
return f"switch.{DOMAIN}_{name}".lower() | ||
|
||
# @property | ||
# def duration_entity(self): | ||
# name = self._name.replace(" ", "_") | ||
# name = name.replace("-", "_") | ||
# return f"number.{DOMAIN}_{name}_watering_duration".lower() | ||
|
||
# @property | ||
# def volume_entity(self): | ||
# name = self._name.replace(" ", "_") | ||
# name = name.replace("-", "_") | ||
# return f"number.{DOMAIN}_{name}_watering_volume".lower() | ||
|
||
async def async_open_valve(self, **kwargs): | ||
#duration = self.get_watering_duration() | ||
#seconds = int(float(duration)) * 60 | ||
#volume = self.get_watering_volume() | ||
#watering_volume = None | ||
#if volume != DEFAULT_VOL: | ||
# watering_volume = volume | ||
#gw_id = self.coordinator.get_gw_id() | ||
#attributes = await self.tap_api.turn_on(gw_id, self.tap_id, seconds, self.get_watering_volume()) | ||
"""Open the valve.""" | ||
await self.hass.services.async_call( | ||
SWITCH_DOMAIN, | ||
SERVICE_TURN_ON, | ||
{ATTR_ENTITY_ID: self.switch_entity}, | ||
blocking=True, | ||
context=self._context, | ||
) | ||
await self.coordinator.async_request_refresh() | ||
#self.control_result = await self.set_state(go="open") | ||
#self.async_write_ha_state() | ||
|
||
async def async_close_valve(self, **kwargs): | ||
"""Close valve.""" | ||
await self.hass.services.async_call( | ||
SWITCH_DOMAIN, | ||
SERVICE_TURN_OFF, | ||
{ATTR_ENTITY_ID: self.switch_entity}, | ||
blocking=True, | ||
context=self._context, | ||
) | ||
await self.coordinator.async_request_refresh() | ||
#self.control_result = await self.set_state(go="close") | ||
#self.async_write_ha_state() | ||
|
||
@property | ||
def extra_state_attributes(self): | ||
return self._attrs | ||
|
||
@callback | ||
def async_state_changed_listener( | ||
self, event: EventType[EventStateChangedData] | None = None | ||
) -> None: | ||
"""Handle child updates.""" | ||
super().async_state_changed_listener(event) | ||
if ( | ||
not self.available | ||
or (state := self.hass.states.get(self.switch_entity)) is None | ||
): | ||
return | ||
|
||
self._attr_is_closed = self._attrs[ATTR_STATE] != STATE_ON | ||
|
||
@property | ||
def state(self): | ||
status = self.coordinator.data | ||
#self._attrs["data"] = status | ||
#_LOGGER.debug(f"Switch Status: {status}") | ||
#duration = self.get_watering_duration() | ||
#_LOGGER.debug(f"Set duration:{duration}") | ||
#volume = self.get_watering_volume() | ||
#_LOGGER.debug(f"Set volume:{volume}") | ||
self._attrs[ATTR_STATE] = status[ATTR_STATE] | ||
state = "unknown" | ||
if status[ATTR_STATE]: | ||
state = "open" | ||
elif not status[ATTR_STATE]: | ||
state = "closed" | ||
_LOGGER.debug(f"Valve {self.name} state {state}") | ||
self._attr_is_closed = state != "open" | ||
return state | ||
|
||
@property | ||
def is_closed(self): | ||
return self.state() == "closed" | ||
|
||
@property | ||
def is_open(self): | ||
return self.state() == "open" | ||
|
||
@property | ||
def device_info(self) -> DeviceInfo: | ||
return self._attr_device_info | ||
|
||
async def _pause_tap(self, hours=False): | ||
if not hours: | ||
hours = 1 | ||
# Currently hard coding 1 hour for testing | ||
_LOGGER.debug(f"Pausing {self.entity_id} for {hours} hours") | ||
await self.tap_api.pause_tap(self._gw_id, self.tap_id, hours) | ||
await self.coordinator.async_request_refresh() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
{ | ||
"name": "Linktap Local", | ||
"homeassistant": "2023.06.0" | ||
"homeassistant": "2024.1.0" | ||
} |