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 support for more sensors & basic Siren (switch) support #84

Merged
merged 44 commits into from
Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
103912f
Add device class CO2
iMicknl Jun 22, 2020
30c7aed
Return measurement based on state
iMicknl Jun 22, 2020
a393355
Fix co2 and add RainSensor
iMicknl Jun 22, 2020
5c98271
Add Rain State
iMicknl Jun 22, 2020
9fdf5b6
Fix binary sensor
iMicknl Jun 22, 2020
63c7d40
Add support for motion sensors
iMicknl Jun 22, 2020
eb11b73
Add support for water sensor
iMicknl Jun 22, 2020
c160042
Fix AirSensor mapping
iMicknl Jun 22, 2020
c578f8e
Add siren support and remove optimistic mode from switch
iMicknl Jun 22, 2020
fec3d18
Style fixes
iMicknl Jun 22, 2020
e796a4a
Add all state to attr
iMicknl Jun 22, 2020
55a2535
Add battery state percentage
iMicknl Jun 22, 2020
33e40ad
Remove todo
iMicknl Jun 22, 2020
aeaa5b9
Battery state hacks
iMicknl Jun 22, 2020
f36db7e
Base icons on device classes
iMicknl Jun 22, 2020
9d7aa89
Update changelog
iMicknl Jun 22, 2020
398ec03
Fix style
iMicknl Jun 22, 2020
a5ea19c
Clean up device_state_attributes
iMicknl Jun 22, 2020
9f2c0b4
Style fix
iMicknl Jun 22, 2020
14d712c
Refactor
iMicknl Jun 22, 2020
26aa512
[fix] Fixed incorrect call to properties.
vlebourl Jun 24, 2020
48ad83e
[fix] Fix command 'ringWithSingleSimpleSequence'
vlebourl Jun 24, 2020
626e61a
[hack] Added ad hoc values to ringWithSingleSimpleSequence
vlebourl Jun 25, 2020
1ff43c2
Merge branch 'master' into refactor_sensor
iMicknl Jul 5, 2020
6d670c6
Make sensor.py more readable
iMicknl Jul 5, 2020
df6893e
Lint fixes
iMicknl Jul 5, 2020
28fe52e
Fix RainSensor const
iMicknl Jul 6, 2020
4df0486
Add WindSensor
iMicknl Jul 6, 2020
047e845
Add support for WindSpeed
iMicknl Jul 6, 2020
07ff932
Add support for VibrationSensor (part of ContactSensor)
iMicknl Jul 6, 2020
e49b534
Add SunSensor support
iMicknl Jul 6, 2020
deb91b4
Switch to const
iMicknl Jul 6, 2020
bdcd8a8
Update README
iMicknl Jul 6, 2020
3d9fd80
Formatting fix
iMicknl Jul 6, 2020
7bc7e50
Add CO sensor
iMicknl Jul 6, 2020
581aa75
Improved comment
iMicknl Jul 6, 2020
f1e7533
Add fix for the future
iMicknl Jul 6, 2020
2caf995
Fix sensor lint
iMicknl Jul 6, 2020
fcf03cc
Add CarButtonSensor
iMicknl Jul 6, 2020
794243f
Fix isort
iMicknl Jul 6, 2020
7563876
Revert changelog
iMicknl Jul 6, 2020
edc8383
Add comment
iMicknl Jul 6, 2020
42f2a17
Improve icon values
iMicknl Jul 6, 2020
edb75d5
Simplify icon()
iMicknl Jul 6, 2020
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
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@

## [1.5](https://github.com/iMicknl/ha-tahoma/tree/1.5) (2020-07-03)

