Remove TaHoma integration (#62607)
This commit is contained in:
parent
40f1d53475
commit
c3917fc250
12 changed files with 0 additions and 895 deletions
|
@ -1072,7 +1072,6 @@ omit =
|
|||
homeassistant/components/system_bridge/sensor.py
|
||||
homeassistant/components/systemmonitor/sensor.py
|
||||
homeassistant/components/tado/*
|
||||
homeassistant/components/tahoma/*
|
||||
homeassistant/components/tank_utility/sensor.py
|
||||
homeassistant/components/tankerkoenig/*
|
||||
homeassistant/components/tapsaff/binary_sensor.py
|
||||
|
|
|
@ -910,7 +910,6 @@ homeassistant/components/tado/* @michaelarnauts @noltari
|
|||
tests/components/tado/* @michaelarnauts @noltari
|
||||
homeassistant/components/tag/* @balloob @dmulcahey
|
||||
tests/components/tag/* @balloob @dmulcahey
|
||||
homeassistant/components/tahoma/* @philklei
|
||||
homeassistant/components/tailscale/* @frenck
|
||||
tests/components/tailscale/* @frenck
|
||||
homeassistant/components/tankerkoenig/* @guillempages
|
||||
|
|
|
@ -1,149 +0,0 @@
|
|||
"""Support for Tahoma devices."""
|
||||
from collections import defaultdict
|
||||
import logging
|
||||
|
||||
from requests.exceptions import RequestException
|
||||
from tahoma_api import Action, TahomaApi
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import CONF_EXCLUDE, CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.helpers import config_validation as cv, discovery
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DOMAIN = "tahoma"
|
||||
|
||||
TAHOMA_ID_FORMAT = "{}_{}"
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
DOMAIN: vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_USERNAME): cv.string,
|
||||
vol.Required(CONF_PASSWORD): cv.string,
|
||||
vol.Optional(CONF_EXCLUDE, default=[]): vol.All(
|
||||
cv.ensure_list, [cv.string]
|
||||
),
|
||||
}
|
||||
)
|
||||
},
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
PLATFORMS = ["binary_sensor", "cover", "lock", "scene", "sensor", "switch"]
|
||||
|
||||
TAHOMA_TYPES = {
|
||||
"io:AwningValanceIOComponent": "cover",
|
||||
"io:ExteriorVenetianBlindIOComponent": "cover",
|
||||
"io:DiscreteGarageOpenerIOComponent": "cover",
|
||||
"io:DiscreteGarageOpenerWithPartialPositionIOComponent": "cover",
|
||||
"io:HorizontalAwningIOComponent": "cover",
|
||||
"io:GarageOpenerIOComponent": "cover",
|
||||
"io:LightIOSystemSensor": "sensor",
|
||||
"io:OnOffIOComponent": "switch",
|
||||
"io:OnOffLightIOComponent": "switch",
|
||||
"io:RollerShutterGenericIOComponent": "cover",
|
||||
"io:RollerShutterUnoIOComponent": "cover",
|
||||
"io:RollerShutterVeluxIOComponent": "cover",
|
||||
"io:RollerShutterWithLowSpeedManagementIOComponent": "cover",
|
||||
"io:SomfyBasicContactIOSystemSensor": "sensor",
|
||||
"io:SomfyContactIOSystemSensor": "sensor",
|
||||
"io:TemperatureIOSystemSensor": "sensor",
|
||||
"io:VerticalExteriorAwningIOComponent": "cover",
|
||||
"io:VerticalInteriorBlindVeluxIOComponent": "cover",
|
||||
"io:WindowOpenerVeluxIOComponent": "cover",
|
||||
"opendoors:OpenDoorsSmartLockComponent": "lock",
|
||||
"rtds:RTDSContactSensor": "sensor",
|
||||
"rtds:RTDSMotionSensor": "sensor",
|
||||
"rtds:RTDSSmokeSensor": "smoke",
|
||||
"rts:BlindRTSComponent": "cover",
|
||||
"rts:CurtainRTSComponent": "cover",
|
||||
"rts:DualCurtainRTSComponent": "cover",
|
||||
"rts:ExteriorVenetianBlindRTSComponent": "cover",
|
||||
"rts:GarageDoor4TRTSComponent": "switch",
|
||||
"rts:LightRTSComponent": "switch",
|
||||
"rts:RollerShutterRTSComponent": "cover",
|
||||
"rts:OnOffRTSComponent": "switch",
|
||||
"rts:VenetianBlindRTSComponent": "cover",
|
||||
"somfythermostat:SomfyThermostatTemperatureSensor": "sensor",
|
||||
"somfythermostat:SomfyThermostatHumiditySensor": "sensor",
|
||||
"zwave:OnOffLightZWaveComponent": "switch",
|
||||
}
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
"""Set up Tahoma integration."""
|
||||
|
||||
conf = config[DOMAIN]
|
||||
username = conf.get(CONF_USERNAME)
|
||||
password = conf.get(CONF_PASSWORD)
|
||||
exclude = conf.get(CONF_EXCLUDE)
|
||||
try:
|
||||
api = TahomaApi(username, password)
|
||||
except RequestException:
|
||||
_LOGGER.exception("Error when trying to log in to the Tahoma API")
|
||||
return False
|
||||
|
||||
try:
|
||||
api.get_setup()
|
||||
devices = api.get_devices()
|
||||
scenes = api.get_action_groups()
|
||||
except RequestException:
|
||||
_LOGGER.exception("Error when getting devices from the Tahoma API")
|
||||
return False
|
||||
|
||||
hass.data[DOMAIN] = {"controller": api, "devices": defaultdict(list), "scenes": []}
|
||||
|
||||
for device in devices:
|
||||
_device = api.get_device(device)
|
||||
if all(ext not in _device.type for ext in exclude):
|
||||
device_type = map_tahoma_device(_device)
|
||||
if device_type is None:
|
||||
_LOGGER.warning(
|
||||
"Unsupported type %s for Tahoma device %s",
|
||||
_device.type,
|
||||
_device.label,
|
||||
)
|
||||
continue
|
||||
hass.data[DOMAIN]["devices"][device_type].append(_device)
|
||||
|
||||
for scene in scenes:
|
||||
hass.data[DOMAIN]["scenes"].append(scene)
|
||||
|
||||
for platform in PLATFORMS:
|
||||
discovery.load_platform(hass, platform, DOMAIN, {}, config)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def map_tahoma_device(tahoma_device):
|
||||
"""Map Tahoma device types to Home Assistant platforms."""
|
||||
return TAHOMA_TYPES.get(tahoma_device.type)
|
||||
|
||||
|
||||
class TahomaDevice(Entity):
|
||||
"""Representation of a Tahoma device entity."""
|
||||
|
||||
def __init__(self, tahoma_device, controller):
|
||||
"""Initialize the device."""
|
||||
self.tahoma_device = tahoma_device
|
||||
self.controller = controller
|
||||
self._name = self.tahoma_device.label
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the device."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return the state attributes of the device."""
|
||||
return {"tahoma_device_id": self.tahoma_device.url}
|
||||
|
||||
def apply_action(self, cmd_name, *args):
|
||||
"""Apply Action to Device."""
|
||||
|
||||
action = Action(self.tahoma_device.url)
|
||||
action.add_command(cmd_name, *args)
|
||||
self.controller.apply_actions("HomeAssistant", [action])
|
|
@ -1,99 +0,0 @@
|
|||
"""Support for Tahoma binary sensors."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDeviceClass,
|
||||
BinarySensorEntity,
|
||||
)
|
||||
from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_OFF, STATE_ON
|
||||
|
||||
from . import DOMAIN as TAHOMA_DOMAIN, TahomaDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=120)
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up Tahoma controller devices."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
_LOGGER.debug("Setup Tahoma Binary sensor platform")
|
||||
controller = hass.data[TAHOMA_DOMAIN]["controller"]
|
||||
devices = []
|
||||
for device in hass.data[TAHOMA_DOMAIN]["devices"]["smoke"]:
|
||||
devices.append(TahomaBinarySensor(device, controller))
|
||||
add_entities(devices, True)
|
||||
|
||||
|
||||
class TahomaBinarySensor(TahomaDevice, BinarySensorEntity):
|
||||
"""Representation of a Tahoma Binary Sensor."""
|
||||
|
||||
def __init__(self, tahoma_device, controller):
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(tahoma_device, controller)
|
||||
|
||||
self._state = None
|
||||
self._icon = None
|
||||
self._battery = None
|
||||
self._available = False
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return the state of the sensor."""
|
||||
return bool(self._state == STATE_ON)
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of the device."""
|
||||
if self.tahoma_device.type == "rtds:RTDSSmokeSensor":
|
||||
return BinarySensorDeviceClass.SMOKE
|
||||
return None
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Icon for device by its type."""
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return the device state attributes."""
|
||||
attr = {}
|
||||
if (super_attr := super().extra_state_attributes) is not None:
|
||||
attr.update(super_attr)
|
||||
|
||||
if self._battery is not None:
|
||||
attr[ATTR_BATTERY_LEVEL] = self._battery
|
||||
return attr
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return True if entity is available."""
|
||||
return self._available
|
||||
|
||||
def update(self):
|
||||
"""Update the state."""
|
||||
self.controller.get_states([self.tahoma_device])
|
||||
if self.tahoma_device.type == "rtds:RTDSSmokeSensor":
|
||||
if self.tahoma_device.active_states["core:SmokeState"] == "notDetected":
|
||||
self._state = STATE_OFF
|
||||
else:
|
||||
self._state = STATE_ON
|
||||
|
||||
if "core:SensorDefectState" in self.tahoma_device.active_states:
|
||||
# 'lowBattery' for low battery warning. 'dead' for not available.
|
||||
self._battery = self.tahoma_device.active_states["core:SensorDefectState"]
|
||||
self._available = bool(self._battery != "dead")
|
||||
else:
|
||||
self._battery = None
|
||||
self._available = True
|
||||
|
||||
if self._state == STATE_ON:
|
||||
self._icon = "mdi:fire"
|
||||
elif self._battery == "lowBattery":
|
||||
self._icon = "mdi:battery-alert"
|
||||
else:
|
||||
self._icon = None
|
||||
|
||||
_LOGGER.debug("Update %s, state: %s", self._name, self._state)
|
|
@ -1,248 +0,0 @@
|
|||
"""Support for Tahoma cover - shutters etc."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from homeassistant.components.cover import ATTR_POSITION, CoverDeviceClass, CoverEntity
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from . import DOMAIN as TAHOMA_DOMAIN, TahomaDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_MEM_POS = "memorized_position"
|
||||
ATTR_RSSI_LEVEL = "rssi_level"
|
||||
ATTR_LOCK_START_TS = "lock_start_ts"
|
||||
ATTR_LOCK_END_TS = "lock_end_ts"
|
||||
ATTR_LOCK_LEVEL = "lock_level"
|
||||
ATTR_LOCK_ORIG = "lock_originator"
|
||||
|
||||
HORIZONTAL_AWNING = "io:HorizontalAwningIOComponent"
|
||||
|
||||
TAHOMA_DEVICE_CLASSES = {
|
||||
HORIZONTAL_AWNING: CoverDeviceClass.AWNING,
|
||||
"io:AwningValanceIOComponent": CoverDeviceClass.AWNING,
|
||||
"io:DiscreteGarageOpenerWithPartialPositionIOComponent": CoverDeviceClass.GARAGE,
|
||||
"io:DiscreteGarageOpenerIOComponent": CoverDeviceClass.GARAGE,
|
||||
"io:ExteriorVenetianBlindIOComponent": CoverDeviceClass.BLIND,
|
||||
"io:GarageOpenerIOComponent": CoverDeviceClass.GARAGE,
|
||||
"io:RollerShutterGenericIOComponent": CoverDeviceClass.SHUTTER,
|
||||
"io:RollerShutterUnoIOComponent": CoverDeviceClass.SHUTTER,
|
||||
"io:RollerShutterVeluxIOComponent": CoverDeviceClass.SHUTTER,
|
||||
"io:RollerShutterWithLowSpeedManagementIOComponent": CoverDeviceClass.SHUTTER,
|
||||
"io:VerticalExteriorAwningIOComponent": CoverDeviceClass.AWNING,
|
||||
"io:VerticalInteriorBlindVeluxIOComponent": CoverDeviceClass.BLIND,
|
||||
"io:WindowOpenerVeluxIOComponent": CoverDeviceClass.WINDOW,
|
||||
"rts:BlindRTSComponent": CoverDeviceClass.BLIND,
|
||||
"rts:CurtainRTSComponent": CoverDeviceClass.CURTAIN,
|
||||
"rts:DualCurtainRTSComponent": CoverDeviceClass.CURTAIN,
|
||||
"rts:ExteriorVenetianBlindRTSComponent": CoverDeviceClass.BLIND,
|
||||
"rts:RollerShutterRTSComponent": CoverDeviceClass.SHUTTER,
|
||||
"rts:VenetianBlindRTSComponent": CoverDeviceClass.BLIND,
|
||||
}
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Tahoma covers."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
controller = hass.data[TAHOMA_DOMAIN]["controller"]
|
||||
devices = []
|
||||
for device in hass.data[TAHOMA_DOMAIN]["devices"]["cover"]:
|
||||
devices.append(TahomaCover(device, controller))
|
||||
add_entities(devices, True)
|
||||
|
||||
|
||||
class TahomaCover(TahomaDevice, CoverEntity):
|
||||
"""Representation a Tahoma Cover."""
|
||||
|
||||
def __init__(self, tahoma_device, controller):
|
||||
"""Initialize the device."""
|
||||
super().__init__(tahoma_device, controller)
|
||||
|
||||
self._closure = 0
|
||||
# 100 equals open
|
||||
self._position = 100
|
||||
self._closed = False
|
||||
self._rssi_level = None
|
||||
self._icon = None
|
||||
# Can be 0 and bigger
|
||||
self._lock_timer = 0
|
||||
self._lock_start_ts = None
|
||||
self._lock_end_ts = None
|
||||
# Can be 'comfortLevel1', 'comfortLevel2', 'comfortLevel3',
|
||||
# 'comfortLevel4', 'environmentProtection', 'humanProtection',
|
||||
# 'userLevel1', 'userLevel2'
|
||||
self._lock_level = None
|
||||
# Can be 'LSC', 'SAAC', 'SFC', 'UPS', 'externalGateway', 'localUser',
|
||||
# 'myself', 'rain', 'security', 'temperature', 'timer', 'user', 'wind'
|
||||
self._lock_originator = None
|
||||
|
||||
def update(self):
|
||||
"""Update method."""
|
||||
self.controller.get_states([self.tahoma_device])
|
||||
|
||||
# For vertical covers
|
||||
self._closure = self.tahoma_device.active_states.get("core:ClosureState")
|
||||
# For horizontal covers
|
||||
if self._closure is None:
|
||||
self._closure = self.tahoma_device.active_states.get("core:DeploymentState")
|
||||
|
||||
# For all, if available
|
||||
if "core:PriorityLockTimerState" in self.tahoma_device.active_states:
|
||||
old_lock_timer = self._lock_timer
|
||||
self._lock_timer = self.tahoma_device.active_states[
|
||||
"core:PriorityLockTimerState"
|
||||
]
|
||||
# Derive timestamps from _lock_timer, only if not already set or
|
||||
# something has changed
|
||||
if self._lock_timer > 0:
|
||||
_LOGGER.debug("Update %s, lock_timer: %d", self._name, self._lock_timer)
|
||||
if self._lock_start_ts is None:
|
||||
self._lock_start_ts = utcnow()
|
||||
if self._lock_end_ts is None or old_lock_timer != self._lock_timer:
|
||||
self._lock_end_ts = utcnow() + timedelta(seconds=self._lock_timer)
|
||||
else:
|
||||
self._lock_start_ts = None
|
||||
self._lock_end_ts = None
|
||||
else:
|
||||
self._lock_timer = 0
|
||||
self._lock_start_ts = None
|
||||
self._lock_end_ts = None
|
||||
|
||||
self._lock_level = self.tahoma_device.active_states.get(
|
||||
"io:PriorityLockLevelState"
|
||||
)
|
||||
|
||||
self._lock_originator = self.tahoma_device.active_states.get(
|
||||
"io:PriorityLockOriginatorState"
|
||||
)
|
||||
|
||||
self._rssi_level = self.tahoma_device.active_states.get("core:RSSILevelState")
|
||||
|
||||
# Define which icon to use
|
||||
if self._lock_timer > 0:
|
||||
if self._lock_originator == "wind":
|
||||
self._icon = "mdi:weather-windy"
|
||||
else:
|
||||
self._icon = "mdi:lock-alert"
|
||||
else:
|
||||
self._icon = None
|
||||
|
||||
# Define current position.
|
||||
# _position: 0 is closed, 100 is fully open.
|
||||
# 'core:ClosureState': 100 is closed, 0 is fully open.
|
||||
if self._closure is not None:
|
||||
if self.tahoma_device.type == HORIZONTAL_AWNING:
|
||||
self._position = self._closure
|
||||
else:
|
||||
self._position = 100 - self._closure
|
||||
if self._position <= 5:
|
||||
self._position = 0
|
||||
if self._position >= 95:
|
||||
self._position = 100
|
||||
self._closed = self._position == 0
|
||||
else:
|
||||
self._position = None
|
||||
if "core:OpenClosedState" in self.tahoma_device.active_states:
|
||||
self._closed = (
|
||||
self.tahoma_device.active_states["core:OpenClosedState"] == "closed"
|
||||
)
|
||||
if "core:OpenClosedPartialState" in self.tahoma_device.active_states:
|
||||
self._closed = (
|
||||
self.tahoma_device.active_states["core:OpenClosedPartialState"]
|
||||
== "closed"
|
||||
)
|
||||
else:
|
||||
self._closed = False
|
||||
|
||||
_LOGGER.debug("Update %s, position: %d", self._name, self._position)
|
||||
|
||||
@property
|
||||
def current_cover_position(self):
|
||||
"""Return current position of cover."""
|
||||
return self._position
|
||||
|
||||
def set_cover_position(self, **kwargs):
|
||||
"""Move the cover to a specific position."""
|
||||
if self.tahoma_device.type == "io:WindowOpenerVeluxIOComponent":
|
||||
command = "setClosure"
|
||||
else:
|
||||
command = "setPosition"
|
||||
|
||||
if self.tahoma_device.type == HORIZONTAL_AWNING:
|
||||
self.apply_action(command, kwargs.get(ATTR_POSITION, 0))
|
||||
else:
|
||||
self.apply_action(command, 100 - kwargs.get(ATTR_POSITION, 0))
|
||||
|
||||
@property
|
||||
def is_closed(self):
|
||||
"""Return if the cover is closed."""
|
||||
return self._closed
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of the device."""
|
||||
return TAHOMA_DEVICE_CLASSES.get(self.tahoma_device.type)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return the device state attributes."""
|
||||
attr = {}
|
||||
if (super_attr := super().extra_state_attributes) is not None:
|
||||
attr.update(super_attr)
|
||||
|
||||
if "core:Memorized1PositionState" in self.tahoma_device.active_states:
|
||||
attr[ATTR_MEM_POS] = self.tahoma_device.active_states[
|
||||
"core:Memorized1PositionState"
|
||||
]
|
||||
if self._rssi_level is not None:
|
||||
attr[ATTR_RSSI_LEVEL] = self._rssi_level
|
||||
if self._lock_start_ts is not None:
|
||||
attr[ATTR_LOCK_START_TS] = self._lock_start_ts.isoformat()
|
||||
if self._lock_end_ts is not None:
|
||||
attr[ATTR_LOCK_END_TS] = self._lock_end_ts.isoformat()
|
||||
if self._lock_level is not None:
|
||||
attr[ATTR_LOCK_LEVEL] = self._lock_level
|
||||
if self._lock_originator is not None:
|
||||
attr[ATTR_LOCK_ORIG] = self._lock_originator
|
||||
return attr
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon to use in the frontend, if any."""
|
||||
return self._icon
|
||||
|
||||
def open_cover(self, **kwargs):
|
||||
"""Open the cover."""
|
||||
self.apply_action("open")
|
||||
|
||||
def close_cover(self, **kwargs):
|
||||
"""Close the cover."""
|
||||
self.apply_action("close")
|
||||
|
||||
def stop_cover(self, **kwargs):
|
||||
"""Stop the cover."""
|
||||
if (
|
||||
self.tahoma_device.type
|
||||
== "io:RollerShutterWithLowSpeedManagementIOComponent"
|
||||
):
|
||||
self.apply_action("setPosition", "secured")
|
||||
elif self.tahoma_device.type in {
|
||||
"io:ExteriorVenetianBlindIOComponent",
|
||||
"rts:BlindRTSComponent",
|
||||
"rts:DualCurtainRTSComponent",
|
||||
"rts:ExteriorVenetianBlindRTSComponent",
|
||||
"rts:VenetianBlindRTSComponent",
|
||||
}:
|
||||
self.apply_action("my")
|
||||
elif self.tahoma_device.type in {
|
||||
HORIZONTAL_AWNING,
|
||||
"io:AwningValanceIOComponent",
|
||||
"io:RollerShutterGenericIOComponent",
|
||||
"io:VerticalExteriorAwningIOComponent",
|
||||
"io:VerticalInteriorBlindVeluxIOComponent",
|
||||
"io:WindowOpenerVeluxIOComponent",
|
||||
}:
|
||||
self.apply_action("stop")
|
||||
else:
|
||||
self.apply_action("stopIdentify")
|
|
@ -1,88 +0,0 @@
|
|||
"""Support for Tahoma lock."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from homeassistant.components.lock import LockEntity
|
||||
from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_LOCKED, STATE_UNLOCKED
|
||||
|
||||
from . import DOMAIN as TAHOMA_DOMAIN, TahomaDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=120)
|
||||
TAHOMA_STATE_LOCKED = "locked"
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Tahoma lock."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
controller = hass.data[TAHOMA_DOMAIN]["controller"]
|
||||
devices = []
|
||||
for device in hass.data[TAHOMA_DOMAIN]["devices"]["lock"]:
|
||||
devices.append(TahomaLock(device, controller))
|
||||
add_entities(devices, True)
|
||||
|
||||
|
||||
class TahomaLock(TahomaDevice, LockEntity):
|
||||
"""Representation a Tahoma lock."""
|
||||
|
||||
def __init__(self, tahoma_device, controller):
|
||||
"""Initialize the device."""
|
||||
super().__init__(tahoma_device, controller)
|
||||
self._lock_status = None
|
||||
self._available = False
|
||||
self._battery_level = None
|
||||
self._name = None
|
||||
|
||||
def update(self):
|
||||
"""Update method."""
|
||||
self.controller.get_states([self.tahoma_device])
|
||||
self._battery_level = self.tahoma_device.active_states["core:BatteryState"]
|
||||
self._name = self.tahoma_device.active_states["core:NameState"]
|
||||
if (
|
||||
self.tahoma_device.active_states.get("core:LockedUnlockedState")
|
||||
== TAHOMA_STATE_LOCKED
|
||||
):
|
||||
self._lock_status = STATE_LOCKED
|
||||
else:
|
||||
self._lock_status = STATE_UNLOCKED
|
||||
self._available = (
|
||||
self.tahoma_device.active_states.get("core:AvailabilityState")
|
||||
== "available"
|
||||
)
|
||||
|
||||
def unlock(self, **kwargs):
|
||||
"""Unlock method."""
|
||||
_LOGGER.debug("Unlocking %s", self._name)
|
||||
self.apply_action("unlock")
|
||||
|
||||
def lock(self, **kwargs):
|
||||
"""Lock method."""
|
||||
_LOGGER.debug("Locking %s", self._name)
|
||||
self.apply_action("lock")
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the lock."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return True if the lock is available."""
|
||||
return self._available
|
||||
|
||||
@property
|
||||
def is_locked(self):
|
||||
"""Return True if the lock is locked."""
|
||||
return self._lock_status == STATE_LOCKED
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return the lock state attributes."""
|
||||
attr = {
|
||||
ATTR_BATTERY_LEVEL: self._battery_level,
|
||||
}
|
||||
if (super_attr := super().extra_state_attributes) is not None:
|
||||
attr.update(super_attr)
|
||||
return attr
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"domain": "tahoma",
|
||||
"name": "Tahoma",
|
||||
"documentation": "https://www.home-assistant.io/integrations/tahoma",
|
||||
"requirements": ["tahoma-api==0.0.16"],
|
||||
"codeowners": ["@philklei"],
|
||||
"iot_class": "cloud_polling"
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
"""Support for Tahoma scenes."""
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.scene import Scene
|
||||
|
||||
from . import DOMAIN as TAHOMA_DOMAIN
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Tahoma scenes."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
controller = hass.data[TAHOMA_DOMAIN]["controller"]
|
||||
scenes = [
|
||||
TahomaScene(scene, controller) for scene in hass.data[TAHOMA_DOMAIN]["scenes"]
|
||||
]
|
||||
|
||||
add_entities(scenes, True)
|
||||
|
||||
|
||||
class TahomaScene(Scene):
|
||||
"""Representation of a Tahoma scene entity."""
|
||||
|
||||
def __init__(self, tahoma_scene, controller):
|
||||
"""Initialize the scene."""
|
||||
self.tahoma_scene = tahoma_scene
|
||||
self.controller = controller
|
||||
self._name = self.tahoma_scene.name
|
||||
|
||||
def activate(self, **kwargs: Any) -> None:
|
||||
"""Activate the scene."""
|
||||
self.controller.launch_action_group(self.tahoma_scene.oid)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the scene."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return the state attributes of the scene."""
|
||||
return {"tahoma_scene_oid": self.tahoma_scene.oid}
|
|
@ -1,132 +0,0 @@
|
|||
"""Support for Tahoma sensors."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from homeassistant.components.sensor import SensorEntity
|
||||
from homeassistant.const import ATTR_BATTERY_LEVEL, LIGHT_LUX, PERCENTAGE, TEMP_CELSIUS
|
||||
|
||||
from . import DOMAIN as TAHOMA_DOMAIN, TahomaDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=60)
|
||||
|
||||
ATTR_RSSI_LEVEL = "rssi_level"
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up Tahoma controller devices."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
controller = hass.data[TAHOMA_DOMAIN]["controller"]
|
||||
devices = []
|
||||
for device in hass.data[TAHOMA_DOMAIN]["devices"]["sensor"]:
|
||||
devices.append(TahomaSensor(device, controller))
|
||||
add_entities(devices, True)
|
||||
|
||||
|
||||
class TahomaSensor(TahomaDevice, SensorEntity):
|
||||
"""Representation of a Tahoma Sensor."""
|
||||
|
||||
def __init__(self, tahoma_device, controller):
|
||||
"""Initialize the sensor."""
|
||||
self.current_value = None
|
||||
self._available = False
|
||||
super().__init__(tahoma_device, controller)
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self.current_value
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit of measurement of this entity, if any."""
|
||||
if self.tahoma_device.type == "io:TemperatureIOSystemSensor":
|
||||
return TEMP_CELSIUS
|
||||
if self.tahoma_device.type == "io:SomfyContactIOSystemSensor":
|
||||
return None
|
||||
if self.tahoma_device.type == "io:SomfyBasicContactIOSystemSensor":
|
||||
return None
|
||||
if self.tahoma_device.type == "io:LightIOSystemSensor":
|
||||
return LIGHT_LUX
|
||||
if self.tahoma_device.type == "Humidity Sensor":
|
||||
return PERCENTAGE
|
||||
if self.tahoma_device.type == "rtds:RTDSContactSensor":
|
||||
return None
|
||||
if self.tahoma_device.type == "rtds:RTDSMotionSensor":
|
||||
return None
|
||||
if (
|
||||
self.tahoma_device.type
|
||||
== "somfythermostat:SomfyThermostatTemperatureSensor"
|
||||
):
|
||||
return TEMP_CELSIUS
|
||||
if self.tahoma_device.type == "somfythermostat:SomfyThermostatHumiditySensor":
|
||||
return PERCENTAGE
|
||||
|
||||
def update(self):
|
||||
"""Update the state."""
|
||||
self.controller.get_states([self.tahoma_device])
|
||||
if self.tahoma_device.type == "io:LightIOSystemSensor":
|
||||
self.current_value = self.tahoma_device.active_states["core:LuminanceState"]
|
||||
self._available = bool(
|
||||
self.tahoma_device.active_states.get("core:StatusState") == "available"
|
||||
)
|
||||
if self.tahoma_device.type == "io:SomfyContactIOSystemSensor":
|
||||
self.current_value = self.tahoma_device.active_states["core:ContactState"]
|
||||
self._available = bool(
|
||||
self.tahoma_device.active_states.get("core:StatusState") == "available"
|
||||
)
|
||||
if self.tahoma_device.type == "io:SomfyBasicContactIOSystemSensor":
|
||||
self.current_value = self.tahoma_device.active_states["core:ContactState"]
|
||||
self._available = bool(
|
||||
self.tahoma_device.active_states.get("core:StatusState") == "available"
|
||||
)
|
||||
if self.tahoma_device.type == "rtds:RTDSContactSensor":
|
||||
self.current_value = self.tahoma_device.active_states["core:ContactState"]
|
||||
self._available = True
|
||||
if self.tahoma_device.type == "rtds:RTDSMotionSensor":
|
||||
self.current_value = self.tahoma_device.active_states["core:OccupancyState"]
|
||||
self._available = True
|
||||
if self.tahoma_device.type == "io:TemperatureIOSystemSensor":
|
||||
self.current_value = round(
|
||||
float(self.tahoma_device.active_states["core:TemperatureState"]), 1
|
||||
)
|
||||
self._available = True
|
||||
if (
|
||||
self.tahoma_device.type
|
||||
== "somfythermostat:SomfyThermostatTemperatureSensor"
|
||||
):
|
||||
self.current_value = float(
|
||||
f"{self.tahoma_device.active_states['core:TemperatureState']:.2f}"
|
||||
)
|
||||
self._available = True
|
||||
if self.tahoma_device.type == "somfythermostat:SomfyThermostatHumiditySensor":
|
||||
self.current_value = float(
|
||||
f"{self.tahoma_device.active_states['core:RelativeHumidityState']:.2f}"
|
||||
)
|
||||
self._available = True
|
||||
|
||||
_LOGGER.debug("Update %s, value: %d", self._name, self.current_value)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return the device state attributes."""
|
||||
attr = {}
|
||||
if (super_attr := super().extra_state_attributes) is not None:
|
||||
attr.update(super_attr)
|
||||
|
||||
if "core:RSSILevelState" in self.tahoma_device.active_states:
|
||||
attr[ATTR_RSSI_LEVEL] = self.tahoma_device.active_states[
|
||||
"core:RSSILevelState"
|
||||
]
|
||||
if "core:SensorDefectState" in self.tahoma_device.active_states:
|
||||
attr[ATTR_BATTERY_LEVEL] = self.tahoma_device.active_states[
|
||||
"core:SensorDefectState"
|
||||
]
|
||||
return attr
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return True if entity is available."""
|
||||
return self._available
|
|
@ -1,123 +0,0 @@
|
|||
"""Support for Tahoma switches."""
|
||||
import logging
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.const import STATE_OFF, STATE_ON
|
||||
|
||||
from . import DOMAIN as TAHOMA_DOMAIN, TahomaDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_RSSI_LEVEL = "rssi_level"
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up Tahoma switches."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
controller = hass.data[TAHOMA_DOMAIN]["controller"]
|
||||
devices = []
|
||||
for switch in hass.data[TAHOMA_DOMAIN]["devices"]["switch"]:
|
||||
devices.append(TahomaSwitch(switch, controller))
|
||||
add_entities(devices, True)
|
||||
|
||||
|
||||
class TahomaSwitch(TahomaDevice, SwitchEntity):
|
||||
"""Representation a Tahoma Switch."""
|
||||
|
||||
def __init__(self, tahoma_device, controller):
|
||||
"""Initialize the switch."""
|
||||
super().__init__(tahoma_device, controller)
|
||||
self._state = STATE_OFF
|
||||
self._skip_update = False
|
||||
self._available = False
|
||||
|
||||
def update(self):
|
||||
"""Update method."""
|
||||
# Postpone the immediate state check for changes that take time.
|
||||
if self._skip_update:
|
||||
self._skip_update = False
|
||||
return
|
||||
|
||||
self.controller.get_states([self.tahoma_device])
|
||||
|
||||
if self.tahoma_device.type == "io:OnOffLightIOComponent":
|
||||
if self.tahoma_device.active_states.get("core:OnOffState") == "on":
|
||||
self._state = STATE_ON
|
||||
else:
|
||||
self._state = STATE_OFF
|
||||
|
||||
if self.tahoma_device.type == "zwave:OnOffLightZWaveComponent":
|
||||
if self.tahoma_device.active_states.get("core:OnOffState") == "on":
|
||||
self._state = STATE_ON
|
||||
else:
|
||||
self._state = STATE_OFF
|
||||
|
||||
# A RTS power socket doesn't have a feedback channel,
|
||||
# so we must assume the socket is available.
|
||||
if self.tahoma_device.type == "rts:OnOffRTSComponent":
|
||||
self._available = True
|
||||
elif self.tahoma_device.type == "zwave:OnOffLightZWaveComponent":
|
||||
self._available = True
|
||||
else:
|
||||
self._available = bool(
|
||||
self.tahoma_device.active_states.get("core:StatusState") == "available"
|
||||
)
|
||||
|
||||
_LOGGER.debug("Update %s, state: %s", self._name, self._state)
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of the device."""
|
||||
if self.tahoma_device.type == "rts:GarageDoor4TRTSComponent":
|
||||
return "garage"
|
||||
return None
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Send the on command."""
|
||||
_LOGGER.debug("Turn on: %s", self._name)
|
||||
if self.tahoma_device.type == "rts:GarageDoor4TRTSComponent":
|
||||
self.toggle()
|
||||
else:
|
||||
self.apply_action("on")
|
||||
self._skip_update = True
|
||||
self._state = STATE_ON
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Send the off command."""
|
||||
_LOGGER.debug("Turn off: %s", self._name)
|
||||
if self.tahoma_device.type == "rts:GarageDoor4TRTSComponent":
|
||||
return
|
||||
|
||||
self.apply_action("off")
|
||||
self._skip_update = True
|
||||
self._state = STATE_OFF
|
||||
|
||||
def toggle(self, **kwargs):
|
||||
"""Click the switch."""
|
||||
self.apply_action("cycle")
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Get whether the switch is in on state."""
|
||||
if self.tahoma_device.type == "rts:GarageDoor4TRTSComponent":
|
||||
return False
|
||||
return bool(self._state == STATE_ON)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return the device state attributes."""
|
||||
attr = {}
|
||||
if (super_attr := super().extra_state_attributes) is not None:
|
||||
attr.update(super_attr)
|
||||
|
||||
if "core:RSSILevelState" in self.tahoma_device.active_states:
|
||||
attr[ATTR_RSSI_LEVEL] = self.tahoma_device.active_states[
|
||||
"core:RSSILevelState"
|
||||
]
|
||||
return attr
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return True if entity is available."""
|
||||
return self._available
|
|
@ -2285,9 +2285,6 @@ synology-srm==0.2.0
|
|||
# homeassistant.components.system_bridge
|
||||
systembridge==2.2.3
|
||||
|
||||
# homeassistant.components.tahoma
|
||||
tahoma-api==0.0.16
|
||||
|
||||
# homeassistant.components.tailscale
|
||||
tailscale==0.1.6
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ ALLOWED_IGNORE_VIOLATIONS = {
|
|||
("spider", "config_flow.py"),
|
||||
("starline", "config_flow.py"),
|
||||
("tado", "config_flow.py"),
|
||||
("tahoma", "scene.py"),
|
||||
("totalconnect", "config_flow.py"),
|
||||
("tradfri", "config_flow.py"),
|
||||
("tuya", "config_flow.py"),
|
||||
|
|
Loading…
Add table
Reference in a new issue