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 service to refresh states on TaHoma box #241

Closed
wants to merge 2 commits into from
Closed
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
53 changes: 50 additions & 3 deletions custom_components/tahoma/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@
from aiohttp import CookieJar
from pyhoma.client import TahomaClient
from pyhoma.exceptions import BadCredentialsException, TooManyRequestsException
from pyhoma.models import Command
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.components.scene import DOMAIN as SCENE
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_EXCLUDE, CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import (
CONF_EXCLUDE,
CONF_PASSWORD,
CONF_USERNAME,
EVENT_HOMEASSISTANT_START,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client, config_validation as cv

Expand All @@ -27,6 +33,8 @@

_LOGGER = logging.getLogger(__name__)

SERVICE_EXECUTE_COMMAND = "execute_command"

CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.All(
Expand All @@ -45,6 +53,8 @@
extra=vol.ALLOW_EXTRA,
)

SERVICE_REFRESH_STATES = "refresh_states"


async def async_setup(hass: HomeAssistant, config: dict):
"""Set up the TaHoma component."""
Expand Down Expand Up @@ -137,6 +147,43 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
hass.config_entries.async_forward_entry_setup(entry, platform)
)

def _register_services(event):
"""Register the domain services."""
hass.services.async_register(
DOMAIN, SERVICE_REFRESH_STATES, handle_service_refresh_states
)

hass.services.async_register(
DOMAIN,
SERVICE_EXECUTE_COMMAND,
handle_execute_command,
vol.Schema(
{
vol.Required("entity_id"): cv.string,
vol.Required("command"): cv.string,
vol.Optional("args", default=[]): vol.All(
cv.ensure_list, [vol.Any(str, int)]
),
}
),
)

hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, _register_services)

async def handle_execute_command(call):
"""Handle execute command service."""
entity_registry = await hass.helpers.entity_registry.async_get_registry()
entity = entity_registry.entities.get(call.data.get("entity_id"))
await tahoma_coordinator.client.execute_command(
entity.unique_id,
Command(call.data.get("command"), call.data.get("args")),
"Home Assistant Service",
)

async def handle_service_refresh_states(call):
"""Handle the service call."""
await client.refresh_states()

return True


Expand All @@ -161,10 +208,10 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
return unload_ok


async def update_listener(hass, entry):
async def update_listener(hass: HomeAssistant, entry: ConfigEntry):
"""Update when config_entry options update."""
if entry.options[CONF_UPDATE_INTERVAL]:
coordinator = hass.data[DOMAIN][entry.entry_id].get("coordinator")
coordinator = hass.data[DOMAIN][entry.entry_id]["coordinator"]
new_update_interval = timedelta(seconds=entry.options[CONF_UPDATE_INTERVAL])
coordinator.update_interval = new_update_interval
coordinator.original_update_interval = new_update_interval
Expand Down
4 changes: 2 additions & 2 deletions custom_components/tahoma/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@
async def async_setup_entry(hass, entry, async_add_entities):
"""Set up the TaHoma sensors from a config entry."""
data = hass.data[DOMAIN][entry.entry_id]
coordinator = data.get("coordinator")
coordinator = data["coordinator"]

entities = [
TahomaAlarmControlPanel(device.deviceurl, coordinator)
for device in data.get("entities").get(ALARM_CONTROL_PANEL)
for device in data["entities"].get(ALARM_CONTROL_PANEL)
]
async_add_entities(entities)

Expand Down
4 changes: 2 additions & 2 deletions custom_components/tahoma/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@
async def async_setup_entry(hass, entry, async_add_entities):
"""Set up the TaHoma sensors from a config entry."""
data = hass.data[DOMAIN][entry.entry_id]
coordinator = data.get("coordinator")
coordinator = data["coordinator"]

entities = [
TahomaBinarySensor(device.deviceurl, coordinator)
for device in data.get("entities").get(BINARY_SENSOR)
for device in data["entities"].get(BINARY_SENSOR)
]
async_add_entities(entities)

Expand Down
8 changes: 6 additions & 2 deletions custom_components/tahoma/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,26 @@
from .climate_devices.atlantic_electrical_heater import AtlanticElectricalHeater
from .climate_devices.dimmer_exterior_heating import DimmerExteriorHeating
from .climate_devices.somfy_thermostat import SomfyThermostat
from .climate_devices.stateless_exterior_heating import StatelessExteriorHeating
from .const import DOMAIN

