Skip to content

Commit

Permalink
Merge pull request #21 from sh00t2kill/add-value-entities
Browse files Browse the repository at this point in the history
Add valve entities
  • Loading branch information
sh00t2kill authored Jan 8, 2024
2 parents 3e6c731 + f122b5d commit c56fb4c
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 3 deletions.
2 changes: 1 addition & 1 deletion custom_components/linktap/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
DEFAULT_TIME = 15
DEFAULT_NAME = "Linktap Local Integration"
DEFAULT_VOL = 0
PLATFORMS = ['number', 'binary_sensor', 'sensor', 'switch']
PLATFORMS = ['number', 'binary_sensor', 'sensor', 'switch', 'valve']
ATTR_DEFAULT_TIME = 'Default Time'
ATTR_VOL = "Watering by Volume"
ATTR_DURATION = "Watering Duration"
Expand Down
15 changes: 14 additions & 1 deletion custom_components/linktap/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dismiss_alerts:

pause:
name: Pause
description: Pause the watering
description: Pause the watering schedule
fields:
hours:
name: Hours
Expand All @@ -27,3 +27,16 @@ pause:
entity:
integration: linktap
domain: switch

pause_valve:
name: Pause
description: Pause the watering schedule
fields:
hours:
name: Hours
example: 1
description: Duration in hours
target:
entity:
integration: linktap
domain: valve
198 changes: 198 additions & 0 deletions custom_components/linktap/valve.py
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()
2 changes: 1 addition & 1 deletion hacs.json
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"
}

0 comments on commit c56fb4c

Please sign in to comment.