iMicknl marked this conversation as resolved.
Show resolved Hide resolved
[Full Changelog](https://github.com/iMicknl/ha-tahoma/compare/1.5-alpha2...1.5)
[Full Changelog](https://github.com/iMicknl/ha-tahoma/compare/1.5-alpha2...1.5)### Adde

## [1.4] - 22-06-2020
**Implemented enhancements:**
- Added support for RainSensor
- Added support for WaterDetectionSensor
- Added basic support for Siren as switch
- Added support for MotionSensor
- Added all available states to device state attributes

- Remove exception raising in Device `__init__` in the API [\#101](https://github.com/iMicknl/ha-tahoma/pull/101) ([vlebourl](https://github.com/vlebourl))
- Changed 'battery_level' attribute to an integer, estimated based on the battery state
- Changed CO2Sensor device class to co2 to show as co2 sensor in HomeKit
- Removed unique oid from scenes

**Fixed bugs:**

Expand Down
31 changes: 31 additions & 0 deletions custom_components/tahoma/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
"""Support for TaHoma binary sensors."""
from datetime import timedelta
import logging
from typing import Optional

from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_OFF, STATE_ON

from .const import (
CORE_CONTACT_STATE,
CORE_OCCUPANCY_STATE,
CORE_RAIN_STATE,
CORE_SMOKE_STATE,
CORE_WATER_DETECTION_STATE,
DEVICE_CLASS_RAIN,
DEVICE_CLASS_WATER,
DOMAIN,
TAHOMA_BINARY_SENSOR_DEVICE_CLASSES,
TAHOMA_TYPES,
Expand Down Expand Up @@ -58,6 +63,21 @@ def device_class(self):
or None
)

@property
def icon(self) -> Optional[str]:
"""Return the icon to use in the frontend, if any."""

if self.device_class == DEVICE_CLASS_RAIN:
return "mdi:weather-rainy"
iMicknl marked this conversation as resolved.
Show resolved Hide resolved

if self.device_class == DEVICE_CLASS_WATER:
if self.is_on:
return "mdi:water"
else:
return "mdi:water-off"

return None

def update(self):
"""Update the state."""
if self.should_wait():
Expand All @@ -82,6 +102,17 @@ def update(self):
self.tahoma_device.active_states.get(CORE_SMOKE_STATE) == "detected"
)

if CORE_RAIN_STATE in self.tahoma_device.active_states:
self.current_value = (
self.tahoma_device.active_states.get(CORE_RAIN_STATE) == "detected"
)

if CORE_WATER_DETECTION_STATE in self.tahoma_device.active_states:
self.current_value = (
self.tahoma_device.active_states.get(CORE_WATER_DETECTION_STATE)
== "detected"
)

if self.current_value:
self._state = STATE_ON
else:
Expand Down
18 changes: 17 additions & 1 deletion custom_components/tahoma/const.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Constants for the TaHoma integration."""

from homeassistant.components.binary_sensor import (
DEVICE_CLASS_MOTION,
DEVICE_CLASS_OCCUPANCY,
DEVICE_CLASS_OPENING,
DEVICE_CLASS_SMOKE,
Expand All @@ -23,6 +24,11 @@

DOMAIN = "tahoma"

DEVICE_CLASS_CO2 = "co2"
DEVICE_CLASS_RAIN = "rain"
DEVICE_CLASS_SIREN = "siren"
DEVICE_CLASS_WATER = "water"

# Used to map the Somfy uiClass to the Home Assistant platform
TAHOMA_TYPES = {
"Light": "light",
Expand All @@ -35,11 +41,13 @@
"LightSensor": "sensor",
"DoorLock": "lock",
"OnOff": "switch",
"WaterDetectionSensor": "binary_sensor", # Needs to be above HumiditySensor
"HumiditySensor": "sensor",
"GarageDoor": "cover",
"ContactSensor": "binary_sensor",
"SmokeSensor": "binary_sensor",
"OccupancySensor": "binary_sensor",
"MotionSensor": "binary_sensor",
"WindowHandle": "binary_sensor",
"ExteriorVenetianBlind": "cover",
"Awning": "cover",
Expand All @@ -49,6 +57,8 @@
"SwingingShutter": "cover",
"ElectricitySensor": "sensor",
"AirSensor": "sensor",
"RainSensor": "sensor",
"Siren": "switch",
}


Expand All @@ -73,8 +83,11 @@
TAHOMA_BINARY_SENSOR_DEVICE_CLASSES = {
"SmokeSensor": DEVICE_CLASS_SMOKE,
"OccupancySensor": DEVICE_CLASS_OCCUPANCY,
"MotionSensor": DEVICE_CLASS_MOTION,
"ContactSensor": DEVICE_CLASS_OPENING,
"WindowHandle": DEVICE_CLASS_OPENING,
"RainSensor": DEVICE_CLASS_RAIN,
"WaterDetectionSensor": DEVICE_CLASS_WATER,
}

# Used to map the Somfy widget or uiClass to the Home Assistant device classes
Expand All @@ -83,7 +96,8 @@
"HumiditySensor": DEVICE_CLASS_HUMIDITY,
"LightSensor": DEVICE_CLASS_ILLUMINANCE,
"ElectricitySensor": DEVICE_CLASS_POWER,
"AirSensor": "carbon dioxide",
"CO2Sensor": DEVICE_CLASS_CO2,
"RelativeHumiditySensor": DEVICE_CLASS_HUMIDITY,
}

# TaHoma Attributes
Expand Down Expand Up @@ -111,6 +125,7 @@
CORE_ON_OFF_STATE = "core:OnOffState"
CORE_PEDESTRIAN_POSITION_STATE = "core:PedestrianPositionState"
CORE_PRIORITY_LOCK_TIMER_STATE = "core:PriorityLockTimerState"
CORE_RAIN_STATE = "core:RainState"
CORE_RED_COLOR_INTENSITY_STATE = "core:RedColorIntensityState"
CORE_RELATIVE_HUMIDITY_STATE = "core:RelativeHumidityState"
CORE_RSSI_LEVEL_STATE = "core:RSSILevelState"
Expand All @@ -122,6 +137,7 @@
CORE_TARGET_TEMPERATURE_STATE = "core:TargetTemperatureState"
CORE_TEMPERATURE_STATE = "core:TemperatureState"
CORE_VERSION_STATE = "core:VersionState"
CORE_WATER_DETECTION_STATE = "core:WaterDetectionState"

# IO Devices specific states
IO_MAXIMUM_HEATING_LEVEL_STATE = "io:MaximumHeatingLevelState"
Expand Down
5 changes: 0 additions & 5 deletions custom_components/tahoma/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,3 @@ def unique_id(self) -> str:
def name(self):
"""Return the name of the scene."""
return self._name

@property
def device_state_attributes(self):
"""Return the state attributes of the scene."""
return {"tahoma_scene_oid": self.tahoma_scene.oid}
11 changes: 6 additions & 5 deletions custom_components/tahoma/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
CORE_LUMINANCE_STATE,
CORE_RELATIVE_HUMIDITY_STATE,
CORE_TEMPERATURE_STATE,
DEVICE_CLASS_CO2,
DOMAIN,
TAHOMA_SENSOR_DEVICE_CLASSES,
TAHOMA_TYPES,
Expand Down Expand Up @@ -64,14 +65,14 @@ def state(self):
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""

if self.tahoma_device.uiclass == "TemperatureSensor":
if CORE_TEMPERATURE_STATE in self.tahoma_device.active_states:
# TODO Retrieve core:MeasuredValueType to understand if it is Celsius or Kelvin
return TEMP_CELSIUS

if self.tahoma_device.uiclass == "HumiditySensor":
if CORE_RELATIVE_HUMIDITY_STATE in self.tahoma_device.active_states:
return UNIT_PERCENTAGE

if self.tahoma_device.uiclass == "LightSensor":
if CORE_LUMINANCE_STATE in self.tahoma_device.active_states:
return "lx"

if CORE_ELECTRIC_POWER_CONSUMPTION_STATE in self.tahoma_device.active_states:
Expand All @@ -80,7 +81,7 @@ def unit_of_measurement(self):
if CORE_ELECTRIC_ENERGY_CONSUMPTION_STATE in self.tahoma_device.active_states:
return ENERGY_KILO_WATT_HOUR

if self.tahoma_device.uiclass == "AirSensor":
if CORE_CO2_CONCENTRATION_STATE in self.tahoma_device.active_states:
return CONCENTRATION_PARTS_PER_MILLION

return None
Expand All @@ -89,7 +90,7 @@ def unit_of_measurement(self):
def icon(self) -> Optional[str]:
"""Return the icon to use in the frontend, if any."""

if self.tahoma_device.uiclass == "AirSensor":
if self.device_class == DEVICE_CLASS_CO2:
return "mdi:periodic-table-co2"

return None
Expand Down
54 changes: 38 additions & 16 deletions custom_components/tahoma/switch.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""Support for TaHoma switches."""
import logging
from typing import Optional

from homeassistant.components.switch import DEVICE_CLASS_SWITCH, SwitchEntity
from homeassistant.const import STATE_OFF, STATE_ON

from .const import DOMAIN, TAHOMA_TYPES
from .const import DEVICE_CLASS_SIREN, DOMAIN, TAHOMA_TYPES
from .tahoma_device import TahomaDevice

_LOGGER = logging.getLogger(__name__)
Expand All @@ -31,47 +32,68 @@ class TahomaSwitch(TahomaDevice, SwitchEntity):
def __init__(self, tahoma_device, controller):
"""Initialize the switch."""
super().__init__(tahoma_device, controller)
self._state = STATE_OFF
self._skip_update = False

self._state = None

def update(self):
"""Update method."""
# Postpone the immediate state check for changes that take time.
if self.should_wait():
self.schedule_update_ha_state(True)
return

if self._skip_update:
self._skip_update = False
return


self.controller.get_states([self.tahoma_device])

_LOGGER.debug("Update %s, state: %s", self._name, self._state)
if "core:OnOffState" in self.tahoma_device.active_states:
self.current_value = (
self.tahoma_device.active_states.get("core:OnOffState") == "on"
)

@property
def device_class(self):
"""Return the class of the device."""

if self.tahoma_device.uiclass == "Siren":
return DEVICE_CLASS_SIREN

return DEVICE_CLASS_SWITCH

@property
def icon(self) -> Optional[str]:
"""Return the icon to use in the frontend, if any."""

if self.device_class == DEVICE_CLASS_SIREN:
if self.is_on:
return "mdi:bell-ring"
else:
return "mdi:bell-off"

return None

def turn_on(self, **kwargs):
"""Send the on command."""
_LOGGER.debug("Turn on: %s", self._name)

if "on" in self.tahoma_device.command_definitions:
return self.apply_action("on")

if "ringWithSingleSimpleSequence" in self.tahoma_device.command_definitions:
return self.apply_action(
"ringWithSingleSimpleSequence", 120000, 75, 2, "memorizedVolume"
iMicknl marked this conversation as resolved.
Show resolved Hide resolved
)

self.apply_action("on")
self._skip_update = True
self._state = STATE_ON

def turn_off(self, **kwargs):
"""Send the off command."""
self.apply_action("off")
self._skip_update = True
self._state = STATE_OFF

if "off" in self.tahoma_device.command_definitions:
return self.apply_action("off")

def toggle(self, **kwargs):
"""Click the switch."""
self.apply_action("cycle")

if "cycle" in self.tahoma_device.command_definitions:
return self.apply_action("cycle")

@property
def is_on(self):
Expand Down