TYPE = {
"AtlanticElectricalHeater": AtlanticElectricalHeater,
"SomfyThermostat": SomfyThermostat,
"DimmerExteriorHeating": DimmerExteriorHeating,
"StatelessExteriorHeating": StatelessExteriorHeating,
}

SERVICE_CLIMATE_MY_POSITION = "set_climate_my_position"


async def async_setup_entry(hass, entry, async_add_entities):
"""Set up the TaHoma climate from a config entry."""

data = hass.data[DOMAIN][entry.entry_id]
coordinator = data.get("coordinator")
coordinator = data["coordinator"]

climate_devices = [device for device in data.get("entities").get(CLIMATE)]
climate_devices = [device for device in data["entities"].get(CLIMATE)]

entities = [
TYPE[device.widget](device.deviceurl, coordinator)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""Support for Stateless Exterior Heating device."""
import logging
from typing import List, Optional

from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import (
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
SUPPORT_PRESET_MODE,
)
from homeassistant.const import TEMP_CELSIUS

from ..tahoma_device import TahomaDevice

_LOGGER = logging.getLogger(__name__)

COMMAND_MY = "my"
COMMAND_OFF = "off"
COMMAND_ON = "on"

PRESET_MY = "My"


class StatelessExteriorHeating(TahomaDevice, ClimateEntity):
"""Representation of TaHoma Stateless Exterior Heating device."""

@property
def temperature_unit(self) -> Optional[str]:
"""Return the unit of measurement used by the platform."""
return TEMP_CELSIUS # Not used but climate devices need a recognized temperature unit...

@property
def supported_features(self) -> int:
"""Return the list of supported features."""
return SUPPORT_PRESET_MODE

@property
def preset_mode(self) -> Optional[str]:
"""Return the current preset mode, e.g., home, away, temp."""
return None

@property
def preset_modes(self) -> Optional[List[str]]:
"""Return a list of available preset modes."""
return [PRESET_MY]

async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set new preset mode."""
if preset_mode in PRESET_MY:
await self.async_execute_command(COMMAND_MY)
else:
_LOGGER.error(
"Invalid preset mode %s for device %s", preset_mode, self.name
)

@property
def hvac_mode(self) -> Optional[str]:
"""Return hvac operation ie. heat, cool mode."""
return None

@property
def hvac_modes(self) -> List[str]:
"""Return the list of available hvac operation modes."""
return [HVAC_MODE_OFF, HVAC_MODE_HEAT]

async def async_set_hvac_mode(self, hvac_mode: str) -> None:
"""Set new target hvac mode."""
if hvac_mode == HVAC_MODE_HEAT:
await self.async_execute_command(COMMAND_ON)
else:
await self.async_execute_command(COMMAND_OFF)
4 changes: 3 additions & 1 deletion custom_components/tahoma/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@
# Used to map the Somfy widget and ui_class to the Home Assistant platform
TAHOMA_TYPES = {
"AdjustableSlatsRollerShutter": COVER,
"Alarm": ALARM_CONTROL_PANEL,
"AirFlowSensor": BINARY_SENSOR, # widgetName, uiClass is AirSensor (sensor)
"AirSensor": SENSOR,
"Alarm": ALARM_CONTROL_PANEL,
"AtlanticElectricalHeater": CLIMATE, # widgetName, uiClass is HeatingSystem (not supported)
"Awning": COVER,
"CarButtonSensor": BINARY_SENSOR,
"ConsumptionSensor": SENSOR,
"ContactSensor": BINARY_SENSOR,
"Curtain": COVER,
"DimmerExteriorHeating": CLIMATE, # widgetName, uiClass is ExteriorHeatingSystem (not supported)
"DomesticHotWaterTank": SWITCH, # widgetName, uiClass is WaterHeatingSystem (not supported)
"DoorLock": LOCK,
"ElectricitySensor": SENSOR,
"ExteriorScreen": COVER,
Expand All @@ -56,6 +57,7 @@
"SirenStatus": BINARY_SENSOR, # widgetName, uiClass is Siren (switch)
"SmokeSensor": BINARY_SENSOR,
"SomfyThermostat": CLIMATE, # widgetName, uiClass is HeatingSystem (not supported)
"StatelessExteriorHeating": CLIMATE, # widgetName, uiClass is ExteriorHeatingSystem.
"SunIntensitySensor": SENSOR,
"SunSensor": SENSOR,
"SwimmingPool": SWITCH,
Expand Down
Loading