From cb3ab1e873a224b3b49b84572c02c89932491ea9 Mon Sep 17 00:00:00 2001 From: David Baumann Date: Wed, 14 Sep 2016 03:21:43 +0200 Subject: [PATCH] Implement Sensor for KNX Platform (#2911) * Added Sensor Support for KNX Devices Added Sensor for KNX Group Addresses - Temperature - Wind Speed - Illuminance(LUX) Mostly to fetch from a KNX Wetterstation * Some pylint,flake8 fixes * Pydoc Fixes * Fix Coverage Ordering * Refactor KNX Sensor Refactor to Idea from @usul27 and added Minimum Maximum * Removed Measurement Untis from const.py Removed needed Measurement Units from const.py and add it to sensor\knx.py * Change .coveragerc * Add as Requested from @Teagan42 the new Type Names Additional add CONF_MINIMUM and CONF_MAXIMUM * Added Changes as Requested from @Teagan42 * Fixed the Merge Conflict, Hopefully i done it rigth :-) * Fixed Styling --- .coveragerc | 4 +- homeassistant/components/sensor/knx.py | 128 +++++++++++++++++++++++++ homeassistant/const.py | 5 + 3 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 homeassistant/components/sensor/knx.py diff --git a/.coveragerc b/.coveragerc index fadff7fe053..de90021bfb7 100644 --- a/.coveragerc +++ b/.coveragerc @@ -93,9 +93,7 @@ omit = homeassistant/components/*/pilight.py homeassistant/components/knx.py - homeassistant/components/switch/knx.py - homeassistant/components/binary_sensor/knx.py - homeassistant/components/thermostat/knx.py + homeassistant/components/*/knx.py homeassistant/components/alarm_control_panel/alarmdotcom.py homeassistant/components/alarm_control_panel/nx584.py diff --git a/homeassistant/components/sensor/knx.py b/homeassistant/components/sensor/knx.py new file mode 100644 index 00000000000..cebd1397366 --- /dev/null +++ b/homeassistant/components/sensor/knx.py @@ -0,0 +1,128 @@ +""" +Sensors of a KNX Device. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/knx/ +""" +from homeassistant.const import (TEMP_CELSIUS, TEMPERATURE, CONF_TYPE, + ILLUMINANCE, SPEED_MS, CONF_MINIMUM, + CONF_MAXIMUM) +from homeassistant.components.knx import (KNXConfig, KNXGroupAddress) + + +DEPENDENCIES = ["knx"] + +# Speed units +SPEED_METERPERSECOND = "m/s" # type: str + +# Illuminance units +ILLUMINANCE_LUX = "lx" # type: str + +# Predefined Minimum, Maximum Values for Sensors +# Temperature as defined in KNX Standard 3.10 - 9.001 DPT_Value_Temp +KNX_TEMP_MIN = -273 +KNX_TEMP_MAX = 670760 + +# Luminance(LUX) as Defined in KNX Standard 3.10 - 9.004 DPT_Value_Lux +KNX_LUX_MIN = 0 +KNX_LUX_MAX = 670760 + +# Speed m/s as defined in KNX Standard 3.10 - 9.005 DPT_Value_Wsp +KNX_SPEED_MS_MIN = 0 +KNX_SPEED_MS_MAX = 670760 + + +def setup_platform(hass, config, add_entities, discovery_info=None): + """Setup the KNX Sensor platform.""" + # Add KNX Temperature Sensors + # KNX Datapoint 9.001 DPT_Value_Temp + if config[CONF_TYPE] == TEMPERATURE: + minimum_value, maximum_value = \ + update_and_define_min_max(config, KNX_TEMP_MIN, + KNX_TEMP_MAX) + + add_entities([ + KNXSensorFloatClass(hass, KNXConfig(config), TEMP_CELSIUS, + minimum_value, maximum_value) + ]) + + # Add KNX Speed Sensors(Like Wind Speed) + # KNX Datapoint 9.005 DPT_Value_Wsp + elif config[CONF_TYPE] == SPEED_MS: + minimum_value, maximum_value = \ + update_and_define_min_max(config, KNX_SPEED_MS_MIN, + KNX_SPEED_MS_MAX) + + add_entities([ + KNXSensorFloatClass(hass, KNXConfig(config), SPEED_METERPERSECOND, + minimum_value, maximum_value) + ]) + + # Add KNX Illuminance Sensors(Lux) + # KNX Datapoint 9.004 DPT_Value_Lux + elif config[CONF_TYPE] == ILLUMINANCE: + minimum_value, maximum_value = \ + update_and_define_min_max(config, KNX_LUX_MIN, KNX_LUX_MAX) + + add_entities([ + KNXSensorFloatClass(hass, KNXConfig(config), ILLUMINANCE_LUX, + minimum_value, maximum_value) + ]) + + +def update_and_define_min_max(config, minimum_default, + maximum_default): + """Function help determinate a min/max value defined in config.""" + minimum_value = minimum_default + maximum_value = maximum_default + if config.get(CONF_MINIMUM): + minimum_value = config.get(CONF_MINIMUM) + + if config.get(CONF_MAXIMUM): + maximum_value = config.get(CONF_MAXIMUM) + + return minimum_value, maximum_value + + +class KNXSensorBaseClass(): # pylint: disable=too-few-public-methods + """Sensor Base Class for all KNX Sensors.""" + + _unit_of_measurement = None + + @property + def cache(self): + """We don't want to cache any Sensor Value.""" + return False + + @property + def unit_of_measurement(self): + """Return the defined Unit of Measurement for the KNX Sensor.""" + return self._unit_of_measurement + + +class KNXSensorFloatClass(KNXGroupAddress, KNXSensorBaseClass): + """ + Base Implementation of a 2byte Floating Point KNX Telegram. + + Defined in KNX 3.7.2 - 3.10 + """ + + # pylint: disable=too-many-arguments + def __init__(self, hass, config, unit_of_measurement, minimum_sensor_value, + maximum_sensor_value): + """Initialize a KNX Float Sensor.""" + self._unit_of_measurement = unit_of_measurement + self._minimum_value = minimum_sensor_value + self._maximum_value = maximum_sensor_value + + KNXGroupAddress.__init__(self, hass, config) + + @property + def state(self): + """Return the Value of the KNX Sensor.""" + if self._data: + from knxip.conversion import knx2_to_float + value = knx2_to_float(self._data) + if self._minimum_value <= value <= self._maximum_value: + return value + return None diff --git a/homeassistant/const.py b/homeassistant/const.py index 4107fb65a24..872f60562cd 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -94,6 +94,8 @@ CONF_LATITUDE = 'latitude' CONF_LONGITUDE = 'longitude' CONF_MAC = 'mac' CONF_METHOD = 'method' +CONF_MINIMUM = 'minimum' +CONF_MAXIMUM = 'maximum' CONF_MONITORED_CONDITIONS = 'monitored_conditions' CONF_MONITORED_VARIABLES = 'monitored_variables' CONF_NAME = 'name' @@ -125,6 +127,7 @@ CONF_TIME_ZONE = 'time_zone' CONF_TIMEOUT = 'timeout' CONF_TOKEN = 'token' CONF_TRIGGER_TIME = 'trigger_time' +CONF_TYPE = 'type' CONF_UNIT_OF_MEASUREMENT = 'unit_of_measurement' CONF_UNIT_SYSTEM = 'unit_system' CONF_URL = 'url' @@ -374,3 +377,5 @@ LENGTH = 'length' # type: str MASS = 'mass' # type: str VOLUME = 'volume' # type: str TEMPERATURE = 'temperature' # type: str +SPEED_MS = 'speed_ms' # type: str +ILLUMINANCE = 'illuminance' # type: str