diff --git a/pyfritzhome/devicetypes/__init__.py b/pyfritzhome/devicetypes/__init__.py index d698551..bef9b92 100644 --- a/pyfritzhome/devicetypes/__init__.py +++ b/pyfritzhome/devicetypes/__init__.py @@ -2,6 +2,8 @@ from .fritzhomedevicealarm import FritzhomeDeviceAlarm from .fritzhomedevicebutton import FritzhomeDeviceButton +from .fritzhomedevicehumidity import FritzhomeDeviceHumidity +from .fritzhomedevicelevel import FritzhomeDeviceLevel from .fritzhomedevicepowermeter import FritzhomeDevicePowermeter from .fritzhomedevicerepeater import FritzhomeDeviceRepeater from .fritzhomedeviceswitch import FritzhomeDeviceSwitch @@ -11,9 +13,12 @@ from .fritzhomedeviceblind import FritzhomeDeviceBlind from .fritzhometemplate import FritzhomeTemplate + __all__ = ( "FritzhomeDeviceAlarm", "FritzhomeDeviceButton", + "FritzhomeDeviceHumidity", + "FritzhomeDeviceLevel", "FritzhomeDevicePowermeter", "FritzhomeDeviceRepeater", "FritzhomeDeviceSwitch", diff --git a/pyfritzhome/devicetypes/fritzhomedevicealarm.py b/pyfritzhome/devicetypes/fritzhomedevicealarm.py index dccca14..de4d613 100644 --- a/pyfritzhome/devicetypes/fritzhomedevicealarm.py +++ b/pyfritzhome/devicetypes/fritzhomedevicealarm.py @@ -29,6 +29,7 @@ def has_alarm(self): return self._has_feature(FritzhomeDeviceFeatures.ALARM) def _update_alarm_from_node(self, node): + _LOGGER.debug("update alert device") val = node.find("alert") try: self.alert_state = self.get_node_value_as_int_as_bool(val, "state") diff --git a/pyfritzhome/devicetypes/fritzhomedevicebase.py b/pyfritzhome/devicetypes/fritzhomedevicebase.py index 32c4992..3ebabc9 100644 --- a/pyfritzhome/devicetypes/fritzhomedevicebase.py +++ b/pyfritzhome/devicetypes/fritzhomedevicebase.py @@ -14,6 +14,8 @@ class FritzhomeDeviceBase(FritzhomeEntityBase): """The Fritzhome Device class.""" + battery_level = None + battery_low = None identifier = None is_group = None fw_version = None @@ -21,6 +23,7 @@ class FritzhomeDeviceBase(FritzhomeEntityBase): manufacturer = None productname = None present = None + tx_busy = None def __repr__(self): """Return a string.""" @@ -37,6 +40,7 @@ def update(self): self._fritz.update_devices() def _update_from_node(self, node): + _LOGGER.debug("update base device") super()._update_from_node(node) self.ain = node.attrib["identifier"] self.identifier = node.attrib["id"] @@ -51,6 +55,17 @@ def _update_from_node(self, node): if self.is_group: self.group_members = str(groupinfo.findtext("members")).split(",") + try: + self.tx_busy = self.get_node_value_as_int_as_bool(node, "txbusy") + except Exception: + pass + + try: + self.battery_low = self.get_node_value_as_int_as_bool(node, "batterylow") + self.battery_level = int(self.get_node_value_as_int(node, "battery")) + except Exception: + pass + # General def get_present(self): """Check if the device is present.""" diff --git a/pyfritzhome/devicetypes/fritzhomedeviceblind.py b/pyfritzhome/devicetypes/fritzhomedeviceblind.py index 26c6b4a..5f728b2 100644 --- a/pyfritzhome/devicetypes/fritzhomedeviceblind.py +++ b/pyfritzhome/devicetypes/fritzhomedeviceblind.py @@ -12,10 +12,7 @@ class FritzhomeDeviceBlind(FritzhomeDeviceBase): """The Fritzhome Device class.""" - tx_busy = None endpositionsset = None - level = None - levelpercentage = None def _update_from_node(self, node): super()._update_from_node(node) @@ -25,18 +22,14 @@ def _update_from_node(self, node): if self.has_blind: self._update_blind_from_node(node) - # Button + # Blind @property def has_blind(self): """Check if the device has blind function.""" return self._has_feature(FritzhomeDeviceFeatures.BLIND) def _update_blind_from_node(self, node): - # print("update from blind") - try: - self.tx_busy = self.get_node_value_as_int_as_bool(node, "txbusy") - except Exception: - pass + _LOGGER.debug("update blind device") blind_element = node.find("blind") try: self.endpositionsset = self.get_node_value_as_int_as_bool( @@ -44,30 +37,6 @@ def _update_blind_from_node(self, node): ) except Exception: pass - levelcontrol_element = node.find("levelcontrol") - try: - self.level = self.get_node_value_as_int(levelcontrol_element, "level") - self.levelpercentage = self.get_node_value_as_int( - levelcontrol_element, "levelpercentage" - ) - except Exception: - pass - - def get_level(self): - """Get the blind level.""" - return self.level - - def get_level_percentage(self): - """Get the blind level in percentage.""" - return self.levelpercentage - - def set_level(self, level): - """Set the blind level.""" - self._fritz.set_level(self.ain, level) - - def set_level_percentage(self, levelpercentage): - """Set the blind level in percentage.""" - self._fritz.set_level_percentage(self.ain, levelpercentage) def set_blind_open(self): """Open the blind.""" diff --git a/pyfritzhome/devicetypes/fritzhomedevicebutton.py b/pyfritzhome/devicetypes/fritzhomedevicebutton.py index 4c4d0f4..29ef575 100644 --- a/pyfritzhome/devicetypes/fritzhomedevicebutton.py +++ b/pyfritzhome/devicetypes/fritzhomedevicebutton.py @@ -28,19 +28,13 @@ def has_button(self): return self._has_feature(FritzhomeDeviceFeatures.BUTTON) def _update_button_from_node(self, node): + _LOGGER.debug("update button device") self.buttons = {} for element in node.findall("button"): button = FritzhomeButton(element) self.buttons[button.ain] = button - try: - self.tx_busy = self.get_node_value_as_int_as_bool(node, "txbusy") - self.battery_low = self.get_node_value_as_int_as_bool(node, "batterylow") - self.battery_level = int(self.get_node_value_as_int(node, "battery")) - except Exception: - pass - def get_button_by_ain(self, ain): """Return the button by AIN.""" return self.buttons[ain] diff --git a/pyfritzhome/devicetypes/fritzhomedevicehumidity.py b/pyfritzhome/devicetypes/fritzhomedevicehumidity.py new file mode 100644 index 0000000..fe56ec0 --- /dev/null +++ b/pyfritzhome/devicetypes/fritzhomedevicehumidity.py @@ -0,0 +1,39 @@ +"""The humidity device class.""" +# -*- coding: utf-8 -*- + +import logging + +from .fritzhomedevicebase import FritzhomeDeviceBase +from .fritzhomedevicefeatures import FritzhomeDeviceFeatures + +_LOGGER = logging.getLogger(__name__) + + +class FritzhomeDeviceHumidity(FritzhomeDeviceBase): + """The Fritzhome Device class.""" + + rel_humidity = None + + def _update_from_node(self, node): + super()._update_from_node(node) + if self.present is False: + return + + if self.has_humidity_sensor: + self._update_humidity_from_node(node) + + # Humidity + @property + def has_humidity_sensor(self): + """Check if the device has humidity function.""" + return self._has_feature(FritzhomeDeviceFeatures.HUMIDITY) + + def _update_humidity_from_node(self, node): + _LOGGER.debug("update humidity device") + humidity_element = node.find("humidity") + try: + self.rel_humidity = self.get_node_value_as_int( + humidity_element, "rel_humidity" + ) + except ValueError: + pass diff --git a/pyfritzhome/devicetypes/fritzhomedevicelevel.py b/pyfritzhome/devicetypes/fritzhomedevicelevel.py new file mode 100644 index 0000000..5b08955 --- /dev/null +++ b/pyfritzhome/devicetypes/fritzhomedevicelevel.py @@ -0,0 +1,57 @@ +"""The level device class.""" +# -*- coding: utf-8 -*- + +import logging + +from .fritzhomedevicebase import FritzhomeDeviceBase +from .fritzhomedevicefeatures import FritzhomeDeviceFeatures + +_LOGGER = logging.getLogger(__name__) + + +class FritzhomeDeviceLevel(FritzhomeDeviceBase): + """The Fritzhome Device class.""" + + level = None + levelpercentage = None + + def _update_from_node(self, node): + super()._update_from_node(node) + if self.present is False: + return + + if self.has_level: + self._update_level_from_node(node) + + # Level + @property + def has_level(self): + """Check if the device has level function.""" + return self._has_feature(FritzhomeDeviceFeatures.LEVEL) + + def _update_level_from_node(self, node): + _LOGGER.debug("update level device") + levelcontrol_element = node.find("levelcontrol") + try: + self.level = self.get_node_value_as_int(levelcontrol_element, "level") + self.levelpercentage = self.get_node_value_as_int( + levelcontrol_element, "levelpercentage" + ) + except Exception: + pass + + def get_level(self): + """Get the level.""" + return self.level + + def get_level_percentage(self): + """Get the level in percentage.""" + return self.levelpercentage + + def set_level(self, level): + """Set the level.""" + self._fritz.set_level(self.ain, level) + + def set_level_percentage(self, levelpercentage): + """Set the level in percentage.""" + self._fritz.set_level_percentage(self.ain, levelpercentage) diff --git a/pyfritzhome/devicetypes/fritzhomedevicelightbulb.py b/pyfritzhome/devicetypes/fritzhomedevicelightbulb.py index 432df24..8d085d5 100644 --- a/pyfritzhome/devicetypes/fritzhomedevicelightbulb.py +++ b/pyfritzhome/devicetypes/fritzhomedevicelightbulb.py @@ -13,7 +13,6 @@ class FritzhomeDeviceLightBulb(FritzhomeDeviceBase): """The Fritzhome Device class.""" state = None - level = None hue = None saturation = None unmapped_hue = None @@ -36,17 +35,13 @@ def has_lightbulb(self): """Check if the device has LightBulb function.""" return self._has_feature(FritzhomeDeviceFeatures.LIGHTBULB) - @property - def has_level(self): - """Check if the device has LightBulb function.""" - return self._has_feature(FritzhomeDeviceFeatures.LEVEL) - @property def has_color(self): """Check if the device has LightBulb function.""" return self._has_feature(FritzhomeDeviceFeatures.COLOR) def _update_lightbulb_from_node(self, node): + _LOGGER.debug("update light bulb device") state_element = node.find("simpleonoff") try: self.state = self.get_node_value_as_int_as_bool(state_element, "state") @@ -54,15 +49,6 @@ def _update_lightbulb_from_node(self, node): except ValueError: pass - if self.has_level: - level_element = node.find("levelcontrol") - try: - self.level = self.get_node_value_as_int(level_element, "level") - - self.level_percentage = int(self.level / 2.55) - except ValueError: - pass - if self.has_color: colorcontrol_element = node.find("colorcontrol") try: @@ -120,16 +106,6 @@ def set_state_toggle(self): self.state = True self._fritz.set_state_toggle(self.ain) - def set_level(self, level): - """Set level.""" - if self.has_level: - self._fritz.set_level(self.ain, level) - - def set_level_percentage(self, level): - """Set HSV color in percent.""" - if self.has_level: - self._fritz.set_level_percentage(self.ain, level) - def get_colors(self): """Get the supported colors.""" if self.has_color: diff --git a/pyfritzhome/devicetypes/fritzhomedevicepowermeter.py b/pyfritzhome/devicetypes/fritzhomedevicepowermeter.py index fbee6d4..237070c 100644 --- a/pyfritzhome/devicetypes/fritzhomedevicepowermeter.py +++ b/pyfritzhome/devicetypes/fritzhomedevicepowermeter.py @@ -32,6 +32,7 @@ def has_powermeter(self): return self._has_feature(FritzhomeDeviceFeatures.POWER_METER) def _update_powermeter_from_node(self, node): + _LOGGER.debug("update powermeter device") val = node.find("powermeter") self.power = int(val.findtext("power")) self.energy = int(val.findtext("energy")) diff --git a/pyfritzhome/devicetypes/fritzhomedeviceswitch.py b/pyfritzhome/devicetypes/fritzhomedeviceswitch.py index 17f015c..9df1fb0 100644 --- a/pyfritzhome/devicetypes/fritzhomedeviceswitch.py +++ b/pyfritzhome/devicetypes/fritzhomedeviceswitch.py @@ -31,13 +31,15 @@ def has_switch(self): if self._has_feature(FritzhomeDeviceFeatures.SWITCH): # for AVM plugs like FRITZ!DECT 200 and FRITZ!DECT 210 return True - if (self._has_feature(FritzhomeDeviceFeatures.SWITCHABLE) - and not self._has_feature(FritzhomeDeviceFeatures.LIGHTBULB)): + if self._has_feature( + FritzhomeDeviceFeatures.SWITCHABLE + ) and not self._has_feature(FritzhomeDeviceFeatures.LIGHTBULB): # for HAN-FUN plugs return True return False def _update_switch_from_node(self, node): + _LOGGER.debug("update switch device") if self._has_feature(FritzhomeDeviceFeatures.SWITCH): val = node.find("switch") try: diff --git a/pyfritzhome/devicetypes/fritzhomedevicetemperature.py b/pyfritzhome/devicetypes/fritzhomedevicetemperature.py index 5b241a9..9ca1c4e 100644 --- a/pyfritzhome/devicetypes/fritzhomedevicetemperature.py +++ b/pyfritzhome/devicetypes/fritzhomedevicetemperature.py @@ -14,7 +14,6 @@ class FritzhomeDeviceTemperature(FritzhomeDeviceBase): offset = None temperature = None - rel_humidity = None def _update_from_node(self, node): super()._update_from_node(node) @@ -31,6 +30,7 @@ def has_temperature_sensor(self): return self._has_feature(FritzhomeDeviceFeatures.TEMPERATURE) def _update_temperature_from_node(self, node): + _LOGGER.debug("update temperature device") temperature_element = node.find("temperature") try: self.offset = ( @@ -45,12 +45,3 @@ def _update_temperature_from_node(self, node): ) except ValueError: pass - - humidity_element = node.find("humidity") - if humidity_element is not None: - try: - self.rel_humidity = self.get_node_value_as_int( - humidity_element, "rel_humidity" - ) - except ValueError: - pass diff --git a/pyfritzhome/devicetypes/fritzhomedevicethermostat.py b/pyfritzhome/devicetypes/fritzhomedevicethermostat.py index a8c8864..e439a5b 100644 --- a/pyfritzhome/devicetypes/fritzhomedevicethermostat.py +++ b/pyfritzhome/devicetypes/fritzhomedevicethermostat.py @@ -20,8 +20,6 @@ class FritzhomeDeviceThermostat(FritzhomeDeviceBase): device_lock = None lock = None error_code = None - battery_low = None - battery_level = None window_open = None window_open_endtime = None summer_active = None @@ -44,6 +42,7 @@ def has_thermostat(self): return self._has_feature(FritzhomeDeviceFeatures.THERMOSTAT) def _update_hkr_from_node(self, node): + _LOGGER.debug("update thermostat device") hkr_element = node.find("hkr") try: @@ -62,6 +61,7 @@ def _update_hkr_from_node(self, node): ) self.lock = self.get_node_value_as_int_as_bool(hkr_element, "lock") self.error_code = self.get_node_value_as_int(hkr_element, "errorcode") + # keep battery values as fallback for Fritz!OS < 7.08 self.battery_low = self.get_node_value_as_int_as_bool( hkr_element, "batterylow" ) diff --git a/pyfritzhome/devicetypes/fritzhometemplate.py b/pyfritzhome/devicetypes/fritzhometemplate.py index 88dff3d..06de21d 100644 --- a/pyfritzhome/devicetypes/fritzhometemplate.py +++ b/pyfritzhome/devicetypes/fritzhometemplate.py @@ -25,6 +25,7 @@ class FritzhomeTemplate(FritzhomeEntityBase): apply_dialhelper = None def _update_from_node(self, node): + _LOGGER.debug("update template") super()._update_from_node(node) self.features = FritzhomeDeviceFeatures(self._functionsbitmask) diff --git a/pyfritzhome/fritzhomedevice.py b/pyfritzhome/fritzhomedevice.py index e4d6889..4823cb4 100644 --- a/pyfritzhome/fritzhomedevice.py +++ b/pyfritzhome/fritzhomedevice.py @@ -7,6 +7,8 @@ FritzhomeDeviceAlarm, FritzhomeDeviceBlind, FritzhomeDeviceButton, + FritzhomeDeviceHumidity, + FritzhomeDeviceLevel, FritzhomeDeviceLightBulb, FritzhomeDevicePowermeter, FritzhomeDeviceRepeater, @@ -18,14 +20,16 @@ class FritzhomeDevice( FritzhomeDeviceAlarm, + FritzhomeDeviceBlind, FritzhomeDeviceButton, + FritzhomeDeviceHumidity, + FritzhomeDeviceLevel, + FritzhomeDeviceLightBulb, FritzhomeDevicePowermeter, FritzhomeDeviceRepeater, FritzhomeDeviceSwitch, FritzhomeDeviceTemperature, FritzhomeDeviceThermostat, - FritzhomeDeviceLightBulb, - FritzhomeDeviceBlind, ): """The Fritzhome Device class.""" diff --git a/tests/responses/thermostat/device_hkr_fritzos_7.xml b/tests/responses/thermostat/device_hkr_fritzos_7.xml index bc10ec9..c0113b3 100644 --- a/tests/responses/thermostat/device_hkr_fritzos_7.xml +++ b/tests/responses/thermostat/device_hkr_fritzos_7.xml @@ -3,6 +3,8 @@ 1 Thermostat Wohnzimmer Seite + 0 + 70 205 -10 diff --git a/tests/responses/thermostat/device_hkr_fw_03_54.xml b/tests/responses/thermostat/device_hkr_fw_03_54.xml index 03a8d93..824df20 100644 --- a/tests/responses/thermostat/device_hkr_fw_03_54.xml +++ b/tests/responses/thermostat/device_hkr_fw_03_54.xml @@ -3,6 +3,8 @@ 1 Badezimmer + 0 + 80 205 -15 @@ -16,6 +18,7 @@ 0 0 0 + 80 1508342400 42 diff --git a/tests/responses/thermostat/device_hkr_no_temp_values.xml b/tests/responses/thermostat/device_hkr_no_temp_values.xml index 17e3b1e..cf7929d 100644 --- a/tests/responses/thermostat/device_hkr_no_temp_values.xml +++ b/tests/responses/thermostat/device_hkr_no_temp_values.xml @@ -3,6 +3,8 @@ 1 Thermostat Wohnzimmer Seite + 0 + 80 @@ -16,6 +18,7 @@ 0 5 0 + 80 1519160400 36 diff --git a/tests/responses/thermostat/device_list_battery_low.xml b/tests/responses/thermostat/device_list_battery_low.xml index bc4d57c..100551a 100644 --- a/tests/responses/thermostat/device_list_battery_low.xml +++ b/tests/responses/thermostat/device_list_battery_low.xml @@ -4,6 +4,8 @@ fwversion="03.54" manufacturer="AVM" productname="Comet DECT"> 1 Badezimmer + 10 + 1 205 -15 @@ -17,6 +19,7 @@ 0 0 1 + 10 1508342400 42 diff --git a/tests/responses/thermostat/device_list_battery_ok.xml b/tests/responses/thermostat/device_list_battery_ok.xml index d643cdf..114cea1 100644 --- a/tests/responses/thermostat/device_list_battery_ok.xml +++ b/tests/responses/thermostat/device_list_battery_ok.xml @@ -4,6 +4,8 @@ fwversion="03.54" manufacturer="AVM" productname="Comet DECT"> 1 Badezimmer + 0 + 80 205 -15 @@ -17,6 +19,7 @@ 0 0 0 + 80 1508342400 42