From 2b08e2e1bbc62f1322eda39d7852e5ecdd64cce2 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Tue, 11 Dec 2018 19:58:24 +0100 Subject: [PATCH 01/21] API: added MotionDetectionSendInterval Enum added missing values to MotionDetectorIndoo added permanentlyReachable to Device HMIP_CLI: added permanentlyReachable to --list-rssi --- hmip_cli.py | 5 +- homematicip/base/enums.py | 8 +++ homematicip/device.py | 20 ++++++- tests/json_data/home.json | 83 ++++++++++++++++++++++++++++++ tests/json_data/unknown_types.json | 1 + tests/test_devices.py | 43 ++++++++++------ 6 files changed, 141 insertions(+), 19 deletions(-) diff --git a/hmip_cli.py b/hmip_cli.py index d7499456..d2fc6919 100644 --- a/hmip_cli.py +++ b/hmip_cli.py @@ -241,12 +241,13 @@ def main(): sortedDevices = sorted(home.devices, key=attrgetter('deviceType', 'label')) for d in sortedDevices: - print("{:45s} - RSSI: {:4} {} - Peer RSSI: {:4} - {} {}".format(d.label, + print("{:45s} - RSSI: {:4} {} - Peer RSSI: {:4} - {} {} permanentlyReachable: {}".format(d.label, d.rssiDeviceValue if d.rssiDeviceValue is not None else "None", getRssiBarString(d.rssiDeviceValue), d.rssiPeerValue if d.rssiPeerValue is not None else "None", getRssiBarString(d.rssiPeerValue), - "Unreachable" if d.unreach else "")) + "Unreachable" if d.unreach else "", + d.permanentlyReachable) ) if args.list_rules: command_entered = True sortedRules = sorted(home.rules, key=attrgetter('ruleType', 'label')) diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index bce3961a..57877d36 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -231,3 +231,11 @@ class EventType(AutoNameEnum): CLIENT_ADDED = auto() HOME_CHANGED = auto() GROUP_CHANGED = auto() + + +class MotionDetectionSendInterval(AutoNameEnum): + SECONDS_30 = auto() + SECONDS_60 = auto() + SECONDS_120 = auto() + SECONDS_240 = auto() + SECONDS_480 = auto() \ No newline at end of file diff --git a/homematicip/device.py b/homematicip/device.py index 57f8c01a..c9e669bf 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -35,6 +35,7 @@ def __init__(self,connection): self.rssiPeerValue = 0 self.dutyCycle = False self.configPending = False + self.permanentlyReachable = False def from_json(self, js): super().from_json(js) @@ -54,6 +55,7 @@ def from_json(self, js): self.oem = js['oem'] self.manufacturerCode = js['manufacturerCode'] self.serializedGlobalTradeItemNumber = js['serializedGlobalTradeItemNumber'] + self.permanentlyReachable = js["permanentlyReachable"] c = get_functional_channel("DEVICE_BASE", js) if c: @@ -417,8 +419,13 @@ class MotionDetectorIndoor(SabotageDevice): def __init__(self,connection): super().__init__(connection) + self.currentIllumination = None self.motionDetected = None self.illumination = None + self.motionBufferActive = False + self.motionDetected = False + self.motionDetectionSendInterval = MotionDetectionSendInterval.SECONDS_30 + self.numberOfBrightnessMeasurements = 0 def from_json(self, js): super().from_json(js) @@ -426,11 +433,20 @@ def from_json(self, js): if c: self.motionDetected = c["motionDetected"] self.illumination = c["illumination"] + self.motionBufferActive = c["motionBufferActive"] + self.motionDetected = c["motionDetected"] + self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(c["motionDetectionSendInterval"]) + self.numberOfBrightnessMeasurements = c["numberOfBrightnessMeasurements"] + self.currentIllumination = c["currentIllumination"] def __str__(self): - return "{} motionDetected({}) illumination({})".format(super().__str__(), + return "{} motionDetected({}) illumination({}) motionBufferActive({}) motionDetected({}) motionDetectionSendInterval({}) numberOfBrightnessMeasurements({})".format(super().__str__(), self.motionDetected, - self.illumination) + self.illumination, + self.motionBufferActive, + self.motionDetected, + self.motionDetectionSendInterval, + self.numberOfBrightnessMeasurements) class MotionDetectorPushButton(MotionDetectorIndoor): diff --git a/tests/json_data/home.json b/tests/json_data/home.json index aaeacfb5..6dd662e4 100644 --- a/tests/json_data/home.json +++ b/tests/json_data/home.json @@ -8,6 +8,57 @@ } }, "devices": { + "3014F711000000000000BB11": { + "availableFirmwareVersion": "1.4.8", + "firmwareVersion": "1.4.8", + "firmwareVersionInteger": 66568, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F711000000000000BB11", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -56, + "rssiPeerValue": -52, + "sabotage": false, + "unreach": false + }, + "1": { + "currentIllumination": null, + "deviceId": "3014F711000000000000BB11", + "functionalChannelType": "MOTION_DETECTION_CHANNEL", + "groupIndex": 1, + "groups": [], + "illumination": 0.1, + "index": 1, + "label": "", + "motionBufferActive": false, + "motionDetected": true, + "motionDetectionSendInterval": "SECONDS_480", + "numberOfBrightnessMeasurements": 7 + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F711000000000000BB11", + "label": "Wohnzimmer", + "lastStatusUpdate": 1544480290322, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 291, + "modelType": "HmIP-SMI", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000011", + "type": "MOTION_DETECTOR_INDOOR", + "updateState": "UP_TO_DATE" + }, "3014F7110000000000000050": { "availableFirmwareVersion": "0.0.0", "firmwareVersion": "1.0.2", @@ -58,6 +109,7 @@ "modelId": 353, "modelType": "HmIP-SWD", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000050", "type": "WATER_SENSOR", "updateState": "UP_TO_DATE" @@ -111,6 +163,7 @@ "modelId": 258, "modelType": "HMIP-SWDO", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000000", "type": "SHUTTER_CONTACT", "updateState": "UP_TO_DATE" @@ -163,6 +216,7 @@ "modelId": 258, "modelType": "HMIP-SWDO", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000001", "type": "SHUTTER_CONTACT", "updateState": "UP_TO_DATE" @@ -215,6 +269,7 @@ "modelId": 258, "modelType": "HMIP-SWDO", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000002", "type": "SHUTTER_CONTACT", "updateState": "UP_TO_DATE" @@ -267,6 +322,7 @@ "modelId": 258, "modelType": "HMIP-SWDO", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000003", "type": "SHUTTER_CONTACT", "updateState": "UP_TO_DATE" @@ -319,6 +375,7 @@ "modelId": 258, "modelType": "HMIP-SWDO", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000004", "type": "SHUTTER_CONTACT", "updateState": "UP_TO_DATE" @@ -371,6 +428,7 @@ "modelId": 258, "modelType": "HMIP-SWDO", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000005", "type": "SHUTTER_CONTACT", "updateState": "UP_TO_DATE" @@ -422,6 +480,7 @@ "modelId": 258, "modelType": "HMIP-SWDO", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000006", "type": "SHUTTER_CONTACT", "updateState": "UP_TO_DATE" @@ -473,6 +532,7 @@ "modelId": 258, "modelType": "HMIP-SWDO", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000007", "type": "SHUTTER_CONTACT", "updateState": "UP_TO_DATE" @@ -524,6 +584,7 @@ "modelId": 262, "modelType": "HMIP-PSM", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000008", "type": "PLUGABLE_SWITCH_MEASURING", "updateState": "UP_TO_DATE" @@ -575,6 +636,7 @@ "modelId": 262, "modelType": "HMIP-PSM", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000009", "type": "PLUGABLE_SWITCH_MEASURING", "updateState": "UP_TO_DATE" @@ -626,6 +688,7 @@ "modelId": 262, "modelType": "HMIP-PSM", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000010", "type": "PLUGABLE_SWITCH_MEASURING", "updateState": "UP_TO_DATE" @@ -678,6 +741,7 @@ "modelId": 269, "modelType": "HMIP-eTRV", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000011", "type": "HEATING_THERMOSTAT", "updateState": "UP_TO_DATE" @@ -730,6 +794,7 @@ "modelId": 269, "modelType": "HMIP-eTRV", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000012", "type": "HEATING_THERMOSTAT", "updateState": "UP_TO_DATE" @@ -782,6 +847,7 @@ "modelId": 269, "modelType": "HMIP-eTRV", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000013", "type": "HEATING_THERMOSTAT", "updateState": "UP_TO_DATE" @@ -834,6 +900,7 @@ "modelId": 269, "modelType": "HMIP-eTRV", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000014", "type": "HEATING_THERMOSTAT", "updateState": "UP_TO_DATE" @@ -886,6 +953,7 @@ "modelId": 269, "modelType": "HMIP-eTRV", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000015", "type": "HEATING_THERMOSTAT", "updateState": "UP_TO_DATE" @@ -938,6 +1006,7 @@ "modelId": 269, "modelType": "HMIP-eTRV", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000016", "type": "HEATING_THERMOSTAT", "updateState": "UP_TO_DATE" @@ -990,6 +1059,7 @@ "modelId": 269, "modelType": "HMIP-eTRV", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000017", "type": "HEATING_THERMOSTAT", "updateState": "UP_TO_DATE" @@ -1039,6 +1109,7 @@ "modelId": 296, "modelType": "HmIP-SWSD", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000018", "type": "SMOKE_DETECTOR", "updateState": "UP_TO_DATE" @@ -1088,6 +1159,7 @@ "modelId": 296, "modelType": "HmIP-SWSD", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000019", "type": "SMOKE_DETECTOR", "updateState": "UP_TO_DATE" @@ -1137,6 +1209,7 @@ "modelId": 296, "modelType": "HmIP-SWSD", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000020", "type": "SMOKE_DETECTOR", "updateState": "UP_TO_DATE" @@ -1186,6 +1259,7 @@ "modelId": 296, "modelType": "HmIP-SWSD", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000021", "type": "SMOKE_DETECTOR", "updateState": "UP_TO_DATE" @@ -1238,6 +1312,7 @@ "modelId": 297, "modelType": "HmIP-WTH-2", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000022", "type": "WALL_MOUNTED_THERMOSTAT_PRO", "updateState": "UP_TO_DATE" @@ -1290,6 +1365,7 @@ "modelId": 297, "modelType": "HmIP-WTH-2", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000023", "type": "WALL_MOUNTED_THERMOSTAT_PRO", "updateState": "UP_TO_DATE" @@ -1342,6 +1418,7 @@ "modelId": 297, "modelType": "HmIP-WTH-2", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000024", "type": "WALL_MOUNTED_THERMOSTAT_PRO", "updateState": "UP_TO_DATE" @@ -1394,6 +1471,7 @@ "modelId": 297, "modelType": "HmIP-WTH-2", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000025", "type": "WALL_MOUNTED_THERMOSTAT_PRO", "updateState": "UP_TO_DATE" @@ -1458,6 +1536,7 @@ "modelId": 352, "modelType": "HmIP-SWO-PR", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F711AAAA000000000001", "type": "WEATHER_SENSOR_PRO", "updateState": "UP_TO_DATE" @@ -1506,6 +1585,7 @@ "modelId": 314, "modelType": "HmIP-STHO", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F711AAAA000000000002", "type": "TEMPERATURE_HUMIDITY_SENSOR_OUTDOOR", "updateState": "UP_TO_DATE" @@ -1559,6 +1639,7 @@ "modelId": 350, "modelType": "HmIP-SWO-B", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F711AAAA000000000003", "type": "WEATHER_SENSOR", "updateState": "UP_TO_DATE" @@ -1604,6 +1685,7 @@ "modelId": 286, "modelType": "HmIP-SRH", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F711AAAA000000000004", "type": "ROTARY_HANDLE_SENSOR", "updateState": "UP_TO_DATE" @@ -1653,6 +1735,7 @@ "modelId": 290, "modelType": "HmIP-BDT", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F711AAAA000000000005", "type": "BRAND_DIMMER", "updateState": "UP_TO_DATE" diff --git a/tests/json_data/unknown_types.json b/tests/json_data/unknown_types.json index 6606507a..931e668f 100644 --- a/tests/json_data/unknown_types.json +++ b/tests/json_data/unknown_types.json @@ -21,6 +21,7 @@ "modelId": 353, "modelType": "HmIP-DUMMY", "oem": "eQ-3", + "permanentlyReachable": true, "serializedGlobalTradeItemNumber": "3014F7110000000000000050", "type": "DUMMY_DEVICE", "updateState": "UP_TO_DATE" diff --git a/tests/test_devices.py b/tests/test_devices.py index cde2fa6f..a03f6d8d 100644 --- a/tests/test_devices.py +++ b/tests/test_devices.py @@ -85,8 +85,8 @@ def test_pluggable_switch_measuring(fake_home : Home): d.turn_off() fake_home.get_current_state() d = fake_home.search_device_by_id('3014F7110000000000000009') - assert d.on == False - + assert d.on == False + d.id = 'INVALID_ID' result = d.turn_off() assert result['errorCode'] == 'INVALID_DEVICE' @@ -153,8 +153,8 @@ def test_wall_mounted_thermostat_pro(fake_home : Home ): d.set_display( ClimateControlDisplay.ACTUAL) fake_home.get_current_state() d = fake_home.search_device_by_id('3014F7110000000000000022') - assert d.display == ClimateControlDisplay.ACTUAL - + assert d.display == ClimateControlDisplay.ACTUAL + d.id = 'INVALID_ID' result = d.set_display( ClimateControlDisplay.ACTUAL) assert result['errorCode'] == 'INVALID_DEVICE' @@ -195,9 +195,9 @@ def test_heating_thermostat(fake_home : Home): d.set_operation_lock(False) fake_home.get_current_state() d = fake_home.search_device_by_id('3014F7110000000000000015') - assert d.operationLockActive == False - - d.id = 'INVALID_ID' + assert d.operationLockActive == False + + d.id = 'INVALID_ID' result = d.set_operation_lock(True) assert result['errorCode'] == 'INVALID_DEVICE' @@ -377,8 +377,8 @@ def test_dimmer(fake_home : Home): d.set_dim_level(0.5) fake_home.get_current_state() d = fake_home.search_device_by_id('3014F711AAAA000000000005') - assert d.dimLevel == 0.5 - + assert d.dimLevel == 0.5 + d.id = 'INVALID_ID' result = d.set_dim_level(0.5) assert result['errorCode'] == 'INVALID_DEVICE' @@ -386,6 +386,7 @@ def test_dimmer(fake_home : Home): def test_basic_device_functions(fake_home:Home): with no_ssl_verification(): d = fake_home.search_device_by_id('3014F7110000000000000009') + assert d.permanentlyReachable == True assert d.label == "Brunnen" assert d.routerModuleEnabled == True assert d.energyCounter == 0.4754 @@ -467,14 +468,26 @@ def test_water_sensor(fake_home : Home): assert d.inAppWaterAlarmTrigger == WaterAlarmTrigger.MOISTURE_DETECTION assert d.sirenWaterAlarmTrigger ==WaterAlarmTrigger.NO_ALARM - d.id = 'INVALID_ID' + d.id = 'INVALID_ID' result = d.set_acoustic_alarm_timing(AcousticAlarmTiming.SIX_MINUTES) - assert result['errorCode'] == 'INVALID_DEVICE' + assert result['errorCode'] == 'INVALID_DEVICE' result = d.set_acoustic_alarm_signal(AcousticAlarmSignal.FREQUENCY_ALTERNATING_LOW_HIGH) - assert result['errorCode'] == 'INVALID_DEVICE' + assert result['errorCode'] == 'INVALID_DEVICE' result = d.set_inapp_water_alarm_trigger(WaterAlarmTrigger.MOISTURE_DETECTION) - assert result['errorCode'] == 'INVALID_DEVICE' + assert result['errorCode'] == 'INVALID_DEVICE' result = d.set_acoustic_water_alarm_trigger(WaterAlarmTrigger.NO_ALARM) - assert result['errorCode'] == 'INVALID_DEVICE' - result = d.set_siren_water_alarm_trigger(WaterAlarmTrigger.NO_ALARM) assert result['errorCode'] == 'INVALID_DEVICE' + result = d.set_siren_water_alarm_trigger(WaterAlarmTrigger.NO_ALARM) + assert result['errorCode'] == 'INVALID_DEVICE' + + +def test_motion_detector_indoor(fake_home:Home): + d = MotionDetectorIndoor(fake_home._connection) + d = fake_home.search_device_by_id("3014F711000000000000BB11") + + assert d.illumination == 0.1 + assert d.currentIllumination == None + assert d.motionBufferActive == False + assert d.motionDetected == True + assert d.motionDetectionSendInterval == MotionDetectionSendInterval.SECONDS_480 + assert d.numberOfBrightnessMeasurements == 7 \ No newline at end of file From e45a051d81a380c0cacee4eecc4acf0063c01f7d Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Tue, 11 Dec 2018 20:21:43 +0100 Subject: [PATCH 02/21] added FULL_FLUSH_DIMMER Device --- README.rst | 53 ++++++++++++++++++----------------- homematicip/aio/class_maps.py | 3 +- homematicip/aio/device.py | 3 ++ homematicip/base/enums.py | 17 +++++++---- homematicip/class_maps.py | 3 +- homematicip/device.py | 4 ++- tests/test_devices.py | 8 ++++-- 7 files changed, 55 insertions(+), 36 deletions(-) diff --git a/README.rst b/README.rst index 0d07b934..0e08538d 100644 --- a/README.rst +++ b/README.rst @@ -63,33 +63,34 @@ Implemented Stuff Devices: -------- -- [X] HMIP-eTRV (Heating-thermostat) +- [X] HMIP-ASIR (Alarm Siren) +- [X] HMIP-BROLL (Shutter Actuator - brand-mount) +- [X] HMIP-BSM (Brand Switch and Meter) +- [X] HMIP-BWTH (Brand Wall Mounted Thermostat Pro) +- [X] HMIP-eTRV (Heating-thermostat) +- [X] HMIP-FAL230-C6 (Floor Terminal Block) +- [X] HMIP-FDT (Dimming Actuator flush-mount) +- [X] HMIP-FROLL (Shutter Actuator - flush-mount) +- [X] HMIP-KRCA (Key Ring Remote Control & alarm) +- [X] HMIP-PCBS-BAT (Printed Curcuit Board Switch Battery) +- [X] HMIP-PDT (Pluggable Dimmer) +- [X] HMIP-PS (Plugable Switch) +- [X] HMIP-PSM (Plugable Switch Measuring) +- [X] HMIP-SMI (Motion Detector with Brightness Sensor - indoor) +- [X] HMIP-SMI55 (Motion Detector with Brightness Sensor and Remote Control - 2-button) +- [X] HMIP-SPI (Precence Sensor - indoor) +- [X] HMIP-SRH (Rotary Handle Sensor) +- [X] HMIP-STH (Temperature and Humidity Sensor without display - indoor) +- [X] HMIP-STHD (Temperature and Humidity Sensor with display - indoor) +- [X] HMIP-STHO (Temperature and Humidity Sensor outdoor) +- [X] HMIP-SWD (Water Sensor) +- [X] HMIP-SWDO (Shutter Contact) +- [X] HMIP-SWDO-I (Shutter Contact Invisible) +- [X] HMIP-SWO-B (Weather Sensor) +- [X] HMIP-SWO-PR (Weather Sensor – pro) +- [X] HMIP-SWSD (Smoke Detector) +- [X] HMIP-WRC2 (Wall-mount Remote Control - 2-button) - [X] HMIP-WTH, HMIP-WTH-2 (Wall Mounted Thermostat Pro) -- [X] HMIP-BWTH (Brand Wall Mounted Thermostat Pro) -- [X] HMIP-SWDO (Shutter Contact) -- [X] HMIP-SWDO-I (Shutter Contact Invisible) -- [X] HMIP-SWSD (Smoke Detector) -- [X] HMIP-FAL230-C6 (Floor Terminal Block) -- [X] HMIP-PS (Plugable Switch) -- [X] HMIP-PSM (Plugable Switch Measuring) -- [X] HMIP-STHD (Temperature and Humidity Sensor with display - indoor) -- [X] HMIP-STH (Temperature and Humidity Sensor without display - indoor) -- [X] HMIP-WRC2 (Wall-mount Remote Control - 2-button) -- [X] HMIP-ASIR (Alarm Siren) -- [X] HMIP-KRCA (Key Ring Remote Control & alarm) -- [X] HMIP-SMI (Motion Detector with Brightness Sensor - indoor) -- [X] HMIP-FROLL (Shutter Actuator - flush-mount) -- [X] HMIP-BROLL (Shutter Actuator - brand-mount) -- [X] HMIP-SPI (Precence Sensor - indoor) -- [X] HMIP-PDT (Pluggable Dimmer) -- [X] HMIP-BSM (Brand Switch and Meter) -- [X] HMIP-PCBS-BAT (Printed Curcuit Board Switch Battery) -- [X] HMIP-STHO (Temperature and Humidity Sensor outdoor) -- [X] HMIP-SWO-PR (Weather Sensor – pro) -- [X] HMIP-SWO-B (Weather Sensor) -- [X] HMIP-SRH (Rotary Handle Sensor) -- [X] HMIP-SWD (Water Sensor) -- [X] HMIP-SMI55 (Motion Detector with Brightness Sensor and Remote Control - 2-button) Events ------ diff --git a/homematicip/aio/class_maps.py b/homematicip/aio/class_maps.py index 655a5fe6..d226b417 100644 --- a/homematicip/aio/class_maps.py +++ b/homematicip/aio/class_maps.py @@ -34,7 +34,8 @@ DeviceType.ROTARY_HANDLE_SENSOR: AsyncRotaryHandleSensor, DeviceType.MOTION_DETECTOR_PUSH_BUTTON: AsyncMotionDetectorPushButton, DeviceType.WATER_SENSOR: AsyncWaterSensor, - DeviceType.SHUTTER_CONTACT_MAGNETIC: AsyncShutterContact + DeviceType.SHUTTER_CONTACT_MAGNETIC: AsyncShutterContact, + DeviceType.FULL_FLUSH_DIMMER : AsyncFullFlushDimmer } TYPE_GROUP_MAP = { diff --git a/homematicip/aio/device.py b/homematicip/aio/device.py index 5ab38fa5..ad158774 100644 --- a/homematicip/aio/device.py +++ b/homematicip/aio/device.py @@ -173,6 +173,9 @@ class AsyncPluggableDimmer(AsyncDimmer): class AsyncBrandDimmer(AsyncDimmer): """HmIP-BDT Brand Dimmer""" +class AsyncFullFlushDimmer(AsyncDimmer): + """HmIP-FDT Dimming Actuator flush-mount""" + class AsyncWeatherSensor(WeatherSensor, AsyncDevice): """ HmIP-SWO-B """ diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index 57877d36..3badc685 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -168,6 +168,7 @@ class DeviceType(AutoNameEnum): MOTION_DETECTOR_PUSH_BUTTON = auto() WATER_SENSOR = auto() SHUTTER_CONTACT_MAGNETIC = auto() + FULL_FLUSH_DIMMER = auto() class GroupType(AutoNameEnum): GROUP = auto() @@ -234,8 +235,14 @@ class EventType(AutoNameEnum): class MotionDetectionSendInterval(AutoNameEnum): - SECONDS_30 = auto() - SECONDS_60 = auto() - SECONDS_120 = auto() - SECONDS_240 = auto() - SECONDS_480 = auto() \ No newline at end of file + SECONDS_30 = auto() + SECONDS_60 = auto() + SECONDS_120 = auto() + SECONDS_240 = auto() + SECONDS_480 = auto() + +class SmokeDetectorAlarmType(AutoNameEnum): + IDLE_OFF = auto() + PRIMARY_ALARM = auto() + INTRUSION_ALARM = auto() + SECONDARY_ALARM = auto() \ No newline at end of file diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index 4e3cc6b4..456d13ec 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -40,7 +40,8 @@ DeviceType.FULL_FLUSH_SWITCH_MEASURING: FullFlushSwitchMeasuring, DeviceType.MOTION_DETECTOR_PUSH_BUTTON: MotionDetectorPushButton, DeviceType.WATER_SENSOR: WaterSensor, - DeviceType.SHUTTER_CONTACT_MAGNETIC: ShutterContact + DeviceType.SHUTTER_CONTACT_MAGNETIC: ShutterContact, + DeviceType.FULL_FLUSH_DIMMER : FullFlushDimmer } TYPE_GROUP_MAP = { diff --git a/homematicip/device.py b/homematicip/device.py index c9e669bf..fedc6531 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -302,7 +302,7 @@ def from_json(self, js): super().from_json(js) c = get_functional_channel("SMOKE_DETECTOR_CHANNEL", js) if c: - self.smokeDetectorAlarmType = c["smokeDetectorAlarmType"] + self.smokeDetectorAlarmType = SmokeDetectorAlarmType.from_str(c["smokeDetectorAlarmType"]) def __str__(self): return "{}: smokeDetectorAlarmType({})".format(super().__str__(), @@ -550,6 +550,8 @@ class PluggableDimmer(Dimmer): class BrandDimmer(Dimmer): """HmIP-BDT Brand Dimmer""" +class FullFlushDimmer(Dimmer): + """HmIP-FDT Dimming Actuator flush-mount""" class WeatherSensor(Device): """ HmIP-SWO-B """ diff --git a/tests/test_devices.py b/tests/test_devices.py index a03f6d8d..6498f751 100644 --- a/tests/test_devices.py +++ b/tests/test_devices.py @@ -108,7 +108,7 @@ def test_smoke_detector(fake_home : Home): assert d.rssiDeviceValue == -54 assert d.rssiPeerValue == None assert d.unreach == False - assert d.smokeDetectorAlarmType == "IDLE_OFF" + assert d.smokeDetectorAlarmType == SmokeDetectorAlarmType.IDLE_OFF assert d.availableFirmwareVersion == "0.0.0" assert d.firmwareVersion == "1.0.11" a,b,c= [ int(i) for i in d.firmwareVersion.split('.') ] @@ -490,4 +490,8 @@ def test_motion_detector_indoor(fake_home:Home): assert d.motionBufferActive == False assert d.motionDetected == True assert d.motionDetectionSendInterval == MotionDetectionSendInterval.SECONDS_480 - assert d.numberOfBrightnessMeasurements == 7 \ No newline at end of file + assert d.numberOfBrightnessMeasurements == 7 + + assert str(d) == ("HmIP-SMI Wohnzimmer lowbat(False) unreach(False) rssiDeviceValue(-56) rssiPeerValue(-52) configPending(False) " + "dutyCycle(False): sabotage(False) motionDetected(True) illumination(0.1) motionBufferActive(False) " + "motionDetected(True) motionDetectionSendInterval(SECONDS_480) numberOfBrightnessMeasurements(7)") \ No newline at end of file From b2aabd681f1f38dec012d6c6cdbad27ac3d63bda Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Fri, 14 Dec 2018 18:51:11 +0100 Subject: [PATCH 03/21] added LiveUpdateState to Device class --- hmip_cli.py | 4 +- homematicip/base/enums.py | 483 +++++++++++++++-------------- homematicip/class_maps.py | 196 ++++++------ homematicip/device.py | 2 + tests/json_data/home.json | 34 +- tests/json_data/unknown_types.json | 3 +- 6 files changed, 382 insertions(+), 340 deletions(-) diff --git a/hmip_cli.py b/hmip_cli.py index d2fc6919..923970ff 100644 --- a/hmip_cli.py +++ b/hmip_cli.py @@ -229,9 +229,9 @@ def main(): home.updateState)) sortedDevices = sorted(home.devices, key=attrgetter('deviceType', 'label')) for d in sortedDevices: - print("{:45s} - Firmware: {:6} - Available Firmware: {:6} UpdateState: {}".format(d.label, d.firmwareVersion, + print("{:45s} - Firmware: {:6} - Available Firmware: {:6} UpdateState: {} LiveUpdateState: {}".format(d.label, d.firmwareVersion, d.availableFirmwareVersion if d.availableFirmwareVersion is not None else "None", - d.updateState)) + d.updateState, d.liveUpdateState)) if args.list_rssi: command_entered = True diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index 3badc685..cb9fd4c2 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -1,240 +1,241 @@ -# coding=utf-8 -from aenum import auto, Enum - -class AutoNameEnum(Enum): - """ auto() will generate the name of the attribute as value """ - def _generate_next_value_(name, start, count, last_values): - return name - def __str__(self): - return self.value - - @classmethod - def from_str(cls, text): - if text is None: - return None - return cls(text) - - -class AcousticAlarmTiming(AutoNameEnum): - PERMANENT = auto() - THREE_MINUTES = auto() - SIX_MINUTES = auto() - ONCE_PER_MINUTE = auto() - -class WaterAlarmTrigger(AutoNameEnum): - NO_ALARM = auto() - MOISTURE_DETECTION = auto() - WATER_DETECTION = auto() - WATER_MOISTURE_DETECTION = auto() - -class AcousticAlarmSignal(AutoNameEnum): - DISABLE_ACOUSTIC_SIGNAL = auto() - FREQUENCY_RISING = auto() - FREQUENCY_FALLING = auto() - FREQUENCY_RISING_AND_FALLING = auto() - FREQUENCY_ALTERNATING_LOW_HIGH = auto() - FREQUENCY_ALTERNATING_LOW_MID_HIGH = auto() - FREQUENCY_HIGHON_OFF = auto() - FREQUENCY_HIGHON_LONGOFF = auto() - FREQUENCY_LOWON_OFF_HIGHON_OFF = auto() - FREQUENCY_LOWON_LONGOFF_HIGHON_LONGOFF = auto() - -class ClimateControlDisplay(AutoNameEnum): - ACTUAL = auto() - SETPOINT = auto() - ACTUAL_HUMIDITY = auto() - -class WindowState(AutoNameEnum): - OPEN = auto() - CLOSED = auto() - TILTED = auto() - -class ValveState(AutoNameEnum): - STATE_NOT_AVAILABLE = auto() - RUN_TO_START = auto() - WAIT_FOR_ADAPTION = auto() - ADAPTION_IN_PROGRESS = auto() - ADAPTION_DONE = auto() - TOO_TIGHT = auto() - ADJUSTMENT_TOO_BIG = auto() - ADJUSTMENT_TOO_SMALL = auto() - ERROR_POSITION = auto() - -class HeatingValveType(AutoNameEnum): - NORMALLY_CLOSE = auto() - NORMALLY_OPEN = auto() - -class RGBColorState(AutoNameEnum): - BLACK = auto() - BLUE = auto() - GREEN = auto() - TURQUOISE = auto() - RED = auto() - PURPLE = auto() - YELLOW = auto() - WHITE = auto() - -class DeviceUpdateStrategy(AutoNameEnum): - MANUALLY = auto() - AUTOMATICALLY_IF_POSSIBLE = auto() - -class ApExchangeState(AutoNameEnum): - NONE = auto() - REQUESTED = auto() - IN_PROGRESS = auto() - DONE = auto() - REJECTED = auto() - -class HomeUpdateState(AutoNameEnum): - UP_TO_DATE = auto() - UPDATE_AVAILABLE = auto() - PERFORM_UPDATE_SENT = auto() - PERFORMING_UPDATE = auto() - -class WeatherCondition(AutoNameEnum): - CLEAR = auto() - LIGHT_CLOUDY = auto() - CLOUDY = auto() - CLOUDY_WITH_RAIN = auto() - CLOUDY_WITH_SNOW_RAIN = auto() - HEAVILY_CLOUDY = auto() - HEAVILY_CLOUDY_WITH_RAIN = auto() - HEAVILY_CLOUDY_WITH_STRONG_RAIN = auto() - HEAVILY_CLOUDY_WITH_SNOW = auto() - HEAVILY_CLOUDY_WITH_SNOW_RAIN = auto() - HEAVILY_CLOUDY_WITH_THUNDER = auto() - HEAVILY_CLOUDY_WITH_RAIN_AND_THUNDER = auto() - FOGGY = auto() - UNKNOWN = auto() - -class WeatherDayTime(AutoNameEnum): - DAY = auto() - TWILIGHT = auto() - NIGHT = auto() - -class AbsenceType(AutoNameEnum): - NOT_ABSENT = auto() - PERIOD = auto() - PERMANENT = auto() - VACATION = auto() - PARTY = auto() - -class EcoDuration(AutoNameEnum): - ONE = auto() - TWO = auto() - FOUR = auto() - SIX = auto() - PERMANENT = auto() - - -class SecurityZoneActivationMode(AutoNameEnum): - ACTIVATION_WITH_DEVICE_IGNORELIST = auto() - ACTIVATION_IF_ALL_IN_VALID_STATE = auto() - -class ClientType(AutoNameEnum): - APP = auto() - C2C = auto() - -class DeviceType(AutoNameEnum): - DEVICE = auto() - FULL_FLUSH_SHUTTER = auto() - PLUGABLE_SWITCH = auto() - KEY_REMOTE_CONTROL_ALARM = auto() - MOTION_DETECTOR_INDOOR = auto() - ALARM_SIREN_INDOOR = auto() - PUSH_BUTTON = auto() - TEMPERATURE_HUMIDITY_SENSOR_DISPLAY = auto() - PLUGABLE_SWITCH_MEASURING = auto() - FLOOR_TERMINAL_BLOCK_6 = auto() - SMOKE_DETECTOR = auto() - WALL_MOUNTED_THERMOSTAT_PRO = auto() - SHUTTER_CONTACT = auto() - HEATING_THERMOSTAT = auto() - SHUTTER_CONTACT_INVISIBLE = auto() - BRAND_WALL_MOUNTED_THERMOSTAT = auto() - TEMPERATURE_HUMIDITY_SENSOR = auto() - BRAND_SHUTTER = auto() - PRECENCE_DETECTOR_INDOOR = auto() - PLUGGABLE_DIMMER = auto() - BRAND_DIMMER = auto() - BRAND_SWITCH_MEASURING = auto() - PRINTED_CIRCUIT_BOARD_SWITCH_BATTERY = auto() - ROOM_CONTROL_DEVICE = auto() - TEMPERATURE_HUMIDITY_SENSOR_OUTDOOR = auto() - WEATHER_SENSOR = auto() - WEATHER_SENSOR_PRO = auto() - ROTARY_HANDLE_SENSOR = auto() - FULL_FLUSH_SWITCH_MEASURING = auto() - MOTION_DETECTOR_PUSH_BUTTON = auto() - WATER_SENSOR = auto() - SHUTTER_CONTACT_MAGNETIC = auto() - FULL_FLUSH_DIMMER = auto() - -class GroupType(AutoNameEnum): - GROUP = auto() - EXTENDED_LINKED_SHUTTER = auto() - SHUTTER_WIND_PROTECTION_RULE = auto() - LOCK_OUT_PROTECTION_RULE = auto() - SMOKE_ALARM_DETECTION_RULE = auto() - OVER_HEAT_PROTECTION_RULE = auto() - SWITCHING_PROFILE = auto() - HEATING_COOLING_DEMAND_PUMP = auto() - HEATING_COOLING_DEMAND_BOILER = auto() - HEATING_DEHUMIDIFIER = auto() - HEATING_EXTERNAL_CLOCK = auto() - HEATING_COOLING_DEMAND = auto() - HEATING = auto() - SECURITY_ZONE = auto() - INBOX = auto() - HEATING_CHANGEOVER = auto() - HEATING_TEMPERATURE_LIMITER = auto() - HEATING_HUMIDITY_LIMITER = auto() - ALARM_SWITCHING = auto() - LINKED_SWITCHING = auto() - EXTENDED_LINKED_SWITCHING = auto() - SWITCHING = auto() - SECURITY = auto() - ENVIRONMENT = auto() - -class SecurityEventType(AutoNameEnum): - SENSOR_EVENT = auto() - ACCESS_POINT_DISCONNECTED = auto() - ACCESS_POINT_CONNECTED = auto() - ACTIVATION_CHANGED = auto() - SILENCE_CHANGED = auto() - SABOTAGE = auto() - MOISTURE_DETECTION_EVENT = auto() - SMOKE_ALARM = auto() - EXTERNAL_TRIGGERED = auto() - OFFLINE_ALARM = auto() - WATER_DETECTION_EVENT = auto() - MAINS_FAILURE_EVENT = auto() - OFFLINE_WATER_DETECTION_EVENT = auto() - -class AutomationRuleType(AutoNameEnum): - SIMPLE = auto() - -class FunctionalHomeType(AutoNameEnum): - INDOOR_CLIMATE = auto() - LIGHT_AND_SHADOW = auto() - SECURITY_AND_ALARM = auto() - WEATHER_AND_ENVIRONMENT = auto() - -class EventType(AutoNameEnum): - SECURITY_JOURNAL_CHANGED = auto() - GROUP_ADDED = auto() - GROUP_REMOVED = auto() - DEVICE_REMOVED = auto() - DEVICE_CHANGED = auto() - DEVICE_ADDED = auto() - CLIENT_REMOVED = auto() - CLIENT_CHANGED = auto() - CLIENT_ADDED = auto() - HOME_CHANGED = auto() - GROUP_CHANGED = auto() - - -class MotionDetectionSendInterval(AutoNameEnum): +# coding=utf-8 +from aenum import auto, Enum + +class AutoNameEnum(Enum): + """ auto() will generate the name of the attribute as value """ + def _generate_next_value_(name, start, count, last_values): + return name + def __str__(self): + return self.value + + @classmethod + def from_str(cls, text): + if text is None: + return None + return cls(text) + + +class AcousticAlarmTiming(AutoNameEnum): + PERMANENT = auto() + THREE_MINUTES = auto() + SIX_MINUTES = auto() + ONCE_PER_MINUTE = auto() + +class WaterAlarmTrigger(AutoNameEnum): + NO_ALARM = auto() + MOISTURE_DETECTION = auto() + WATER_DETECTION = auto() + WATER_MOISTURE_DETECTION = auto() + +class AcousticAlarmSignal(AutoNameEnum): + DISABLE_ACOUSTIC_SIGNAL = auto() + FREQUENCY_RISING = auto() + FREQUENCY_FALLING = auto() + FREQUENCY_RISING_AND_FALLING = auto() + FREQUENCY_ALTERNATING_LOW_HIGH = auto() + FREQUENCY_ALTERNATING_LOW_MID_HIGH = auto() + FREQUENCY_HIGHON_OFF = auto() + FREQUENCY_HIGHON_LONGOFF = auto() + FREQUENCY_LOWON_OFF_HIGHON_OFF = auto() + FREQUENCY_LOWON_LONGOFF_HIGHON_LONGOFF = auto() + +class ClimateControlDisplay(AutoNameEnum): + ACTUAL = auto() + SETPOINT = auto() + ACTUAL_HUMIDITY = auto() + +class WindowState(AutoNameEnum): + OPEN = auto() + CLOSED = auto() + TILTED = auto() + +class ValveState(AutoNameEnum): + STATE_NOT_AVAILABLE = auto() + RUN_TO_START = auto() + WAIT_FOR_ADAPTION = auto() + ADAPTION_IN_PROGRESS = auto() + ADAPTION_DONE = auto() + TOO_TIGHT = auto() + ADJUSTMENT_TOO_BIG = auto() + ADJUSTMENT_TOO_SMALL = auto() + ERROR_POSITION = auto() + +class HeatingValveType(AutoNameEnum): + NORMALLY_CLOSE = auto() + NORMALLY_OPEN = auto() + +class RGBColorState(AutoNameEnum): + BLACK = auto() + BLUE = auto() + GREEN = auto() + TURQUOISE = auto() + RED = auto() + PURPLE = auto() + YELLOW = auto() + WHITE = auto() + +class DeviceUpdateStrategy(AutoNameEnum): + MANUALLY = auto() + AUTOMATICALLY_IF_POSSIBLE = auto() + +class ApExchangeState(AutoNameEnum): + NONE = auto() + REQUESTED = auto() + IN_PROGRESS = auto() + DONE = auto() + REJECTED = auto() + +class HomeUpdateState(AutoNameEnum): + UP_TO_DATE = auto() + UPDATE_AVAILABLE = auto() + PERFORM_UPDATE_SENT = auto() + PERFORMING_UPDATE = auto() + +class WeatherCondition(AutoNameEnum): + CLEAR = auto() + LIGHT_CLOUDY = auto() + CLOUDY = auto() + CLOUDY_WITH_RAIN = auto() + CLOUDY_WITH_SNOW_RAIN = auto() + HEAVILY_CLOUDY = auto() + HEAVILY_CLOUDY_WITH_RAIN = auto() + HEAVILY_CLOUDY_WITH_STRONG_RAIN = auto() + HEAVILY_CLOUDY_WITH_SNOW = auto() + HEAVILY_CLOUDY_WITH_SNOW_RAIN = auto() + HEAVILY_CLOUDY_WITH_THUNDER = auto() + HEAVILY_CLOUDY_WITH_RAIN_AND_THUNDER = auto() + FOGGY = auto() + UNKNOWN = auto() + +class WeatherDayTime(AutoNameEnum): + DAY = auto() + TWILIGHT = auto() + NIGHT = auto() + +class AbsenceType(AutoNameEnum): + NOT_ABSENT = auto() + PERIOD = auto() + PERMANENT = auto() + VACATION = auto() + PARTY = auto() + +class EcoDuration(AutoNameEnum): + ONE = auto() + TWO = auto() + FOUR = auto() + SIX = auto() + PERMANENT = auto() + + +class SecurityZoneActivationMode(AutoNameEnum): + ACTIVATION_WITH_DEVICE_IGNORELIST = auto() + ACTIVATION_IF_ALL_IN_VALID_STATE = auto() + +class ClientType(AutoNameEnum): + APP = auto() + C2C = auto() + +class DeviceType(AutoNameEnum): + DEVICE = auto() + FULL_FLUSH_SHUTTER = auto() + PLUGABLE_SWITCH = auto() + KEY_REMOTE_CONTROL_ALARM = auto() + MOTION_DETECTOR_INDOOR = auto() + ALARM_SIREN_INDOOR = auto() + PUSH_BUTTON = auto() + TEMPERATURE_HUMIDITY_SENSOR_DISPLAY = auto() + PLUGABLE_SWITCH_MEASURING = auto() + FLOOR_TERMINAL_BLOCK_6 = auto() + SMOKE_DETECTOR = auto() + WALL_MOUNTED_THERMOSTAT_PRO = auto() + SHUTTER_CONTACT = auto() + HEATING_THERMOSTAT = auto() + SHUTTER_CONTACT_INVISIBLE = auto() + BRAND_WALL_MOUNTED_THERMOSTAT = auto() + TEMPERATURE_HUMIDITY_SENSOR = auto() + BRAND_SHUTTER = auto() + PRECENCE_DETECTOR_INDOOR = auto() + PLUGGABLE_DIMMER = auto() + BRAND_DIMMER = auto() + BRAND_SWITCH_MEASURING = auto() + PRINTED_CIRCUIT_BOARD_SWITCH_BATTERY = auto() + ROOM_CONTROL_DEVICE = auto() + TEMPERATURE_HUMIDITY_SENSOR_OUTDOOR = auto() + WEATHER_SENSOR = auto() + WEATHER_SENSOR_PRO = auto() + ROTARY_HANDLE_SENSOR = auto() + FULL_FLUSH_SWITCH_MEASURING = auto() + MOTION_DETECTOR_PUSH_BUTTON = auto() + WATER_SENSOR = auto() + SHUTTER_CONTACT_MAGNETIC = auto() + FULL_FLUSH_DIMMER = auto() + PUSH_BUTTON_6 = auto() + +class GroupType(AutoNameEnum): + GROUP = auto() + EXTENDED_LINKED_SHUTTER = auto() + SHUTTER_WIND_PROTECTION_RULE = auto() + LOCK_OUT_PROTECTION_RULE = auto() + SMOKE_ALARM_DETECTION_RULE = auto() + OVER_HEAT_PROTECTION_RULE = auto() + SWITCHING_PROFILE = auto() + HEATING_COOLING_DEMAND_PUMP = auto() + HEATING_COOLING_DEMAND_BOILER = auto() + HEATING_DEHUMIDIFIER = auto() + HEATING_EXTERNAL_CLOCK = auto() + HEATING_COOLING_DEMAND = auto() + HEATING = auto() + SECURITY_ZONE = auto() + INBOX = auto() + HEATING_CHANGEOVER = auto() + HEATING_TEMPERATURE_LIMITER = auto() + HEATING_HUMIDITY_LIMITER = auto() + ALARM_SWITCHING = auto() + LINKED_SWITCHING = auto() + EXTENDED_LINKED_SWITCHING = auto() + SWITCHING = auto() + SECURITY = auto() + ENVIRONMENT = auto() + +class SecurityEventType(AutoNameEnum): + SENSOR_EVENT = auto() + ACCESS_POINT_DISCONNECTED = auto() + ACCESS_POINT_CONNECTED = auto() + ACTIVATION_CHANGED = auto() + SILENCE_CHANGED = auto() + SABOTAGE = auto() + MOISTURE_DETECTION_EVENT = auto() + SMOKE_ALARM = auto() + EXTERNAL_TRIGGERED = auto() + OFFLINE_ALARM = auto() + WATER_DETECTION_EVENT = auto() + MAINS_FAILURE_EVENT = auto() + OFFLINE_WATER_DETECTION_EVENT = auto() + +class AutomationRuleType(AutoNameEnum): + SIMPLE = auto() + +class FunctionalHomeType(AutoNameEnum): + INDOOR_CLIMATE = auto() + LIGHT_AND_SHADOW = auto() + SECURITY_AND_ALARM = auto() + WEATHER_AND_ENVIRONMENT = auto() + +class EventType(AutoNameEnum): + SECURITY_JOURNAL_CHANGED = auto() + GROUP_ADDED = auto() + GROUP_REMOVED = auto() + DEVICE_REMOVED = auto() + DEVICE_CHANGED = auto() + DEVICE_ADDED = auto() + CLIENT_REMOVED = auto() + CLIENT_CHANGED = auto() + CLIENT_ADDED = auto() + HOME_CHANGED = auto() + GROUP_CHANGED = auto() + + +class MotionDetectionSendInterval(AutoNameEnum): SECONDS_30 = auto() SECONDS_60 = auto() SECONDS_120 = auto() @@ -245,4 +246,10 @@ class SmokeDetectorAlarmType(AutoNameEnum): IDLE_OFF = auto() PRIMARY_ALARM = auto() INTRUSION_ALARM = auto() - SECONDARY_ALARM = auto() \ No newline at end of file + SECONDARY_ALARM = auto() + +class LiveUpdateState(AutoNameEnum): + UP_TO_DATE = auto() + UPDATE_AVAILABLE = auto() + UPDATE_INCOMPLETE = auto() + LIVE_UPDATE_NOT_SUPPORTED = auto() \ No newline at end of file diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index 456d13ec..298ab6b7 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -1,99 +1,99 @@ -from homematicip.base.enums import * - -from homematicip.device import * - -from homematicip.group import * - -from homematicip.securityEvent import * -from homematicip.rule import * -from homematicip.functionalHomes import * - -TYPE_CLASS_MAP = { - DeviceType.DEVICE: Device, - DeviceType.HEATING_THERMOSTAT: HeatingThermostat, - DeviceType.SHUTTER_CONTACT: ShutterContact, - DeviceType.SHUTTER_CONTACT_INVISIBLE: ShutterContact, - DeviceType.WALL_MOUNTED_THERMOSTAT_PRO: WallMountedThermostatPro, - DeviceType.BRAND_WALL_MOUNTED_THERMOSTAT: WallMountedThermostatPro, - DeviceType.SMOKE_DETECTOR: SmokeDetector, - DeviceType.FLOOR_TERMINAL_BLOCK_6: FloorTerminalBlock6, - DeviceType.PLUGABLE_SWITCH_MEASURING: PlugableSwitchMeasuring, - DeviceType.TEMPERATURE_HUMIDITY_SENSOR_DISPLAY: TemperatureHumiditySensorDisplay, - DeviceType.ROOM_CONTROL_DEVICE: TemperatureHumiditySensorDisplay, - DeviceType.TEMPERATURE_HUMIDITY_SENSOR: TemperatureHumiditySensorWithoutDisplay, - DeviceType.PUSH_BUTTON: PushButton, - DeviceType.ALARM_SIREN_INDOOR: AlarmSirenIndoor, - DeviceType.MOTION_DETECTOR_INDOOR: MotionDetectorIndoor, - DeviceType.KEY_REMOTE_CONTROL_ALARM: KeyRemoteControlAlarm, - DeviceType.PLUGABLE_SWITCH: PlugableSwitch, - DeviceType.FULL_FLUSH_SHUTTER: FullFlushShutter, - DeviceType.BRAND_SHUTTER: FullFlushShutter, - DeviceType.PRECENCE_DETECTOR_INDOOR: PresenceDetectorIndoor, - DeviceType.PLUGGABLE_DIMMER: PluggableDimmer, - DeviceType.BRAND_DIMMER: BrandDimmer, - DeviceType.BRAND_SWITCH_MEASURING: BrandSwitchMeasuring, - DeviceType.PRINTED_CIRCUIT_BOARD_SWITCH_BATTERY: PrintedCircuitBoardSwitchBattery, - DeviceType.TEMPERATURE_HUMIDITY_SENSOR_OUTDOOR: TemperatureHumiditySensorOutdoor, - DeviceType.WEATHER_SENSOR: WeatherSensor, - DeviceType.WEATHER_SENSOR_PRO: WeatherSensorPro, - DeviceType.ROTARY_HANDLE_SENSOR: RotaryHandleSensor, - DeviceType.FULL_FLUSH_SWITCH_MEASURING: FullFlushSwitchMeasuring, - DeviceType.MOTION_DETECTOR_PUSH_BUTTON: MotionDetectorPushButton, - DeviceType.WATER_SENSOR: WaterSensor, +from homematicip.base.enums import * + +from homematicip.device import * + +from homematicip.group import * + +from homematicip.securityEvent import * +from homematicip.rule import * +from homematicip.functionalHomes import * + +TYPE_CLASS_MAP = { + DeviceType.DEVICE: Device, + DeviceType.HEATING_THERMOSTAT: HeatingThermostat, + DeviceType.SHUTTER_CONTACT: ShutterContact, + DeviceType.SHUTTER_CONTACT_INVISIBLE: ShutterContact, + DeviceType.WALL_MOUNTED_THERMOSTAT_PRO: WallMountedThermostatPro, + DeviceType.BRAND_WALL_MOUNTED_THERMOSTAT: WallMountedThermostatPro, + DeviceType.SMOKE_DETECTOR: SmokeDetector, + DeviceType.FLOOR_TERMINAL_BLOCK_6: FloorTerminalBlock6, + DeviceType.PLUGABLE_SWITCH_MEASURING: PlugableSwitchMeasuring, + DeviceType.TEMPERATURE_HUMIDITY_SENSOR_DISPLAY: TemperatureHumiditySensorDisplay, + DeviceType.ROOM_CONTROL_DEVICE: TemperatureHumiditySensorDisplay, + DeviceType.TEMPERATURE_HUMIDITY_SENSOR: TemperatureHumiditySensorWithoutDisplay, + DeviceType.PUSH_BUTTON: PushButton, + DeviceType.ALARM_SIREN_INDOOR: AlarmSirenIndoor, + DeviceType.MOTION_DETECTOR_INDOOR: MotionDetectorIndoor, + DeviceType.KEY_REMOTE_CONTROL_ALARM: KeyRemoteControlAlarm, + DeviceType.PLUGABLE_SWITCH: PlugableSwitch, + DeviceType.FULL_FLUSH_SHUTTER: FullFlushShutter, + DeviceType.BRAND_SHUTTER: FullFlushShutter, + DeviceType.PRECENCE_DETECTOR_INDOOR: PresenceDetectorIndoor, + DeviceType.PLUGGABLE_DIMMER: PluggableDimmer, + DeviceType.BRAND_DIMMER: BrandDimmer, + DeviceType.BRAND_SWITCH_MEASURING: BrandSwitchMeasuring, + DeviceType.PRINTED_CIRCUIT_BOARD_SWITCH_BATTERY: PrintedCircuitBoardSwitchBattery, + DeviceType.TEMPERATURE_HUMIDITY_SENSOR_OUTDOOR: TemperatureHumiditySensorOutdoor, + DeviceType.WEATHER_SENSOR: WeatherSensor, + DeviceType.WEATHER_SENSOR_PRO: WeatherSensorPro, + DeviceType.ROTARY_HANDLE_SENSOR: RotaryHandleSensor, + DeviceType.FULL_FLUSH_SWITCH_MEASURING: FullFlushSwitchMeasuring, + DeviceType.MOTION_DETECTOR_PUSH_BUTTON: MotionDetectorPushButton, + DeviceType.WATER_SENSOR: WaterSensor, DeviceType.SHUTTER_CONTACT_MAGNETIC: ShutterContact, - DeviceType.FULL_FLUSH_DIMMER : FullFlushDimmer -} - -TYPE_GROUP_MAP = { - GroupType.GROUP: Group, - GroupType.SECURITY: SecurityGroup, - GroupType.SWITCHING: SwitchingGroup, - GroupType.EXTENDED_LINKED_SWITCHING: ExtendedLinkedSwitchingGroup, - GroupType.LINKED_SWITCHING: LinkedSwitchingGroup, - GroupType.ALARM_SWITCHING: AlarmSwitchingGroup, - GroupType.HEATING_HUMIDITY_LIMITER: HeatingHumidyLimiterGroup, - GroupType.HEATING_TEMPERATURE_LIMITER: HeatingTemperatureLimiterGroup, - GroupType.HEATING_CHANGEOVER: HeatingChangeoverGroup, - GroupType.INBOX: InboxGroup, - GroupType.SECURITY_ZONE: SecurityZoneGroup, - GroupType.HEATING: HeatingGroup, - GroupType.HEATING_COOLING_DEMAND: HeatingCoolingDemandGroup, - GroupType.HEATING_EXTERNAL_CLOCK: HeatingExternalClockGroup, - GroupType.HEATING_DEHUMIDIFIER: HeatingDehumidifierGroup, - GroupType.HEATING_COOLING_DEMAND_BOILER: HeatingCoolingDemandBoilerGroup, - GroupType.HEATING_COOLING_DEMAND_PUMP: HeatingCoolingDemandPumpGroup, - GroupType.SWITCHING_PROFILE: SwitchingProfileGroup, - GroupType.OVER_HEAT_PROTECTION_RULE: OverHeatProtectionRule, - GroupType.SMOKE_ALARM_DETECTION_RULE: SmokeAlarmDetectionRule, - GroupType.LOCK_OUT_PROTECTION_RULE: LockOutProtectionRule, - GroupType.SHUTTER_WIND_PROTECTION_RULE: ShutterWindProtectionRule, - GroupType.EXTENDED_LINKED_SHUTTER: ExtendedLinkedShutterGroup, - GroupType.ENVIRONMENT:EnvironmentGroup -} - -TYPE_SECURITY_EVENT_MAP = { - SecurityEventType.SILENCE_CHANGED: SilenceChangedEvent, - SecurityEventType.ACTIVATION_CHANGED: ActivationChangedEvent, - SecurityEventType.ACCESS_POINT_CONNECTED: AccessPointConnectedEvent, - SecurityEventType.ACCESS_POINT_DISCONNECTED: AccessPointDisconnectedEvent, - SecurityEventType.SENSOR_EVENT: SensorEvent, - SecurityEventType.SABOTAGE: SabotageEvent, - SecurityEventType.MOISTURE_DETECTION_EVENT : MoistureDetectionEvent, - SecurityEventType.SMOKE_ALARM : SmokeAlarmEvent, - SecurityEventType.EXTERNAL_TRIGGERED : ExternalTriggeredEvent, - SecurityEventType.OFFLINE_ALARM : OfflineAlarmEvent, - SecurityEventType.WATER_DETECTION_EVENT : WaterDetectionEvent, - SecurityEventType.MAINS_FAILURE_EVENT : MainsFailureEvent, - SecurityEventType.OFFLINE_WATER_DETECTION_EVENT : OfflineWaterDetectionEvent -} - -TYPE_RULE_MAP = { - AutomationRuleType.SIMPLE : SimpleRule -} - -TYPE_FUNCTIONALHOME_MAP = { - FunctionalHomeType.INDOOR_CLIMATE: IndoorClimateHome, - FunctionalHomeType.WEATHER_AND_ENVIRONMENT: WeatherAndEnvironmentHome, - FunctionalHomeType.LIGHT_AND_SHADOW: LightAndShadowHome, - FunctionalHomeType.SECURITY_AND_ALARM: SecurityAndAlarmHome -} + DeviceType.FULL_FLUSH_DIMMER : FullFlushDimmer +} + +TYPE_GROUP_MAP = { + GroupType.GROUP: Group, + GroupType.SECURITY: SecurityGroup, + GroupType.SWITCHING: SwitchingGroup, + GroupType.EXTENDED_LINKED_SWITCHING: ExtendedLinkedSwitchingGroup, + GroupType.LINKED_SWITCHING: LinkedSwitchingGroup, + GroupType.ALARM_SWITCHING: AlarmSwitchingGroup, + GroupType.HEATING_HUMIDITY_LIMITER: HeatingHumidyLimiterGroup, + GroupType.HEATING_TEMPERATURE_LIMITER: HeatingTemperatureLimiterGroup, + GroupType.HEATING_CHANGEOVER: HeatingChangeoverGroup, + GroupType.INBOX: InboxGroup, + GroupType.SECURITY_ZONE: SecurityZoneGroup, + GroupType.HEATING: HeatingGroup, + GroupType.HEATING_COOLING_DEMAND: HeatingCoolingDemandGroup, + GroupType.HEATING_EXTERNAL_CLOCK: HeatingExternalClockGroup, + GroupType.HEATING_DEHUMIDIFIER: HeatingDehumidifierGroup, + GroupType.HEATING_COOLING_DEMAND_BOILER: HeatingCoolingDemandBoilerGroup, + GroupType.HEATING_COOLING_DEMAND_PUMP: HeatingCoolingDemandPumpGroup, + GroupType.SWITCHING_PROFILE: SwitchingProfileGroup, + GroupType.OVER_HEAT_PROTECTION_RULE: OverHeatProtectionRule, + GroupType.SMOKE_ALARM_DETECTION_RULE: SmokeAlarmDetectionRule, + GroupType.LOCK_OUT_PROTECTION_RULE: LockOutProtectionRule, + GroupType.SHUTTER_WIND_PROTECTION_RULE: ShutterWindProtectionRule, + GroupType.EXTENDED_LINKED_SHUTTER: ExtendedLinkedShutterGroup, + GroupType.ENVIRONMENT:EnvironmentGroup +} + +TYPE_SECURITY_EVENT_MAP = { + SecurityEventType.SILENCE_CHANGED: SilenceChangedEvent, + SecurityEventType.ACTIVATION_CHANGED: ActivationChangedEvent, + SecurityEventType.ACCESS_POINT_CONNECTED: AccessPointConnectedEvent, + SecurityEventType.ACCESS_POINT_DISCONNECTED: AccessPointDisconnectedEvent, + SecurityEventType.SENSOR_EVENT: SensorEvent, + SecurityEventType.SABOTAGE: SabotageEvent, + SecurityEventType.MOISTURE_DETECTION_EVENT : MoistureDetectionEvent, + SecurityEventType.SMOKE_ALARM : SmokeAlarmEvent, + SecurityEventType.EXTERNAL_TRIGGERED : ExternalTriggeredEvent, + SecurityEventType.OFFLINE_ALARM : OfflineAlarmEvent, + SecurityEventType.WATER_DETECTION_EVENT : WaterDetectionEvent, + SecurityEventType.MAINS_FAILURE_EVENT : MainsFailureEvent, + SecurityEventType.OFFLINE_WATER_DETECTION_EVENT : OfflineWaterDetectionEvent +} + +TYPE_RULE_MAP = { + AutomationRuleType.SIMPLE : SimpleRule +} + +TYPE_FUNCTIONALHOME_MAP = { + FunctionalHomeType.INDOOR_CLIMATE: IndoorClimateHome, + FunctionalHomeType.WEATHER_AND_ENVIRONMENT: WeatherAndEnvironmentHome, + FunctionalHomeType.LIGHT_AND_SHADOW: LightAndShadowHome, + FunctionalHomeType.SECURITY_AND_ALARM: SecurityAndAlarmHome +} diff --git a/homematicip/device.py b/homematicip/device.py index fedc6531..8ef70736 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -36,6 +36,7 @@ def __init__(self,connection): self.dutyCycle = False self.configPending = False self.permanentlyReachable = False + self.liveUpdateState = LiveUpdateState.LIVE_UPDATE_NOT_SUPPORTED def from_json(self, js): super().from_json(js) @@ -56,6 +57,7 @@ def from_json(self, js): self.manufacturerCode = js['manufacturerCode'] self.serializedGlobalTradeItemNumber = js['serializedGlobalTradeItemNumber'] self.permanentlyReachable = js["permanentlyReachable"] + self.liveUpdateState = LiveUpdateState.from_str(js["liveUpdateState"]) c = get_functional_channel("DEVICE_BASE", js) if c: diff --git a/tests/json_data/home.json b/tests/json_data/home.json index 6dd662e4..1d5c5666 100644 --- a/tests/json_data/home.json +++ b/tests/json_data/home.json @@ -4,7 +4,7 @@ "homeId": "00000000-0000-0000-0000-000000000001", "id": "00000000-0000-0000-0000-000000000000", "label": "TEST-Client", - "clientType" : "APP" + "clientType": "APP" } }, "devices": { @@ -105,6 +105,7 @@ "id": "3014F7110000000000000050", "label": "Wassersensor", "lastStatusUpdate": 1530802738493, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 353, "modelType": "HmIP-SWD", @@ -159,6 +160,7 @@ "id": "3014F7110000000000000000", "label": "Balkontüre", "lastStatusUpdate": 1524516526498, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 258, "modelType": "HMIP-SWDO", @@ -212,6 +214,7 @@ "id": "3014F7110000000000000001", "label": "Fenster", "lastStatusUpdate": 1524515854304, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 258, "modelType": "HMIP-SWDO", @@ -265,6 +268,7 @@ "id": "3014F7110000000000000002", "label": "Balkonfenster", "lastStatusUpdate": 1524516088763, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 258, "modelType": "HMIP-SWDO", @@ -318,6 +322,7 @@ "id": "3014F7110000000000000003", "label": "Küche", "lastStatusUpdate": 1524514836466, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 258, "modelType": "HMIP-SWDO", @@ -371,6 +376,7 @@ "id": "3014F7110000000000000004", "label": "Fenster", "lastStatusUpdate": 1524512404032, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 258, "modelType": "HMIP-SWDO", @@ -424,6 +430,7 @@ "id": "3014F7110000000000000005", "label": "Wohnzimmer", "lastStatusUpdate": 0, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 258, "modelType": "HMIP-SWDO", @@ -476,6 +483,7 @@ "id": "3014F7110000000000000006", "label": "Wohnungstüre", "lastStatusUpdate": 1524516489316, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 258, "modelType": "HMIP-SWDO", @@ -528,6 +536,7 @@ "id": "3014F7110000000000000007", "label": "Vorzimmer", "lastStatusUpdate": 1524515489257, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 258, "modelType": "HMIP-SWDO", @@ -580,6 +589,7 @@ "id": "3014F7110000000000000008", "label": "Pc", "lastStatusUpdate": 1524516554056, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 262, "modelType": "HMIP-PSM", @@ -632,6 +642,7 @@ "id": "3014F7110000000000000009", "label": "Brunnen", "lastStatusUpdate": 1524515786303, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 262, "modelType": "HMIP-PSM", @@ -684,6 +695,7 @@ "id": "3014F7110000000000000010", "label": "Büro", "lastStatusUpdate": 1524513613922, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 262, "modelType": "HMIP-PSM", @@ -737,6 +749,7 @@ "id": "3014F7110000000000000011", "label": "Heizung", "lastStatusUpdate": 1524516360178, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 269, "modelType": "HMIP-eTRV", @@ -790,6 +803,7 @@ "id": "3014F7110000000000000012", "label": "Heizkörperthermostat", "lastStatusUpdate": 1524514105832, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 269, "modelType": "HMIP-eTRV", @@ -843,6 +857,7 @@ "id": "3014F7110000000000000013", "label": "Heizkörperthermostat", "lastStatusUpdate": 1524514007132, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 269, "modelType": "HMIP-eTRV", @@ -896,6 +911,7 @@ "id": "3014F7110000000000000014", "label": "Küche-Heizung", "lastStatusUpdate": 1524513898337, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 269, "modelType": "HMIP-eTRV", @@ -949,6 +965,7 @@ "id": "3014F7110000000000000015", "label": "Wohnzimmer-Heizung", "lastStatusUpdate": 1524513950325, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 269, "modelType": "HMIP-eTRV", @@ -1002,6 +1019,7 @@ "id": "3014F7110000000000000016", "label": "Heizkörperthermostat", "lastStatusUpdate": 1524514626157, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 269, "modelType": "HMIP-eTRV", @@ -1055,6 +1073,7 @@ "id": "3014F7110000000000000017", "label": "Balkon-Heizung", "lastStatusUpdate": 1524511331830, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 269, "modelType": "HMIP-eTRV", @@ -1105,6 +1124,7 @@ "id": "3014F7110000000000000018", "label": "Rauchwarnmelder", "lastStatusUpdate": 1524461072721, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 296, "modelType": "HmIP-SWSD", @@ -1155,6 +1175,7 @@ "id": "3014F7110000000000000019", "label": "Rauchwarnmelder", "lastStatusUpdate": 1524480981494, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 296, "modelType": "HmIP-SWSD", @@ -1205,6 +1226,7 @@ "id": "3014F7110000000000000020", "label": "Rauchwarnmelder", "lastStatusUpdate": 1524456324824, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 296, "modelType": "HmIP-SWSD", @@ -1255,6 +1277,7 @@ "id": "3014F7110000000000000021", "label": "Rauchwarnmelder", "lastStatusUpdate": 1524443129876, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 296, "modelType": "HmIP-SWSD", @@ -1308,6 +1331,7 @@ "id": "3014F7110000000000000022", "label": "Wandthermostat", "lastStatusUpdate": 1524516534382, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 297, "modelType": "HmIP-WTH-2", @@ -1361,6 +1385,7 @@ "id": "3014F7110000000000000023", "label": "Wandthermostat", "lastStatusUpdate": 1524516454116, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 297, "modelType": "HmIP-WTH-2", @@ -1414,6 +1439,7 @@ "id": "3014F7110000000000000024", "label": "Wandthermostat", "lastStatusUpdate": 1524516436601, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 297, "modelType": "HmIP-WTH-2", @@ -1467,6 +1493,7 @@ "id": "3014F7110000000000000025", "label": "Wandthermostat", "lastStatusUpdate": 1524516556479, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 297, "modelType": "HmIP-WTH-2", @@ -1532,6 +1559,7 @@ "id": "3014F711AAAA000000000001", "label": "Wettersensor - pro", "lastStatusUpdate": 1524513950325, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 352, "modelType": "HmIP-SWO-PR", @@ -1581,6 +1609,7 @@ "id": "3014F711AAAA000000000002", "label": "Temperatur- und Luftfeuchtigkeitssensor - außen", "lastStatusUpdate": 1524513950325, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 314, "modelType": "HmIP-STHO", @@ -1635,6 +1664,7 @@ "id": "3014F711AAAA000000000003", "label": "Wettersensor", "lastStatusUpdate": 1524513950325, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 350, "modelType": "HmIP-SWO-B", @@ -1681,6 +1711,7 @@ "id": "3014F711AAAA000000000004", "label": "Fenstergriffsensor", "lastStatusUpdate": 1524816385462, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 286, "modelType": "HmIP-SRH", @@ -1731,6 +1762,7 @@ "id": "3014F711AAAA000000000005", "label": "Schlafzimmerlicht", "lastStatusUpdate": 1524816385462, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 290, "modelType": "HmIP-BDT", diff --git a/tests/json_data/unknown_types.json b/tests/json_data/unknown_types.json index 931e668f..8fc93007 100644 --- a/tests/json_data/unknown_types.json +++ b/tests/json_data/unknown_types.json @@ -12,11 +12,12 @@ "availableFirmwareVersion": "0.0.0", "firmwareVersion": "1.0.2", "firmwareVersionInteger": "65538", - "functionalChannels": { }, + "functionalChannels": {}, "homeId": "00000000-0000-0000-0000-000000000001", "id": "3014F7110000000000000050", "label": "DUMMY_DEVICE", "lastStatusUpdate": 1530802738493, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", "manufacturerCode": 1, "modelId": 353, "modelType": "HmIP-DUMMY", From 283e5be817a9a6e92d6a31535dcf1664fdf4f072 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Fri, 14 Dec 2018 19:10:55 +0100 Subject: [PATCH 04/21] added PushButton6 --- homematicip/aio/class_maps.py | 3 +- homematicip/aio/device.py | 11 ++--- homematicip/class_maps.py | 3 +- homematicip/device.py | 8 +++ tests/json_data/home.json | 91 +++++++++++++++++++++++++++++++++++ tests/test_devices.py | 9 +++- 6 files changed, 114 insertions(+), 11 deletions(-) diff --git a/homematicip/aio/class_maps.py b/homematicip/aio/class_maps.py index d226b417..4ef52ec7 100644 --- a/homematicip/aio/class_maps.py +++ b/homematicip/aio/class_maps.py @@ -35,7 +35,8 @@ DeviceType.MOTION_DETECTOR_PUSH_BUTTON: AsyncMotionDetectorPushButton, DeviceType.WATER_SENSOR: AsyncWaterSensor, DeviceType.SHUTTER_CONTACT_MAGNETIC: AsyncShutterContact, - DeviceType.FULL_FLUSH_DIMMER : AsyncFullFlushDimmer + DeviceType.FULL_FLUSH_DIMMER : AsyncFullFlushDimmer, + DeviceType.PUSH_BUTTON_6 : AsyncPushButton6 } TYPE_GROUP_MAP = { diff --git a/homematicip/aio/device.py b/homematicip/aio/device.py index ad158774..6ba99453 100644 --- a/homematicip/aio/device.py +++ b/homematicip/aio/device.py @@ -1,13 +1,6 @@ import logging -from homematicip.device import Device, PlugableSwitch, PlugableSwitchMeasuring, \ - SabotageDevice, ShutterContact, OperationLockableDevice, HeatingThermostat, \ - TemperatureHumiditySensorWithoutDisplay, TemperatureHumiditySensorDisplay, \ - WallMountedThermostatPro, SmokeDetector, FloorTerminalBlock6, PushButton, AlarmSirenIndoor, \ - MotionDetectorIndoor, MotionDetectorPushButton, PresenceDetectorIndoor, KeyRemoteControlAlarm, FullFlushShutter, \ - Dimmer, PluggableDimmer, BrandSwitchMeasuring, FullFlushSwitchMeasuring, Switch, \ - WeatherSensor, WeatherSensorPro, RotaryHandleSensor, TemperatureHumiditySensorOutdoor, \ - WaterSensor +from homematicip.device import * from homematicip.base.enums import * ERROR_CODE = "errorCode" @@ -126,6 +119,8 @@ class AsyncFloorTerminalBlock6(FloorTerminalBlock6, AsyncDevice): class AsyncPushButton(PushButton, AsyncDevice): """ HMIP-WRC2 (Wall-mount Remote Control - 2-button) """ +class AsyncPushButton6(PushButton6, AsyncPushButton): + """ HMIP-WRC6 (Wall-mount Remote Control - 6-button) """ class AsyncAlarmSirenIndoor(AlarmSirenIndoor, AsyncSabotageDevice): """ HMIP-ASIR (Alarm Siren) """ diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index 298ab6b7..e538f11f 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -41,7 +41,8 @@ DeviceType.MOTION_DETECTOR_PUSH_BUTTON: MotionDetectorPushButton, DeviceType.WATER_SENSOR: WaterSensor, DeviceType.SHUTTER_CONTACT_MAGNETIC: ShutterContact, - DeviceType.FULL_FLUSH_DIMMER : FullFlushDimmer + DeviceType.FULL_FLUSH_DIMMER : FullFlushDimmer, + DeviceType.PUSH_BUTTON_6: PushButton6 } TYPE_GROUP_MAP = { diff --git a/homematicip/device.py b/homematicip/device.py index 8ef70736..4534b34a 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -410,6 +410,14 @@ class FullFlushSwitchMeasuring(SwitchMeasuring): class PushButton(Device): """ HMIP-WRC2 (Wall-mount Remote Control - 2-button) """ +class PushButton6(PushButton): + """ HMIP-WRC6 (Wall-mount Remote Control - 6-button) """ + + def from_json(self, js): + super().from_json(js) + #TODO: PUSH_BUTTON_6 has 6 functional Channels of "SINGLE_KEY_CHANNEL" + #They don't provide any information except for the groups. + #Maybe the functional channels should get there own class and be added as class member? class AlarmSirenIndoor(SabotageDevice): """ HMIP-ASIR (Alarm Siren) """ diff --git a/tests/json_data/home.json b/tests/json_data/home.json index 1d5c5666..0deb59d0 100644 --- a/tests/json_data/home.json +++ b/tests/json_data/home.json @@ -1771,6 +1771,97 @@ "serializedGlobalTradeItemNumber": "3014F711AAAA000000000005", "type": "BRAND_DIMMER", "updateState": "UP_TO_DATE" + }, + "3014F711BBBBBBBBBBBBB017": { + "availableFirmwareVersion": "1.0.19", + "firmwareVersion": "1.0.19", + "firmwareVersionInteger": 65555, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F711BBBBBBBBBBBBB017", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -61, + "rssiPeerValue": null, + "unreach": false + }, + "1": { + "deviceId": "3014F711BBBBBBBBBBBBB017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 1, + "groups": [ + ], + "index": 1, + "label": "" + }, + "2": { + "deviceId": "3014F711BBBBBBBBBBBBB017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 1, + "groups": [ + ], + "index": 2, + "label": "" + }, + "3": { + "deviceId": "3014F711BBBBBBBBBBBBB017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 2, + "groups": [ + ], + "index": 3, + "label": "" + }, + "4": { + "deviceId": "3014F711BBBBBBBBBBBBB017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 2, + "groups": [ + ], + "index": 4, + "label": "" + }, + "5": { + "deviceId": "3014F711BBBBBBBBBBBBB017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 3, + "groups": [ + ], + "index": 5, + "label": "" + }, + "6": { + "deviceId": "3014F711BBBBBBBBBBBBB017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 3, + "groups": [ + ], + "index": 6, + "label": "" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F711BBBBBBBBBBBBB017", + "label": "Wandtaster - 6-fach", + "lastStatusUpdate": 1544475961687, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 300, + "modelType": "HmIP-WRC6", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F711BBBBBBBBBBBBB017", + "type": "PUSH_BUTTON_6", + "updateState": "UP_TO_DATE" } }, "groups": { diff --git a/tests/test_devices.py b/tests/test_devices.py index 6498f751..d3d95bdc 100644 --- a/tests/test_devices.py +++ b/tests/test_devices.py @@ -494,4 +494,11 @@ def test_motion_detector_indoor(fake_home:Home): assert str(d) == ("HmIP-SMI Wohnzimmer lowbat(False) unreach(False) rssiDeviceValue(-56) rssiPeerValue(-52) configPending(False) " "dutyCycle(False): sabotage(False) motionDetected(True) illumination(0.1) motionBufferActive(False) " - "motionDetected(True) motionDetectionSendInterval(SECONDS_480) numberOfBrightnessMeasurements(7)") \ No newline at end of file + "motionDetected(True) motionDetectionSendInterval(SECONDS_480) numberOfBrightnessMeasurements(7)") + +def test_push_button_6(fake_home:Home): + d = PushButton6(fake_home._connection) + d = fake_home.search_device_by_id("3014F711BBBBBBBBBBBBB017") + + assert d.modelId == 300 + assert d.label == "Wandtaster - 6-fach" \ No newline at end of file From e538ade277b0d76e097cef90b1eec4b6e20a72d8 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Fri, 14 Dec 2018 19:25:06 +0100 Subject: [PATCH 05/21] added HMIP-RC8 (Remote Control - 8 buttons) updated Readme for the implemented devices --- README.rst | 213 +++++++++++++++++----------------- homematicip/aio/class_maps.py | 3 +- homematicip/aio/device.py | 3 + homematicip/base/enums.py | 1 + homematicip/class_maps.py | 3 +- homematicip/device.py | 5 +- tests/json_data/home.json | 111 ++++++++++++++++++ tests/test_devices.py | 9 +- 8 files changed, 240 insertions(+), 108 deletions(-) diff --git a/README.rst b/README.rst index addeee27..d381fc99 100644 --- a/README.rst +++ b/README.rst @@ -1,68 +1,68 @@ -homematicip-rest-api -==================== - -A **Python 3** wrapper for the homematicIP REST API (Access Point Based) -Since there is no official documentation about this API everything was -done via reverse engineering. Use at your own risk. - -|CircleCI| |PyPi| |codecov| |Average time to resolve an issue| |commits-since-latest-release| |donate-paypal| - -Installation -============ - -Just run **pip3 install homematicip** to get the package - -Usage -===== - -first run hmip_generate_auth_token.py (from the command line) to get an -auth token for your access point. it will generate a “config.ini” in -your current directory. The scripts will look for a config.ini in 3 -different locations depending on your OS. Copy the file to one of these -locations so that it will be accessable for the scripts. - -- General - - - current working directory - -- Windows - - - %APPDATA%:raw-latex:`\homematicip`-rest-api - - %PROGRAMDATA%:raw-latex:`\homematicip`-rest-api - -- Linux - - - ~/.homematicip-rest-api/ - - /etc/homematicip-rest-api/ - -- MAC OS - - - ~/Library/Preferences/homematicip-rest-api/ - - /Library/Application Support/homematicip-rest-api/ - -Examples -======== - -- hmip_cli.py for list devices,groups,securityJournal; set label, turn - switches on/off -- Sample Projects are under - https://github.com/coreGreenberet/homematicip-samples - -Implemented Stuff -================= - -- [X] generate authentication token -- [X] Read current state of the Environment -- [X] Weather -- [X] Location -- [X] Basic Informations( apversion, pinAssigned, timeZone, … ) -- [X] Devices (partly) -- [X] Client -- [X] Groups - -Devices: --------- - +homematicip-rest-api +==================== + +A **Python 3** wrapper for the homematicIP REST API (Access Point Based) +Since there is no official documentation about this API everything was +done via reverse engineering. Use at your own risk. + +|CircleCI| |PyPi| |codecov| |Average time to resolve an issue| |commits-since-latest-release| |donate-paypal| + +Installation +============ + +Just run **pip3 install homematicip** to get the package + +Usage +===== + +first run hmip_generate_auth_token.py (from the command line) to get an +auth token for your access point. it will generate a “config.ini” in +your current directory. The scripts will look for a config.ini in 3 +different locations depending on your OS. Copy the file to one of these +locations so that it will be accessable for the scripts. + +- General + + - current working directory + +- Windows + + - %APPDATA%:raw-latex:`\homematicip`-rest-api + - %PROGRAMDATA%:raw-latex:`\homematicip`-rest-api + +- Linux + + - ~/.homematicip-rest-api/ + - /etc/homematicip-rest-api/ + +- MAC OS + + - ~/Library/Preferences/homematicip-rest-api/ + - /Library/Application Support/homematicip-rest-api/ + +Examples +======== + +- hmip_cli.py for list devices,groups,securityJournal; set label, turn + switches on/off +- Sample Projects are under + https://github.com/coreGreenberet/homematicip-samples + +Implemented Stuff +================= + +- [X] generate authentication token +- [X] Read current state of the Environment +- [X] Weather +- [X] Location +- [X] Basic Informations( apversion, pinAssigned, timeZone, … ) +- [X] Devices (partly) +- [X] Client +- [X] Groups + +Devices: +-------- + - [X] HMIP-ASIR (Alarm Siren) - [X] HMIP-BROLL (Shutter Actuator - brand-mount) - [X] HMIP-BSM (Brand Switch and Meter) @@ -72,6 +72,7 @@ Devices: - [X] HMIP-FDT (Dimming Actuator flush-mount) - [X] HMIP-FROLL (Shutter Actuator - flush-mount) - [X] HMIP-KRCA (Key Ring Remote Control & alarm) +- [X] HMIP-RC8 (Remote Control - 8 buttons) - [X] HMIP-PCBS-BAT (Printed Curcuit Board Switch Battery) - [X] HMIP-PDT (Pluggable Dimmer) - [X] HMIP-PS (Plugable Switch) @@ -86,46 +87,50 @@ Devices: - [X] HMIP-SWD (Water Sensor) - [X] HMIP-SWDO (Shutter Contact) - [X] HMIP-SWDO-I (Shutter Contact Invisible) +- [X] HMIP-SWDM (Door / Window Contact - magnetic ) +- [X] HMIP-SWDM-B2 (Door / Window Contact - magnetic ) - [X] HMIP-SWO-B (Weather Sensor) - [X] HMIP-SWO-PR (Weather Sensor – pro) - [X] HMIP-SWSD (Smoke Detector) - [X] HMIP-WRC2 (Wall-mount Remote Control - 2-button) -- [X] HMIP-WTH, HMIP-WTH-2 (Wall Mounted Thermostat Pro) - -Events ------- - -It’s also possible to use push notifications based on a websocket -connection - -.. code:: python - - ##initialize the api - #... - #get the home object - home = homematicip.Home() - #add a function to handle new events - home.onEvent += printEvents - #enable the event connection -> this will also start the websocket connection to the homeMaticIP Cloud - home.enable_events() - - - #example function to display incoming events - def printEvents(eventList): - for event in eventList: - print "EventType: {} Data: {}".format(event["eventType"], event["data"]) - - #if needed you can close the websocket connection with - home.disable_events() - -.. |CircleCI| image:: https://circleci.com/gh/coreGreenberet/homematicip-rest-api.svg?style=shield - :target: https://circleci.com/gh/coreGreenberet/homematicip-rest-api -.. |PyPi| image:: https://badge.fury.io/py/homematicip.svg - :target: https://badge.fury.io/py//homematicip -.. |codecov| image:: https://codecov.io/gh/coreGreenberet/homematicip-rest-api/branch/master/graph/badge.svg - :target: https://codecov.io/gh/coreGreenberet/homematicip-rest-api -.. |Average time to resolve an issue| image:: http://isitmaintained.com/badge/resolution/coreGreenberet/homematicip-rest-api.svg - :target: http://isitmaintained.com/project/coreGreenberet/homematicip-rest-api -.. |commits-since-latest-release| image:: https://img.shields.io/github/commits-since/coreGreenberet/homematicip-rest-api/latest.svg -.. |donate-paypal| image:: https://img.shields.io/badge/Donate-PayPal-green.svg - :target: https://paypal.me/coreGreenberet +- [X] HMIP-WRC6 (Wall-mount Remote Control - 6-button) +- [X] HMIP-WTH, HMIP-WTH-2 (Wall Mounted Thermostat Pro) + + +Events +------ + +It’s also possible to use push notifications based on a websocket +connection + +.. code:: python + + ##initialize the api + #... + #get the home object + home = homematicip.Home() + #add a function to handle new events + home.onEvent += printEvents + #enable the event connection -> this will also start the websocket connection to the homeMaticIP Cloud + home.enable_events() + + + #example function to display incoming events + def printEvents(eventList): + for event in eventList: + print "EventType: {} Data: {}".format(event["eventType"], event["data"]) + + #if needed you can close the websocket connection with + home.disable_events() + +.. |CircleCI| image:: https://circleci.com/gh/coreGreenberet/homematicip-rest-api.svg?style=shield + :target: https://circleci.com/gh/coreGreenberet/homematicip-rest-api +.. |PyPi| image:: https://badge.fury.io/py/homematicip.svg + :target: https://badge.fury.io/py//homematicip +.. |codecov| image:: https://codecov.io/gh/coreGreenberet/homematicip-rest-api/branch/master/graph/badge.svg + :target: https://codecov.io/gh/coreGreenberet/homematicip-rest-api +.. |Average time to resolve an issue| image:: http://isitmaintained.com/badge/resolution/coreGreenberet/homematicip-rest-api.svg + :target: http://isitmaintained.com/project/coreGreenberet/homematicip-rest-api +.. |commits-since-latest-release| image:: https://img.shields.io/github/commits-since/coreGreenberet/homematicip-rest-api/latest.svg +.. |donate-paypal| image:: https://img.shields.io/badge/Donate-PayPal-green.svg + :target: https://paypal.me/coreGreenberet diff --git a/homematicip/aio/class_maps.py b/homematicip/aio/class_maps.py index 4ef52ec7..9cbaaec4 100644 --- a/homematicip/aio/class_maps.py +++ b/homematicip/aio/class_maps.py @@ -36,7 +36,8 @@ DeviceType.WATER_SENSOR: AsyncWaterSensor, DeviceType.SHUTTER_CONTACT_MAGNETIC: AsyncShutterContact, DeviceType.FULL_FLUSH_DIMMER : AsyncFullFlushDimmer, - DeviceType.PUSH_BUTTON_6 : AsyncPushButton6 + DeviceType.PUSH_BUTTON_6 : AsyncPushButton6, + DeviceType.REMOTE_CONTROL_8 : AsyncRemoteControl8 } TYPE_GROUP_MAP = { diff --git a/homematicip/aio/device.py b/homematicip/aio/device.py index 6ba99453..bb9c9dda 100644 --- a/homematicip/aio/device.py +++ b/homematicip/aio/device.py @@ -122,6 +122,9 @@ class AsyncPushButton(PushButton, AsyncDevice): class AsyncPushButton6(PushButton6, AsyncPushButton): """ HMIP-WRC6 (Wall-mount Remote Control - 6-button) """ +class AsyncRemoteControl8(RemoteControl8,AsyncPushButton): + """ HmIP-RC8 (Remote Control - 8 buttons) """ + class AsyncAlarmSirenIndoor(AlarmSirenIndoor, AsyncSabotageDevice): """ HMIP-ASIR (Alarm Siren) """ diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index cb9fd4c2..c676c5a4 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -170,6 +170,7 @@ class DeviceType(AutoNameEnum): SHUTTER_CONTACT_MAGNETIC = auto() FULL_FLUSH_DIMMER = auto() PUSH_BUTTON_6 = auto() + REMOTE_CONTROL_8 = auto() class GroupType(AutoNameEnum): GROUP = auto() diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index e538f11f..8e356c78 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -42,7 +42,8 @@ DeviceType.WATER_SENSOR: WaterSensor, DeviceType.SHUTTER_CONTACT_MAGNETIC: ShutterContact, DeviceType.FULL_FLUSH_DIMMER : FullFlushDimmer, - DeviceType.PUSH_BUTTON_6: PushButton6 + DeviceType.PUSH_BUTTON_6: PushButton6, + DeviceType.REMOTE_CONTROL_8 : RemoteControl8 } TYPE_GROUP_MAP = { diff --git a/homematicip/device.py b/homematicip/device.py index 4534b34a..4c1a9b3f 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -175,7 +175,7 @@ def __str__(self): class ShutterContact(SabotageDevice): """ HMIP-SWDO (Door / Window Contact - optical) / HMIP-SWDO-I (Door / Window Contact Invisible - optical) / - HmIP-SWDM / HmIP-SWDM-B2 (Door / Window Contact - magnetic""" + HmIP-SWDM / HmIP-SWDM-B2 (Door / Window Contact - magnetic )""" def __init__(self,connection): super().__init__(connection) self.windowState = WindowState.CLOSED @@ -419,6 +419,9 @@ def from_json(self, js): #They don't provide any information except for the groups. #Maybe the functional channels should get there own class and be added as class member? +class RemoteControl8(PushButton): + """ HmIP-RC8 (Remote Control - 8 buttons) """ + class AlarmSirenIndoor(SabotageDevice): """ HMIP-ASIR (Alarm Siren) """ diff --git a/tests/json_data/home.json b/tests/json_data/home.json index 0deb59d0..c3931a2e 100644 --- a/tests/json_data/home.json +++ b/tests/json_data/home.json @@ -1862,6 +1862,117 @@ "serializedGlobalTradeItemNumber": "3014F711BBBBBBBBBBBBB017", "type": "PUSH_BUTTON_6", "updateState": "UP_TO_DATE" + }, + "3014F711BBBBBBBBBBBBB016": { + "availableFirmwareVersion": "1.0.19", + "firmwareVersion": "1.0.19", + "firmwareVersionInteger": 65555, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F711BBBBBBBBBBBBB016", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -42, + "rssiPeerValue": null, + "unreach": false + }, + "1": { + "deviceId": "3014F711BBBBBBBBBBBBB016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 1, + "groups": [ + ], + "index": 1, + "label": "" + }, + "2": { + "deviceId": "3014F711BBBBBBBBBBBBB016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 1, + "groups": [ + ], + "index": 2, + "label": "" + }, + "3": { + "deviceId": "3014F711BBBBBBBBBBBBB016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 2, + "groups": [ + ], + "index": 3, + "label": "" + }, + "4": { + "deviceId": "3014F711BBBBBBBBBBBBB016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 2, + "groups": [ + ], + "index": 4, + "label": "" + }, + "5": { + "deviceId": "3014F711BBBBBBBBBBBBB016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 3, + "groups": [ + ], + "index": 5, + "label": "" + }, + "6": { + "deviceId": "3014F711BBBBBBBBBBBBB016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 3, + "groups": [ + ], + "index": 6, + "label": "" + }, + "7": { + "deviceId": "3014F711BBBBBBBBBBBBB016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 4, + "groups": [ + ], + "index": 7, + "label": "" + }, + "8": { + "deviceId": "3014F711BBBBBBBBBBBBB016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 4, + "groups": [ + ], + "index": 8, + "label": "" + } + + + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F711BBBBBBBBBBBBB016", + "label": "Fernbedienung - 8 Tasten", + "lastStatusUpdate": 1544479483638, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 299, + "modelType": "HmIP-RC8", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F711BBBBBBBBBBBBB016", + "type": "REMOTE_CONTROL_8", + "updateState": "UP_TO_DATE" } }, "groups": { diff --git a/tests/test_devices.py b/tests/test_devices.py index d3d95bdc..2e50fd5c 100644 --- a/tests/test_devices.py +++ b/tests/test_devices.py @@ -501,4 +501,11 @@ def test_push_button_6(fake_home:Home): d = fake_home.search_device_by_id("3014F711BBBBBBBBBBBBB017") assert d.modelId == 300 - assert d.label == "Wandtaster - 6-fach" \ No newline at end of file + assert d.label == "Wandtaster - 6-fach" + +def test_remote_control_8(fake_home:Home): + d = PushButton6(fake_home._connection) + d = fake_home.search_device_by_id("3014F711BBBBBBBBBBBBB016") + + assert d.modelId == 299 + assert d.label == "Fernbedienung - 8 Tasten" \ No newline at end of file From 566146dc75a44084ee870aaf7f232f834e02ca49 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Fri, 14 Dec 2018 19:50:56 +0100 Subject: [PATCH 06/21] added chanelIndex parameter the Switch turn_on/off and set_switch_state functions --- homematicip/aio/device.py | 12 ++++++++---- homematicip/device.py | 12 ++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/homematicip/aio/device.py b/homematicip/aio/device.py index bb9c9dda..0c947544 100644 --- a/homematicip/aio/device.py +++ b/homematicip/aio/device.py @@ -29,15 +29,19 @@ async def is_update_applicable(self): class AsyncSwitch(Switch, AsyncDevice): """ Generic async switch """ + async def set_switch_state(self, on=True, channelIndex = 1): + _LOGGER.debug("Async switch set_switch_state") + url, data = super().set_switch_state(on,channelIndex) + return await self._connection.api_call(url, data) - async def turn_on(self): + async def turn_on(self,channelIndex=1): _LOGGER.debug("Async switch turn_on") - url, data = super().turn_on() + url, data = super().turn_on(channelIndex) return await self._connection.api_call(url, data) - async def turn_off(self): + async def turn_off(self,channelIndex=1): _LOGGER.debug("Async switch turn_off") - url, data = super().turn_off() + url, data = super().turn_off(channelIndex) return await self._connection.api_call(url, data) diff --git a/homematicip/device.py b/homematicip/device.py index 4c1a9b3f..f99d7e2c 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -354,16 +354,16 @@ def from_json(self, js): def __str__(self): return "{}: on({}) profileMode({}) userDesiredProfileMode({})".format(super().__str__(), self.on, self.profileMode, self.userDesiredProfileMode) - def set_switch_state(self, on=True): - data = {"channelIndex": 1, "deviceId": self.id, "on": on} + def set_switch_state(self, on=True, channelIndex = 1): + data = {"channelIndex": channelIndex, "deviceId": self.id, "on": on} return self._restCall("device/control/setSwitchState", body=json.dumps(data)) - def turn_on(self): - return self.set_switch_state(True) + def turn_on(self, channelIndex = 1): + return self.set_switch_state(True,channelIndex) - def turn_off(self): - return self.set_switch_state(False) + def turn_off(self, channelIndex = 1): + return self.set_switch_state(False,channelIndex) class PlugableSwitch(Switch): """ HMIP-PS (Pluggable Switch) """ From 7909b87feb570ae2c67ea13a8dab756444e22890 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Fri, 14 Dec 2018 20:05:28 +0100 Subject: [PATCH 07/21] implemented SECURITY_BACKUP_ALARM_SWITCHING Group --- homematicip/aio/class_maps.py | 1 + homematicip/base/enums.py | 14 +- homematicip/class_maps.py | 1 + homematicip/group.py | 40 ++--- tests/test_groups.py | 326 +++++++++++++++++----------------- 5 files changed, 194 insertions(+), 188 deletions(-) diff --git a/homematicip/aio/class_maps.py b/homematicip/aio/class_maps.py index 9cbaaec4..b3101451 100644 --- a/homematicip/aio/class_maps.py +++ b/homematicip/aio/class_maps.py @@ -47,6 +47,7 @@ GroupType.EXTENDED_LINKED_SWITCHING: AsyncExtendedLinkedSwitchingGroup, GroupType.LINKED_SWITCHING: AsyncLinkedSwitchingGroup, GroupType.ALARM_SWITCHING: AsyncAlarmSwitchingGroup, + GroupType.SECURITY_BACKUP_ALARM_SWITCHING: AsyncAlarmSwitchingGroup, GroupType.HEATING_HUMIDITY_LIMITER: AsyncHeatingHumidyLimiterGroup, GroupType.HEATING_TEMPERATURE_LIMITER: AsyncHeatingTemperatureLimiterGroup, GroupType.HEATING_CHANGEOVER: AsyncHeatingChangeoverGroup, diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index c676c5a4..5ce3b0af 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -197,6 +197,7 @@ class GroupType(AutoNameEnum): SWITCHING = auto() SECURITY = auto() ENVIRONMENT = auto() + SECURITY_BACKUP_ALARM_SWITCHING = auto() class SecurityEventType(AutoNameEnum): SENSOR_EVENT = auto() @@ -253,4 +254,15 @@ class LiveUpdateState(AutoNameEnum): UP_TO_DATE = auto() UPDATE_AVAILABLE = auto() UPDATE_INCOMPLETE = auto() - LIVE_UPDATE_NOT_SUPPORTED = auto() \ No newline at end of file + LIVE_UPDATE_NOT_SUPPORTED = auto() + +class OpticalAlarmSignal(AutoNameEnum): + DISABLE_OPTICAL_SIGNAL = auto() + BLINKING_ALTERNATELY_REPEATING = auto() + BLINKING_BOTH_REPEATING = auto() + DOUBLE_FLASHING_REPEATING = auto() + FLASHING_BOTH_REPEATING = auto() + CONFIRMATION_SIGNAL_0 = auto() + CONFIRMATION_SIGNAL_1 = auto() + CONFIRMATION_SIGNAL_2 = auto() + diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index 8e356c78..94a88dc7 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -53,6 +53,7 @@ GroupType.EXTENDED_LINKED_SWITCHING: ExtendedLinkedSwitchingGroup, GroupType.LINKED_SWITCHING: LinkedSwitchingGroup, GroupType.ALARM_SWITCHING: AlarmSwitchingGroup, + GroupType.SECURITY_BACKUP_ALARM_SWITCHING : AlarmSwitchingGroup, GroupType.HEATING_HUMIDITY_LIMITER: HeatingHumidyLimiterGroup, GroupType.HEATING_TEMPERATURE_LIMITER: HeatingTemperatureLimiterGroup, GroupType.HEATING_CHANGEOVER: HeatingChangeoverGroup, diff --git a/homematicip/group.py b/homematicip/group.py index 84815ee8..f753442f 100644 --- a/homematicip/group.py +++ b/homematicip/group.py @@ -5,6 +5,8 @@ import calendar from operator import attrgetter +from homematicip.base.enums import * + class Group(HomeMaticIPObject.HomeMaticIPObject): """this class represents a group """ @@ -48,10 +50,10 @@ def __str__(self): def set_label(self, label): data = {"groupId": self.id, "label": label} return self._restCall("group/setGroupLabel", json.dumps(data)) - - def delete(self): - data = {"groupId": self.id} - return self._restCall("group/deleteGroup", body=json.dumps(data)) + + def delete(self): + data = {"groupId": self.id} + return self._restCall("group/deleteGroup", body=json.dumps(data)) class MetaGroup(Group): @@ -94,7 +96,7 @@ def __init__(self,connection): self.motionDetected = None self.presenceDetected = None self.sabotage = None - self.smokeDetectorAlarmType = None + self.smokeDetectorAlarmType = SmokeDetectorAlarmType.IDLE_OFF self.dutyCycle = None self.lowBat = None self.moistureDetected = None @@ -107,7 +109,7 @@ def from_json(self, js, devices): self.motionDetected = js["motionDetected"] self.presenceDetected = js["presenceDetected"] self.sabotage = js["sabotage"] - self.smokeDetectorAlarmType = js["smokeDetectorAlarmType"] + self.smokeDetectorAlarmType = SmokeDetectorAlarmType.from_str(js["smokeDetectorAlarmType"]) self.dutyCycle = js["dutyCycle"] self.lowBat = js["lowBat"] self.moistureDetected = js["moistureDetected"] @@ -232,25 +234,15 @@ def set_shutter_stop(self): class AlarmSwitchingGroup(Group): - SIGNAL_OPTICAL_DISABLE_OPTICAL_SIGNAL = "DISABLE_OPTICAL_SIGNAL" - SIGNAL_OPTICAL_BLINKING_ALTERNATELY_REPEATING = "BLINKING_ALTERNATELY_REPEATING" - SIGNAL_OPTICAL_BLINKING_BOTH_REPEATING = "BLINKING_BOTH_REPEATING" - SIGNAL_OPTICAL_DOUBLE_FLASHING_REPEATING = "DOUBLE_FLASHING_REPEATING" - SIGNAL_OPTICAL_FLASHING_BOTH_REPEATING = "FLASHING_BOTH_REPEATING" - SIGNAL_OPTICAL_CONFIRMATION_SIGNAL_0 = "CONFIRMATION_SIGNAL_0" - SIGNAL_OPTICAL_CONFIRMATION_SIGNAL_1 = "CONFIRMATION_SIGNAL_1" - SIGNAL_OPTICAL_CONFIRMATION_SIGNAL_2 = "CONFIRMATION_SIGNAL_2" - - def __init__(self,connection): super().__init__(connection) self.on = None self.dimLevel = None self.onTime = None - self.signalAcoustic = None - self.signalOptical = None - self.smokeDetectorAlarmType = None + self.signalAcoustic = AcousticAlarmSignal.DISABLE_ACOUSTIC_SIGNAL + self.signalOptical = OpticalAlarmSignal.DISABLE_OPTICAL_SIGNAL + self.smokeDetectorAlarmType = SmokeDetectorAlarmType.IDLE_OFF self.acousticFeedbackEnabled = None def from_json(self, js, devices): @@ -258,9 +250,9 @@ def from_json(self, js, devices): self.onTime = js["onTime"] self.on = js["on"] self.dimLevel = js["dimLevel"] - self.signalAcoustic = js["signalAcoustic"] - self.signalOptical = js["signalOptical"] - self.smokeDetectorAlarmType = js["smokeDetectorAlarmType"] + self.signalAcoustic = AcousticAlarmSignal.from_str(js["signalAcoustic"]) + self.signalOptical = OpticalAlarmSignal.from_str(js["signalOptical"]) + self.smokeDetectorAlarmType = SmokeDetectorAlarmType.from_str(js["smokeDetectorAlarmType"]) self.acousticFeedbackEnabled = js["acousticFeedbackEnabled"] def set_on_time(self, onTimeSeconds): @@ -275,12 +267,12 @@ def __str__(self): self.acousticFeedbackEnabled) def test_signal_optical(self, - signalOptical=SIGNAL_OPTICAL_BLINKING_ALTERNATELY_REPEATING): + signalOptical=OpticalAlarmSignal.BLINKING_ALTERNATELY_REPEATING): data = {"groupId": self.id, "signalOptical": signalOptical} return self._restCall("group/switching/alarm/testSignalOptical", body=json.dumps(data)) def set_signal_optical(self, - signalOptical=SIGNAL_OPTICAL_BLINKING_ALTERNATELY_REPEATING): + signalOptical=OpticalAlarmSignal.BLINKING_ALTERNATELY_REPEATING): data = {"groupId": self.id, "signalOptical": signalOptical} return self._restCall("group/switching/alarm/setSignalOptical", body=json.dumps(data)) diff --git a/tests/test_groups.py b/tests/test_groups.py index 57b4356c..e3a76a3a 100644 --- a/tests/test_groups.py +++ b/tests/test_groups.py @@ -1,173 +1,173 @@ -from unittest.mock import MagicMock, Mock - -import pytest - -from homematicip.group import * -from homematicip.home import Home -import json -from datetime import datetime, timedelta, timezone - -from conftest import fake_home_download_configuration, no_ssl_verification, utc_offset - - -def test_meta_group(fake_home : Home): - g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000020') - assert isinstance(g, MetaGroup) - assert g.label == "Badezimmer" - assert g.lastStatusUpdate == datetime(2018, 4, 23, 20, 49, 16, 479000) + timedelta(0,utc_offset) - assert g.lowBat == False - assert g.metaGroup == None - assert g.sabotage == None - assert g.configPending == False - assert g.unreach == False - assert g.dutyCycle == False - assert g.incorrectPositioned == None - for d in g.devices: - assert d.id in ['3014F7110000000000000025', '3014F7110000000000000016', '3014F7110000000000000050'] - for g_sub in g.groups: - assert g_sub.id in ['00000000-0000-0000-0000-000000000021', '00000000-0000-0000-0000-000000000021'] - - assert str(g) == "META Badezimmer" - - assert g._rawJSONData == fake_home_download_configuration()["groups"]["00000000-0000-0000-0000-000000000020"] - -def test_heating_group(fake_home : Home): - g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000012') - assert isinstance(g, HeatingGroup) - for d in g.devices: - assert d.id in ['3014F7110000000000000004', '3014F7110000000000000022', '3014F7110000000000000011'] - - assert g.activeProfile.index == "PROFILE_1" - assert g.activeProfile.enabled == True - assert g.activeProfile.name == "" - assert g.activeProfile.visible == True - assert g.activeProfile.id == "00000000-0000-0000-0000-000000000023" - assert g.activeProfile.groupId == "00000000-0000-0000-0000-000000000012" - - profile3 = g.profiles[2] - assert profile3.index == 'PROFILE_3' - assert profile3.visible == False - assert profile3.id == '00000000-0000-0000-0000-000000000025' - - assert g.actualTemperature == 24.7 - assert g.boostDuration == 15 - assert g.boostMode == False - assert g.controlMode == "AUTOMATIC" - assert g.controllable == True - assert g.cooling == False - assert g.coolingAllowed == False - assert g.coolingIgnored == False - assert g.dutyCycle == False - assert g.ecoAllowed == True - assert g.ecoIgnored == False - assert g.externalClockCoolingTemperature == 23.0 - assert g.externalClockEnabled == False - assert g.externalClockHeatingTemperature == 19.0 - assert g.floorHeatingMode == "FLOOR_HEATING_STANDARD" - assert g.humidity == 43 - assert g.humidityLimitEnabled == True - assert g.humidityLimitValue == 60 - assert g.label == "Schlafzimmer" - assert g.lastStatusUpdate == datetime(2018, 4, 23, 20, 48, 54, 382000) + timedelta(0,utc_offset) - assert g.lowBat == False - assert g.maxTemperature == 30.0 - assert g.metaGroup.id == "00000000-0000-0000-0000-000000000011" - assert g.minTemperature == 5.0 - assert g.partyMode == False - assert g.setPointTemperature == 5.0 - assert g.unreach == False - assert g.valvePosition == 0.0 - assert g.windowOpenTemperature == 5.0 - assert g.windowState == "OPEN" - - assert str(g) == ('HEATING Schlafzimmer windowOpenTemperature(5.0) setPointTemperature(5.0) windowState(OPEN) motionDetected(30.0)' - ' sabotage(5.0) cooling(False) partyMode(False) controlMode(AUTOMATIC) actualTemperature(24.7) valvePosition(0.0)') - - assert g._rawJSONData == fake_home_download_configuration()["groups"]["00000000-0000-0000-0000-000000000012"] - -def test_security_group(fake_home : Home): - g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000009') - assert isinstance(g, SecurityGroup) - for d in g.devices: - assert d.id in ['3014F7110000000000000001', '3014F7110000000000000019'] - - assert g.dutyCycle == False - assert g.homeId == "00000000-0000-0000-0000-000000000001" - assert g.id == "00000000-0000-0000-0000-000000000009" - assert g.label == "Büro" - assert g.lastStatusUpdate == datetime(2018, 4, 23, 20, 37, 34, 304000) + timedelta(0,utc_offset) - assert g.lowBat == False - assert g.metaGroup.id == "00000000-0000-0000-0000-000000000008" - assert g.motionDetected == None - assert g.presenceDetected == None - assert g.sabotage == False - assert g.smokeDetectorAlarmType == "IDLE_OFF" - assert g.unreach == False - assert g.windowState == "CLOSED" - - assert str(g) == ('SECURITY Büro: windowState(CLOSED) motionDetected(None) presenceDetected(None) sabotage(False)' - ' smokeDetectorAlarmType(IDLE_OFF) dutyCycle(False) lowBat(False) powerMainsFailure(None) moistureDetected(None) waterlevelDetected(None)') - -def test_switching_group(fake_home : Home): - with no_ssl_verification(): - g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000018') - assert isinstance(g, SwitchingGroup) - for d in g.devices: - assert d.id in ['3014F7110000000000000010', '3014F7110000000000000009', '3014F7110000000000000008'] - - assert g.dimLevel == None - assert g.dutyCycle == False - assert g.homeId == "00000000-0000-0000-0000-000000000001" - assert g.id == "00000000-0000-0000-0000-000000000018" - assert g.label == "Strom" - assert g.lastStatusUpdate == datetime(2018, 4, 23, 20, 49, 14, 56000) + timedelta(0,utc_offset) - assert g.lowBat == None - assert g.metaGroup.id == "00000000-0000-0000-0000-000000000017" - assert g.on == True - assert g.processing == None - assert g.shutterLevel == None - assert g.slatsLevel == None - assert g.unreach == False - - assert str(g) == ('SWITCHING Strom: on(True) dimLevel(None) processing(None) shutterLevel(None) slatsLevel(None)' - ' dutyCycle(False) lowBat(None)') - - g.turn_off() - g.set_label("NEW GROUP") - g.set_shutter_level(50) - fake_home.get_current_state() - g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000018') - assert g.on == False - assert g.label == "NEW GROUP" - assert g.shutterLevel == 50 - - assert str(g) == ('SWITCHING NEW GROUP: on(False) dimLevel(None) processing(None) shutterLevel(50) slatsLevel(None)' - ' dutyCycle(False) lowBat(None)') - g.turn_on() - fake_home.get_current_state() - g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000018') - assert g.on == True - +from unittest.mock import MagicMock, Mock + +import pytest + +from homematicip.group import * +from homematicip.home import Home +import json +from datetime import datetime, timedelta, timezone + +from conftest import fake_home_download_configuration, no_ssl_verification, utc_offset + + +def test_meta_group(fake_home : Home): + g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000020') + assert isinstance(g, MetaGroup) + assert g.label == "Badezimmer" + assert g.lastStatusUpdate == datetime(2018, 4, 23, 20, 49, 16, 479000) + timedelta(0,utc_offset) + assert g.lowBat == False + assert g.metaGroup == None + assert g.sabotage == None + assert g.configPending == False + assert g.unreach == False + assert g.dutyCycle == False + assert g.incorrectPositioned == None + for d in g.devices: + assert d.id in ['3014F7110000000000000025', '3014F7110000000000000016', '3014F7110000000000000050'] + for g_sub in g.groups: + assert g_sub.id in ['00000000-0000-0000-0000-000000000021', '00000000-0000-0000-0000-000000000021'] + + assert str(g) == "META Badezimmer" + + assert g._rawJSONData == fake_home_download_configuration()["groups"]["00000000-0000-0000-0000-000000000020"] + +def test_heating_group(fake_home : Home): + g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000012') + assert isinstance(g, HeatingGroup) + for d in g.devices: + assert d.id in ['3014F7110000000000000004', '3014F7110000000000000022', '3014F7110000000000000011'] + + assert g.activeProfile.index == "PROFILE_1" + assert g.activeProfile.enabled == True + assert g.activeProfile.name == "" + assert g.activeProfile.visible == True + assert g.activeProfile.id == "00000000-0000-0000-0000-000000000023" + assert g.activeProfile.groupId == "00000000-0000-0000-0000-000000000012" + + profile3 = g.profiles[2] + assert profile3.index == 'PROFILE_3' + assert profile3.visible == False + assert profile3.id == '00000000-0000-0000-0000-000000000025' + + assert g.actualTemperature == 24.7 + assert g.boostDuration == 15 + assert g.boostMode == False + assert g.controlMode == "AUTOMATIC" + assert g.controllable == True + assert g.cooling == False + assert g.coolingAllowed == False + assert g.coolingIgnored == False + assert g.dutyCycle == False + assert g.ecoAllowed == True + assert g.ecoIgnored == False + assert g.externalClockCoolingTemperature == 23.0 + assert g.externalClockEnabled == False + assert g.externalClockHeatingTemperature == 19.0 + assert g.floorHeatingMode == "FLOOR_HEATING_STANDARD" + assert g.humidity == 43 + assert g.humidityLimitEnabled == True + assert g.humidityLimitValue == 60 + assert g.label == "Schlafzimmer" + assert g.lastStatusUpdate == datetime(2018, 4, 23, 20, 48, 54, 382000) + timedelta(0,utc_offset) + assert g.lowBat == False + assert g.maxTemperature == 30.0 + assert g.metaGroup.id == "00000000-0000-0000-0000-000000000011" + assert g.minTemperature == 5.0 + assert g.partyMode == False + assert g.setPointTemperature == 5.0 + assert g.unreach == False + assert g.valvePosition == 0.0 + assert g.windowOpenTemperature == 5.0 + assert g.windowState == "OPEN" + + assert str(g) == ('HEATING Schlafzimmer windowOpenTemperature(5.0) setPointTemperature(5.0) windowState(OPEN) motionDetected(30.0)' + ' sabotage(5.0) cooling(False) partyMode(False) controlMode(AUTOMATIC) actualTemperature(24.7) valvePosition(0.0)') + + assert g._rawJSONData == fake_home_download_configuration()["groups"]["00000000-0000-0000-0000-000000000012"] + +def test_security_group(fake_home : Home): + g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000009') + assert isinstance(g, SecurityGroup) + for d in g.devices: + assert d.id in ['3014F7110000000000000001', '3014F7110000000000000019'] + + assert g.dutyCycle == False + assert g.homeId == "00000000-0000-0000-0000-000000000001" + assert g.id == "00000000-0000-0000-0000-000000000009" + assert g.label == "Büro" + assert g.lastStatusUpdate == datetime(2018, 4, 23, 20, 37, 34, 304000) + timedelta(0,utc_offset) + assert g.lowBat == False + assert g.metaGroup.id == "00000000-0000-0000-0000-000000000008" + assert g.motionDetected == None + assert g.presenceDetected == None + assert g.sabotage == False + assert g.smokeDetectorAlarmType == SmokeDetectorAlarmType.IDLE_OFF + assert g.unreach == False + assert g.windowState == "CLOSED" + + assert str(g) == ('SECURITY Büro: windowState(CLOSED) motionDetected(None) presenceDetected(None) sabotage(False)' + ' smokeDetectorAlarmType(IDLE_OFF) dutyCycle(False) lowBat(False) powerMainsFailure(None) moistureDetected(None) waterlevelDetected(None)') + +def test_switching_group(fake_home : Home): + with no_ssl_verification(): + g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000018') + assert isinstance(g, SwitchingGroup) + for d in g.devices: + assert d.id in ['3014F7110000000000000010', '3014F7110000000000000009', '3014F7110000000000000008'] + + assert g.dimLevel == None + assert g.dutyCycle == False + assert g.homeId == "00000000-0000-0000-0000-000000000001" + assert g.id == "00000000-0000-0000-0000-000000000018" + assert g.label == "Strom" + assert g.lastStatusUpdate == datetime(2018, 4, 23, 20, 49, 14, 56000) + timedelta(0,utc_offset) + assert g.lowBat == None + assert g.metaGroup.id == "00000000-0000-0000-0000-000000000017" + assert g.on == True + assert g.processing == None + assert g.shutterLevel == None + assert g.slatsLevel == None + assert g.unreach == False + + assert str(g) == ('SWITCHING Strom: on(True) dimLevel(None) processing(None) shutterLevel(None) slatsLevel(None)' + ' dutyCycle(False) lowBat(None)') + + g.turn_off() + g.set_label("NEW GROUP") + g.set_shutter_level(50) + fake_home.get_current_state() + g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000018') + assert g.on == False + assert g.label == "NEW GROUP" + assert g.shutterLevel == 50 + + assert str(g) == ('SWITCHING NEW GROUP: on(False) dimLevel(None) processing(None) shutterLevel(50) slatsLevel(None)' + ' dutyCycle(False) lowBat(None)') + g.turn_on() + fake_home.get_current_state() + g = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000018') + assert g.on == True + fake_home.delete_group(g) fake_home.get_current_state() gNotFound = fake_home.search_group_by_id('00000000-0000-0000-0000-000000000018') - assert gNotFound == None - - result = g.delete() + assert gNotFound == None + + result = g.delete() assert result["errorCode"] == 'INVALID_GROUP' - result = g.set_label('LABEL') + result = g.set_label('LABEL') assert result["errorCode"] == 'INVALID_GROUP' - result = g.turn_off() + result = g.turn_off() assert result["errorCode"] == 'INVALID_GROUP' - result = g.set_shutter_level(50) - assert result["errorCode"] == 'INVALID_GROUP' - - -def test_all_groups_implemented(fake_home : Home): - for g in fake_home.groups: - assert type(g) != Group - + result = g.set_shutter_level(50) + assert result["errorCode"] == 'INVALID_GROUP' + + +def test_all_groups_implemented(fake_home : Home): + for g in fake_home.groups: + assert type(g) != Group + From e4da6c991f0cde2f385c7fd7e6f79cd24b7a7a19 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Fri, 14 Dec 2018 20:58:39 +0100 Subject: [PATCH 08/21] added base functionalChanel --- homematicip/functionalChannels.py | 28 ++++++++++++++++++++++++++++ tests/json_data/home.json | 20 ++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 homematicip/functionalChannels.py diff --git a/homematicip/functionalChannels.py b/homematicip/functionalChannels.py new file mode 100644 index 00000000..7610d106 --- /dev/null +++ b/homematicip/functionalChannels.py @@ -0,0 +1,28 @@ +from homematicip.group import Group + +from typing import Iterable + +class FunctionalChanel(): + """ this is the base class for the functional channels """ + + def __init__(self): + self.index = -1 + self.groupIndex = -1 + self.label = "" + self.groupIndex = -1 + + self.groups = Iterable[Group] + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + self.index = js["index"] + self.groupIndex = js["groupIndex"] + self.label = js["label"] + + self.groups = [] + for id in js["groups"]: + for g in groups: + if g.id == id: + self.groups.append(g) + break diff --git a/tests/json_data/home.json b/tests/json_data/home.json index c3931a2e..66c2ae22 100644 --- a/tests/json_data/home.json +++ b/tests/json_data/home.json @@ -3219,6 +3219,25 @@ "type": "ENVIRONMENT", "unreach": false, "windSpeed": 29.1 + }, + "00000000-AAAA-0000-0000-000000000068": { + "acousticFeedbackEnabled": true, + "channels": [], + "dimLevel": null, + "dutyCycle": null, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-AAAA-0000-0000-000000000068", + "label": "BACKUP_ALARM_SIREN", + "lastStatusUpdate": 0, + "lowBat": null, + "metaGroupId": null, + "on": null, + "onTime": 180.0, + "signalAcoustic": "FREQUENCY_RISING", + "signalOptical": "DISABLE_OPTICAL_SIGNAL", + "smokeDetectorAlarmType": null, + "type": "SECURITY_BACKUP_ALARM_SWITCHING", + "unreach": null } }, "home": { @@ -3287,6 +3306,7 @@ "intrusionAlertThroughSmokeDetectors": false, "securitySwitchingGroups": { "ALARM": "00000000-0000-0000-0000-000000000056", + "BACKUP_ALARM_SIREN": "00000000-AAAA-0000-0000-000000000068", "COMING_HOME": "00000000-0000-0000-0000-000000000037", "PANIC": "00000000-0000-0000-0000-000000000053", "SIREN": "00000000-0000-0000-0000-000000000022" From 868198dd57a4940246957d940c3d5f13879bef4a Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Fri, 14 Dec 2018 22:07:46 +0100 Subject: [PATCH 09/21] added functionalChanelType mapping --- homematicip.pyproj | 5 ++++- homematicip/base/enums.py | 4 ++++ homematicip/class_maps.py | 6 ++++++ homematicip/device.py | 19 +++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/homematicip.pyproj b/homematicip.pyproj index f16f879c..e17c08cc 100644 --- a/homematicip.pyproj +++ b/homematicip.pyproj @@ -17,7 +17,7 @@ False - --list-events + -g 678bb392-4e08-4072-8a15-b5471d8a218b --set-boost-duration 30 Global|PythonCore|3.6 @@ -59,6 +59,9 @@ Code + + Code + Code diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index 5ce3b0af..ee9d66c1 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -266,3 +266,7 @@ class OpticalAlarmSignal(AutoNameEnum): CONFIRMATION_SIGNAL_1 = auto() CONFIRMATION_SIGNAL_2 = auto() + +class FunctionalChanelType(AutoNameEnum): + FUNCTIONAL_CHANEL = auto() + diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index 94a88dc7..3460fd5f 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -7,6 +7,8 @@ from homematicip.securityEvent import * from homematicip.rule import * from homematicip.functionalHomes import * +from homematicip.functionalChanels import * + TYPE_CLASS_MAP = { DeviceType.DEVICE: Device, @@ -100,3 +102,7 @@ FunctionalHomeType.LIGHT_AND_SHADOW: LightAndShadowHome, FunctionalHomeType.SECURITY_AND_ALARM: SecurityAndAlarmHome } + +TYPE_FUNCTIONALCHANEL_MAP = { + FunctionalChanelType.FUNCTIONAL_CHANEL : FunctionalChanel +} \ No newline at end of file diff --git a/homematicip/device.py b/homematicip/device.py index f99d7e2c..16c33714 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -6,6 +6,10 @@ from homematicip.base.helpers import get_functional_channel from homematicip.base.enums import * from homematicip import HomeMaticIPObject +from homematicip.group import Group +from homematicip.class_maps import TYPE_FUNCTIONALCHANEL_MAP + +from typing import Iterable LOGGER = logging.getLogger(__name__) @@ -97,6 +101,21 @@ def set_router_module_enabled(self, enabled=True): "routerModuleEnabled": enabled} return self._restCall("device/configuration/setRouterModuleEnabled", json.dumps(data)) + def load_functionalChanels(groups : Iterable[Group]): + """ this function will load the functionalChanels into the device """ + + def _parse_functionalChanel(self,json_state,groups : Iterable[Group]) + try: + chanelType = FunctionalChanelType.from_str(json_state["type"]) + fc = self._typeClassMap[chanelType](self._connection) + fc.from_json(json_state,groups) + return fc + except: + fc = self._typeClassMap[FunctionalChanelType.FUNCTIONAL_CHANEL](self._connection) + fc.from_json(json_state,groups) + LOGGER.warning("There is no class for %s yet", json_state["type"]) + return fc + class SabotageDevice(Device): def __init__(self,connection): From 96503747c6005189a60d9bca4538302752a6d9b4 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 16:47:58 +0100 Subject: [PATCH 10/21] added the first functional Base Channels --- homematicip/base/enums.py | 15 +++++++-- homematicip/class_maps.py | 9 ++++-- homematicip/device.py | 40 ++++++++++++++---------- homematicip/functionalChannels.py | 52 ++++++++++++++++++++++++++++++- homematicip/home.py | 5 +++ 5 files changed, 99 insertions(+), 22 deletions(-) diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index ee9d66c1..f1d4e32c 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -267,6 +267,17 @@ class OpticalAlarmSignal(AutoNameEnum): CONFIRMATION_SIGNAL_2 = auto() -class FunctionalChanelType(AutoNameEnum): - FUNCTIONAL_CHANEL = auto() +class FunctionalChannelType(AutoNameEnum): + FUNCTIONAL_CHANNEL = auto() + DEVICE_BASE = auto() + DEVICE_INCORRECT_POSITIONED = auto() + DEVICE_OPERATIONLOCK = auto() + DEVICE_SABOTAGE = auto() + HEATING_THERMOSTAT_CHANNEL = auto() + SHUTTER_CONTACT_CHANNEL = auto() + SMOKE_DETECTOR_CHANNEL = auto() + SWITCH_MEASURING_CHANNEL = auto() + WALL_MOUNTED_THERMOSTAT_PRO_CHANNEL = auto() + WATER_SENSOR_CHANNEL = auto() + diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index 3460fd5f..e75209a8 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -7,7 +7,7 @@ from homematicip.securityEvent import * from homematicip.rule import * from homematicip.functionalHomes import * -from homematicip.functionalChanels import * +from homematicip.functionalChannels import * TYPE_CLASS_MAP = { @@ -103,6 +103,9 @@ FunctionalHomeType.SECURITY_AND_ALARM: SecurityAndAlarmHome } -TYPE_FUNCTIONALCHANEL_MAP = { - FunctionalChanelType.FUNCTIONAL_CHANEL : FunctionalChanel +TYPE_FUNCTIONALCHANNEL_MAP = { + FunctionalChannelType.FUNCTIONAL_CHANNEL : FunctionalChannel, + FunctionalChannelType.DEVICE_BASE : DeviceBaseChannel, + FunctionalChannelType.DEVICE_SABOTAGE: DeviceSabotageChannel, + FunctionalChannelType.DEVICE_OPERATIONLOCK : DeviceOperationLockChannel } \ No newline at end of file diff --git a/homematicip/device.py b/homematicip/device.py index 16c33714..1c5be748 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -7,7 +7,6 @@ from homematicip.base.enums import * from homematicip import HomeMaticIPObject from homematicip.group import Group -from homematicip.class_maps import TYPE_FUNCTIONALCHANEL_MAP from typing import Iterable @@ -15,6 +14,7 @@ class Device(HomeMaticIPObject.HomeMaticIPObject): """ this class represents a generic homematic ip device """ + def __init__(self,connection): super().__init__(connection) self.id = None @@ -41,6 +41,11 @@ def __init__(self,connection): self.configPending = False self.permanentlyReachable = False self.liveUpdateState = LiveUpdateState.LIVE_UPDATE_NOT_SUPPORTED + self.functionalChannels = [] + + #must be imported in init. otherwise we have cross import issues + from homematicip.class_maps import TYPE_FUNCTIONALCHANNEL_MAP + self._typeFunctionalChannelMap = TYPE_FUNCTIONALCHANNEL_MAP def from_json(self, js): super().from_json(js) @@ -101,20 +106,24 @@ def set_router_module_enabled(self, enabled=True): "routerModuleEnabled": enabled} return self._restCall("device/configuration/setRouterModuleEnabled", json.dumps(data)) - def load_functionalChanels(groups : Iterable[Group]): - """ this function will load the functionalChanels into the device """ - - def _parse_functionalChanel(self,json_state,groups : Iterable[Group]) - try: - chanelType = FunctionalChanelType.from_str(json_state["type"]) - fc = self._typeClassMap[chanelType](self._connection) - fc.from_json(json_state,groups) - return fc - except: - fc = self._typeClassMap[FunctionalChanelType.FUNCTIONAL_CHANEL](self._connection) - fc.from_json(json_state,groups) - LOGGER.warning("There is no class for %s yet", json_state["type"]) - return fc + def load_functionalChannels(self, groups : Iterable[Group]): + """ this function will load the functionalChannels into the device """ + self.functionalChannels = [] + for channel in self._rawJSONData['functionalChannels'].values(): + fc = self._parse_functionalChannel(channel,groups) + self.functionalChannels.append(fc) + + def _parse_functionalChannel(self,json_state,groups : Iterable[Group]): + fc = None + try: + channelType = FunctionalChannelType.from_str(json_state["functionalChannelType"]) + fc = self._typeFunctionalChannelMap[channelType]() + fc.from_json(json_state,groups) + except: + fc = self._typeFunctionalChannelMap[FunctionalChannelType.FUNCTIONAL_CHANNEL]() + fc.from_json(json_state,groups) + LOGGER.warning("There is no class for %s yet", json_state["functionalChannelType"]) + return fc class SabotageDevice(Device): @@ -137,7 +146,6 @@ def from_json(self, js): def __str__(self): return "{}: sabotage({})".format(super().__str__(), self.sabotage) - class OperationLockableDevice(Device): def __init__(self,connection): super().__init__(connection) diff --git a/homematicip/functionalChannels.py b/homematicip/functionalChannels.py index 7610d106..a19befd9 100644 --- a/homematicip/functionalChannels.py +++ b/homematicip/functionalChannels.py @@ -2,7 +2,7 @@ from typing import Iterable -class FunctionalChanel(): +class FunctionalChannel(): """ this is the base class for the functional channels """ def __init__(self): @@ -26,3 +26,53 @@ def from_json(self, js, groups: Iterable[Group]): if g.id == id: self.groups.append(g) break + +class DeviceBaseChannel(FunctionalChannel): + """ this is the representive of the DEVICE_BASE channel""" + def __init__(self): + super().__init__() + self.unreach = None + self.lowBat = None + self.routerModuleSupported = False + self.routerModuleEnabled = False + self.rssiDeviceValue = 0 + self.rssiPeerValue = 0 + self.dutyCycle = False + self.configPending = False + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.unreach = js["unreach"] + self.lowBat = js["lowBat"] + self.routerModuleSupported = js["routerModuleSupported"] + self.routerModuleEnabled = js["routerModuleEnabled"] + self.rssiDeviceValue = js["rssiDeviceValue"] + self.rssiPeerValue = js["rssiPeerValue"] + self.dutyCycle = js["dutyCycle"] + self.configPending = js["configPending"] + +class DeviceSabotageChannel(DeviceBaseChannel): + """ this is the representive of the DEVICE_SABOTAGE channel""" + def __init__(self): + super().__init__() + self.sabotage = False + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.sabotage = js["sabotage"] + +class DeviceOperationLockChannel(DeviceBaseChannel): + """ this is the representive of the DEVICE_OPERATIONLOCK channel""" + def __init__(self): + super().__init__() + self.operationLockActive = False + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.operationLockActive = js["operationLockActive"] \ No newline at end of file diff --git a/homematicip/home.py b/homematicip/home.py index 4d0b5e43..0266cee8 100644 --- a/homematicip/home.py +++ b/homematicip/home.py @@ -207,6 +207,7 @@ def get_current_state(self, clearConfig = False): self._get_groups(json_state) self._get_functionalHomes(js_home) + self._load_functionalChannels() return True @@ -317,6 +318,10 @@ def _get_functionalHomes(self, json_state): LOGGER.warning("There is no class for %s yet", solution) self.functionalHomes.append(h) + def _load_functionalChannels(self): + for d in self.devices: + d.load_functionalChannels(self.groups) + def get_functionalHome(self, functionalHomeType ): """ returns the functionalHome from the given type or None if the functional home couldn't be found""" for x in self.functionalHomes: From 1ef25df10f1eee8347499bcb8a714c9233a1151d Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 16:56:32 +0100 Subject: [PATCH 11/21] calling Device.load_functionalChannels on Home._ws_on_message --- homematicip/home.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homematicip/home.py b/homematicip/home.py index 0266cee8..977dafa4 100644 --- a/homematicip/home.py +++ b/homematicip/home.py @@ -536,6 +536,7 @@ def _ws_on_message(self, message ): elif pushEventType == EventType.DEVICE_ADDED: data = event["device"] obj = self._parse_device(data) + obj.load_functionalChannels(self.groups) self.devices.append(obj) elif pushEventType == EventType.DEVICE_CHANGED: data = event["device"] @@ -545,6 +546,7 @@ def _ws_on_message(self, message ): self.devices.append(obj) else: obj.from_json(data) + obj.load_functionalChannels(self.groups) obj.fire_update_event(data, event_type=pushEventType, obj=obj) elif pushEventType == EventType.DEVICE_REMOVED: obj = self.search_device_by_id(event["id"]) From fd9d636859a40bee2fdfec8e52f12adfd80a5e35 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 17:42:02 +0100 Subject: [PATCH 12/21] added FunctionalChannels: * ClimateSensorChannel * DeviceGlobalPumpControlChannel * DeviceIncorrectPositionedChannel * HeatingThermostatChannel * MotionDetectionChannel * PresenceDetectionChannel * RotaryHandleChannel * ShutterChannel * ShutterContactChannel * SmokeDetectorChannel * SwitchChannel * SwitchMeasuringChannel * WallMountedThermostatWithoutDisplayChannel * WallMountedThermostatProChannel * WaterSensorChannel --- homematicip.pyproj | 2 +- homematicip/base/enums.py | 8 + homematicip/class_maps.py | 17 ++- homematicip/device.py | 28 ++-- homematicip/functionalChannels.py | 234 +++++++++++++++++++++++++++++- 5 files changed, 271 insertions(+), 18 deletions(-) diff --git a/homematicip.pyproj b/homematicip.pyproj index e17c08cc..e64655f2 100644 --- a/homematicip.pyproj +++ b/homematicip.pyproj @@ -17,7 +17,7 @@ False - -g 678bb392-4e08-4072-8a15-b5471d8a218b --set-boost-duration 30 + --list-devices Global|PythonCore|3.6 diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index f1d4e32c..cc90e73d 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -269,15 +269,23 @@ class OpticalAlarmSignal(AutoNameEnum): class FunctionalChannelType(AutoNameEnum): FUNCTIONAL_CHANNEL = auto() + CLIMATE_SENSOR_CHANNEL = auto() DEVICE_BASE = auto() + DEVICE_GLOBAL_PUMP_CONTROL = auto() DEVICE_INCORRECT_POSITIONED = auto() DEVICE_OPERATIONLOCK = auto() DEVICE_SABOTAGE = auto() HEATING_THERMOSTAT_CHANNEL = auto() + MOTION_DETECTION_CHANNEL = auto() + PRESENCE_DETECTION_CHANNEL = auto() + ROTARY_HANDLE_CHANNEL = auto() + SHUTTER_CHANNEL = auto() SHUTTER_CONTACT_CHANNEL = auto() SMOKE_DETECTOR_CHANNEL = auto() + SWITCH_CHANNEL = auto() SWITCH_MEASURING_CHANNEL = auto() WALL_MOUNTED_THERMOSTAT_PRO_CHANNEL = auto() + WALL_MOUNTED_THERMOSTAT_WITHOUT_DISPLAY_CHANNEL = auto() WATER_SENSOR_CHANNEL = auto() diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index e75209a8..3cf478ee 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -105,7 +105,22 @@ TYPE_FUNCTIONALCHANNEL_MAP = { FunctionalChannelType.FUNCTIONAL_CHANNEL : FunctionalChannel, + FunctionalChannelType.CLIMATE_SENSOR_CHANNEL : ClimateSensorChannel, FunctionalChannelType.DEVICE_BASE : DeviceBaseChannel, + FunctionalChannelType.DEVICE_GLOBAL_PUMP_CONTROL : DeviceGlobalPumpControlChannel, FunctionalChannelType.DEVICE_SABOTAGE: DeviceSabotageChannel, - FunctionalChannelType.DEVICE_OPERATIONLOCK : DeviceOperationLockChannel + FunctionalChannelType.DEVICE_OPERATIONLOCK : DeviceOperationLockChannel, + FunctionalChannelType.DEVICE_INCORRECT_POSITIONED : DeviceIncorrectPositionedChannel, + FunctionalChannelType.HEATING_THERMOSTAT_CHANNEL : HeatingThermostatChannel, + FunctionalChannelType.MOTION_DETECTION_CHANNEL : MotionDetectionChannel, + FunctionalChannelType.PRESENCE_DETECTION_CHANNEL : PresenceDetectionChannel, + FunctionalChannelType.ROTARY_HANDLE_CHANNEL : RotaryHandleChannel, + FunctionalChannelType.SHUTTER_CHANNEL : ShutterChannel, + FunctionalChannelType.SHUTTER_CONTACT_CHANNEL : ShutterContactChannel, + FunctionalChannelType.SMOKE_DETECTOR_CHANNEL: SmokeDetectorChannel, + FunctionalChannelType.SWITCH_CHANNEL: SwitchChannel, + FunctionalChannelType.SWITCH_MEASURING_CHANNEL: SwitchMeasuringChannel, + FunctionalChannelType.WALL_MOUNTED_THERMOSTAT_WITHOUT_DISPLAY_CHANNEL : WallMountedThermostatWithoutDisplayChannel, + FunctionalChannelType.WALL_MOUNTED_THERMOSTAT_PRO_CHANNEL : WallMountedThermostatProChannel, + FunctionalChannelType.WATER_SENSOR_CHANNEL : WaterSensorChannel, } \ No newline at end of file diff --git a/homematicip/device.py b/homematicip/device.py index 1c5be748..5f326123 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -240,8 +240,8 @@ class TemperatureHumiditySensorOutdoor(Device): def __init__(self,connection): super().__init__(connection) - self.actualTemperature = None - self.humidity = None + self.actualTemperature = 0 + self.humidity = 0 def from_json(self, js): super().from_json(js) @@ -258,9 +258,9 @@ class TemperatureHumiditySensorWithoutDisplay(Device): def __init__(self,connection): super().__init__(connection) - self.temperatureOffset = None - self.actualTemperature = None - self.humidity = None + self.temperatureOffset = 0 + self.actualTemperature = 0 + self.humidity = 0 def from_json(self, js): super().from_json(js) @@ -279,11 +279,11 @@ class TemperatureHumiditySensorDisplay(Device): def __init__(self,connection): super().__init__(connection) - self.temperatureOffset = None + self.temperatureOffset = 0 self.display = ClimateControlDisplay.ACTUAL - self.actualTemperature = None - self.humidity = None - self.setPointTemperature = None + self.actualTemperature = 0 + self.humidity = 0 + self.setPointTemperature = 0 def from_json(self, js): super().from_json(js) @@ -325,7 +325,7 @@ class SmokeDetector(Device): def __init__(self,connection): super().__init__(connection) - self.smokeDetectorAlarmType = None + self.smokeDetectorAlarmType = SmokeDetectorAlarmType.IDLE_OFF def from_json(self, js): super().from_json(js) @@ -403,8 +403,8 @@ class SwitchMeasuring(Switch): def __init__(self,connection): super().__init__(connection) - self.energyCounter = None - self.currentPowerConsumption = None + self.energyCounter = 0 + self.currentPowerConsumption = 0 def reset_energy_counter(self): data = {"channelIndex": 1, "deviceId": self.id} @@ -499,8 +499,8 @@ class PresenceDetectorIndoor(SabotageDevice): def __init__(self,connection): super().__init__(connection) - self.presenceDetected = None - self.illumination = None + self.presenceDetected = False + self.illumination = 0 def from_json(self, js): super().from_json(js) diff --git a/homematicip/functionalChannels.py b/homematicip/functionalChannels.py index a19befd9..ba86ec5f 100644 --- a/homematicip/functionalChannels.py +++ b/homematicip/functionalChannels.py @@ -1,4 +1,5 @@ -from homematicip.group import Group +from homematicip.group import Group +from homematicip.base.enums import * from typing import Iterable @@ -75,4 +76,233 @@ def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.operationLockActive = js["operationLockActive"] \ No newline at end of file + self.operationLockActive = js["operationLockActive"] + +class DeviceIncorrectPositionedChannel(DeviceBaseChannel): + """ this is the representive of the DEVICE_INCORRECT_POSITIONED channel""" + def __init__(self): + super().__init__() + self.incorrectPositioned = False + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.incorrectPositioned = js["incorrectPositioned"] + +class WaterSensorChannel(FunctionalChannel): + """ this is the representive of the WATER_SENSOR_CHANNEL channel""" + def __init__(self): + super().__init__() + self.acousticAlarmSignal = AcousticAlarmSignal.DISABLE_ACOUSTIC_SIGNAL + self.acousticAlarmTiming = AcousticAlarmTiming.PERMANENT + self.acousticWaterAlarmTrigger = WaterAlarmTrigger.NO_ALARM + self.inAppWaterAlarmTrigger = WaterAlarmTrigger.NO_ALARM + self.moistureDetected = False + self.sirenWateralarmTrigger = WaterAlarmTrigger.NO_ALARM + self.waterlevelDetected = False + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.acousticAlarmSignal = AcousticAlarmSignal.from_str(js["acousticAlarmSignal"]) + self.acousticAlarmTiming = AcousticAlarmTiming.from_str(js["acousticAlarmTiming"]) + self.acousticWaterAlarmTrigger = WaterAlarmTrigger.from_str(js["acousticWaterAlarmTrigger"]) + self.inAppWaterAlarmTrigger = WaterAlarmTrigger.from_str(js["inAppWaterAlarmTrigger"]) + self.moistureDetected = js["moistureDetected"] + self.sirenWaterAlarmTrigger = WaterAlarmTrigger.from_str(js["sirenWaterAlarmTrigger"]) + self.waterlevelDetected = js["waterlevelDetected"] + + +class HeatingThermostatChannel(FunctionalChannel): + """ this is the representive of the HEATING_THERMOSTAT_CHANNEL channel""" + def __init__(self): + super().__init__() + self.temperatureOffset = 0 + self.valvePosition = 0.0 + self.valveState = ValveState.ERROR_POSITION + self.setPointTemperature = 0.0 + self.automaticValveAdaptionNeeded = False + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.temperatureOffset = js["temperatureOffset"] + self.valvePosition = js["valvePosition"] + self.valveState = ValveState.from_str(js["valveState"]) + self.setPointTemperature = js["setPointTemperature"] + +class ShutterContactChannel(FunctionalChannel): + """ this is the representive of the SHUTTER_CONTACT_CHANNEL channel""" + def __init__(self): + super().__init__() + self.windowState = WindowState.CLOSED + self.eventDelay = None + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.windowState = WindowState.from_str(js["windowState"]) + self.eventDelay = js["eventDelay"] + +class RotaryHandleChannel(ShutterContactChannel): + """ this is the representive of the ROTARY_HANDLE_CHANNEL channel""" + +class ClimateSensorChannel(FunctionalChannel): + """ this is the representive of the CLIMATE_SENSOR_CHANNEL channel""" + def __init__(self): + super().__init__() + self.actualTemperature = 0 + self.humidity = 0 + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.actualTemperature = js["actualTemperature"] + self.humidity = js["humidity"] + +class WallMountedThermostatWithoutDisplayChannel(ClimateSensorChannel): + """ this is the representive of the WALL_MOUNTED_THERMOSTAT_WITHOUT_DISPLAY_CHANNEL channel""" + def __init__(self): + super().__init__() + self.temperatureOffset = 0 + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.temperatureOffset = js["temperatureOffset"] + +class WallMountedThermostatProChannel(WallMountedThermostatWithoutDisplayChannel): + """ this is the representive of the WALL_MOUNTED_THERMOSTAT_PRO_CHANNEL channel""" + def __init__(self): + super().__init__() + self.display = ClimateControlDisplay.ACTUAL + self.setPointTemperature = 0 + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.setPointTemperature = js["setPointTemperature"] + self.display = ClimateControlDisplay.from_str(js["display"]) + +class SmokeDetectorChannel(FunctionalChannel): + """ this is the representive of the SMOKE_DETECTOR_CHANNEL channel""" + def __init__(self): + super().__init__() + self.smokeDetectorAlarmType = SmokeDetectorAlarmType.IDLE_OFF + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.smokeDetectorAlarmType = SmokeDetectorAlarmType.from_str(js["smokeDetectorAlarmType"]) + + + +class SwitchChannel(FunctionalChannel): + """ this is the representive of the SWITCH_CHANNEL channel""" + def __init__(self): + super().__init__() + self.on = False + self.profileMode = None + self.userDesiredProfileMode = None + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.on = c["on"] + self.profileMode = c["profileMode"] + self.userDesiredProfileMode = c["userDesiredProfileMode"] + + + +class SwitchMeasuringChannel(SwitchChannel): + """ this is the representive of the SWITCH_MEASURING_CHANNEL channel""" + def __init__(self): + super().__init__() + self.energyCounter = 0 + self.currentPowerConsumption = 0 + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.energyCounter = js["energyCounter"] + self.currentPowerConsumption = js["currentPowerConsumption"] + +class DeviceGlobalPumpControlChannel(FunctionalChannel): + """ this is the representive of the DEVICE_GLOBAL_PUMP_CONTROL channel""" + def __init__(self): + super().__init__() + self.globalPumpControl = None + self.heatingValveType = HeatingValveType.NORMALLY_CLOSE + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.globalPumpControl = c["globalPumpControl"] + self.heatingValveType = HeatingValveType.from_str(c["heatingValveType"]) + + +class MotionDetectionChannel(FunctionalChannel): + """ this is the representive of the MOTION_DETECTION_CHANNEL channel""" + def __init__(self): + super().__init__() + self.currentIllumination = None + self.motionDetected = None + self.illumination = None + self.motionBufferActive = False + self.motionDetected = False + self.motionDetectionSendInterval = MotionDetectionSendInterval.SECONDS_30 + self.numberOfBrightnessMeasurements = 0 + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.motionDetected = c["motionDetected"] + self.illumination = c["illumination"] + self.motionBufferActive = c["motionBufferActive"] + self.motionDetected = c["motionDetected"] + self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(c["motionDetectionSendInterval"]) + self.numberOfBrightnessMeasurements = c["numberOfBrightnessMeasurements"] + self.currentIllumination = c["currentIllumination"] + + +class PresenceDetectionChannel(FunctionalChannel): + """ this is the representive of the PRESENCE_DETECTION_CHANNEL channel""" + def __init__(self): + super().__init__() + self.presenceDetected = False + self.illumination = 0 + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.presenceDetected = c["presenceDetected"] + self.illumination = c["illumination"] + +class ShutterChannel(FunctionalChannel): + """ this is the representive of the SHUTTER_CHANNEL channel""" + def __init__(self): + super().__init__() + self.shutterLevel = None + self.bottomToTopReferenceTime = None + self.topToBottomReferenceTime = None + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.shutterLevel = c["shutterLevel"] + self.bottomToTopReferenceTime = c["bottomToTopReferenceTime"] + self.topToBottomReferenceTime = c["topToBottomReferenceTime"] \ No newline at end of file From 0229577a65e4f741b77a53b170a6feb73d7d83a6 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 17:44:42 +0100 Subject: [PATCH 13/21] fixed copy&paste error --- homematicip/functionalChannels.py | 34 +- tests/json_data/new_devices.json | 3935 +++++++++++++++++++++++++++++ 2 files changed, 3952 insertions(+), 17 deletions(-) create mode 100644 tests/json_data/new_devices.json diff --git a/homematicip/functionalChannels.py b/homematicip/functionalChannels.py index ba86ec5f..ad4521b1 100644 --- a/homematicip/functionalChannels.py +++ b/homematicip/functionalChannels.py @@ -217,9 +217,9 @@ def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.on = c["on"] - self.profileMode = c["profileMode"] - self.userDesiredProfileMode = c["userDesiredProfileMode"] + self.on = js["on"] + self.profileMode = js["profileMode"] + self.userDesiredProfileMode = js["userDesiredProfileMode"] @@ -248,8 +248,8 @@ def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.globalPumpControl = c["globalPumpControl"] - self.heatingValveType = HeatingValveType.from_str(c["heatingValveType"]) + self.globalPumpControl = js["globalPumpControl"] + self.heatingValveType = HeatingValveType.from_str(js["heatingValveType"]) class MotionDetectionChannel(FunctionalChannel): @@ -268,13 +268,13 @@ def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.motionDetected = c["motionDetected"] - self.illumination = c["illumination"] - self.motionBufferActive = c["motionBufferActive"] - self.motionDetected = c["motionDetected"] - self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(c["motionDetectionSendInterval"]) - self.numberOfBrightnessMeasurements = c["numberOfBrightnessMeasurements"] - self.currentIllumination = c["currentIllumination"] + self.motionDetected = js["motionDetected"] + self.illumination = js["illumination"] + self.motionBufferActive = js["motionBufferActive"] + self.motionDetected = js["motionDetected"] + self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(js["motionDetectionSendInterval"]) + self.numberOfBrightnessMeasurements = js["numberOfBrightnessMeasurements"] + self.currentIllumination = js["currentIllumination"] class PresenceDetectionChannel(FunctionalChannel): @@ -288,8 +288,8 @@ def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.presenceDetected = c["presenceDetected"] - self.illumination = c["illumination"] + self.presenceDetected = js["presenceDetected"] + self.illumination = js["illumination"] class ShutterChannel(FunctionalChannel): """ this is the representive of the SHUTTER_CHANNEL channel""" @@ -303,6 +303,6 @@ def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.shutterLevel = c["shutterLevel"] - self.bottomToTopReferenceTime = c["bottomToTopReferenceTime"] - self.topToBottomReferenceTime = c["topToBottomReferenceTime"] \ No newline at end of file + self.shutterLevel = js["shutterLevel"] + self.bottomToTopReferenceTime = js["bottomToTopReferenceTime"] + self.topToBottomReferenceTime = js["topToBottomReferenceTime"] \ No newline at end of file diff --git a/tests/json_data/new_devices.json b/tests/json_data/new_devices.json new file mode 100644 index 00000000..07cc59b8 --- /dev/null +++ b/tests/json_data/new_devices.json @@ -0,0 +1,3935 @@ +{ + "clients": { + "00000000-0000-0000-0000-000000000000": { + "clientType": "APP", + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000000", + "label": "SM-G935F" + }, + "00000000-0000-0000-0000-000000000002": { + "clientType": "APP", + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000002", + "label": "HomeAssistant" + }, + "00000000-0000-0000-0000-000000000003": { + "clientType": "APP", + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000003", + "label": "iPad (Viktoria)" + }, + "00000000-0000-0000-0000-000000000004": { + "clientType": "APP", + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000004", + "label": "homematicip-python" + }, + "00000000-0000-0000-0000-000000000005": { + "clientType": "APP", + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000005", + "label": "SM-G935F samsung s7" + }, + "00000000-0000-0000-0000-000000000006": { + "c2cServiceIdentifier": "hmip_alexa_skill", + "clientType": "C2C", + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000006", + "label": "Amazon Alexa Client" + }, + "00000000-0000-0000-0000-000000000007": { + "clientType": "APP", + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000007", + "label": "SM-G920F samsung s6" + }, + "00000000-0000-0000-0000-000000000008": { + "clientType": "APP", + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000008", + "label": "SM-G925F" + } + }, + "devices": { + "3014F7110000000000000000": { + "availableFirmwareVersion": "1.16.8", + "firmwareVersion": "1.16.8", + "firmwareVersionInteger": 69640, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000000", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000010" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -66, + "rssiPeerValue": null, + "sabotage": false, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000000", + "eventDelay": 0, + "functionalChannelType": "SHUTTER_CONTACT_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000011", + "00000000-0000-0000-0000-000000000009" + ], + "index": 1, + "label": "", + "windowState": "CLOSED" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000000", + "label": "Eingang", + "lastStatusUpdate": 1544479257057, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 258, + "modelType": "HMIP-SWDO", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000000", + "type": "SHUTTER_CONTACT", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000001": { + "availableFirmwareVersion": "1.16.8", + "firmwareVersion": "1.16.8", + "firmwareVersionInteger": 69640, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000001", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000012" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -53, + "rssiPeerValue": null, + "sabotage": false, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000001", + "eventDelay": 0, + "functionalChannelType": "SHUTTER_CONTACT_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000013" + ], + "index": 1, + "label": "", + "windowState": "CLOSED" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000001", + "label": "Terrasse", + "lastStatusUpdate": 1544477850708, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 258, + "modelType": "HMIP-SWDO", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000001", + "type": "SHUTTER_CONTACT", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000002": { + "availableFirmwareVersion": "1.16.8", + "firmwareVersion": "1.16.8", + "firmwareVersionInteger": 69640, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000002", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000014" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -65, + "rssiPeerValue": null, + "sabotage": false, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000002", + "eventDelay": 0, + "functionalChannelType": "SHUTTER_CONTACT_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000015" + ], + "index": 1, + "label": "", + "windowState": "CLOSED" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000002", + "label": "Schlafzimmer", + "lastStatusUpdate": 1544480362317, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 258, + "modelType": "HMIP-SWDO", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000002", + "type": "SHUTTER_CONTACT", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000003": { + "availableFirmwareVersion": "1.16.8", + "firmwareVersion": "1.16.8", + "firmwareVersionInteger": 69640, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000003", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000016" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -63, + "rssiPeerValue": null, + "sabotage": false, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000003", + "eventDelay": 0, + "functionalChannelType": "SHUTTER_CONTACT_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000017" + ], + "index": 1, + "label": "", + "windowState": "CLOSED" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000003", + "label": "K\u00fcche", + "lastStatusUpdate": 1544479342015, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 258, + "modelType": "HMIP-SWDO", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000003", + "type": "SHUTTER_CONTACT", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000004": { + "availableFirmwareVersion": "1.16.8", + "firmwareVersion": "1.16.8", + "firmwareVersionInteger": 69640, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000004", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000018" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -56, + "rssiPeerValue": null, + "sabotage": false, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000004", + "eventDelay": 0, + "functionalChannelType": "SHUTTER_CONTACT_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000019" + ], + "index": 1, + "label": "", + "windowState": "OPEN" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000004", + "label": "GEO+Strom", + "lastStatusUpdate": 1544479325761, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 258, + "modelType": "HMIP-SWDO", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000004", + "type": "SHUTTER_CONTACT", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000005": { + "availableFirmwareVersion": "2.6.2", + "firmwareVersion": "2.6.2", + "firmwareVersionInteger": 132610, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000005", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000020" + ], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": true, + "rssiDeviceValue": -46, + "rssiPeerValue": -47, + "unreach": false + }, + "1": { + "currentPowerConsumption": 0.0, + "deviceId": "3014F7110000000000000005", + "energyCounter": 0.023700000000000002, + "functionalChannelType": "SWITCH_MEASURING_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000021" + ], + "index": 1, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000005", + "label": "Schalt-Mess-Steckdose", + "lastStatusUpdate": 1544479988534, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 262, + "modelType": "HMIP-PSM", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000005", + "type": "PLUGABLE_SWITCH_MEASURING", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000006": { + "automaticValveAdaptionNeeded": false, + "availableFirmwareVersion": "2.0.2", + "firmwareVersion": "2.0.2", + "firmwareVersionInteger": 131074, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000006", + "dutyCycle": false, + "functionalChannelType": "DEVICE_OPERATIONLOCK", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000020" + ], + "index": 0, + "label": "", + "lowBat": false, + "operationLockActive": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -52, + "rssiPeerValue": -49, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000006", + "functionalChannelType": "HEATING_THERMOSTAT_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000022" + ], + "index": 1, + "label": "", + "setPointTemperature": 19.0, + "temperatureOffset": 0.0, + "valvePosition": 0.0, + "valveState": "ADAPTION_DONE" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000006", + "label": "Wohnzimmer", + "lastStatusUpdate": 1544480010168, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 269, + "modelType": "HMIP-eTRV", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000006", + "type": "HEATING_THERMOSTAT", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000007": { + "automaticValveAdaptionNeeded": false, + "availableFirmwareVersion": "2.0.2", + "firmwareVersion": "2.0.2", + "firmwareVersionInteger": 131074, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000007", + "dutyCycle": false, + "functionalChannelType": "DEVICE_OPERATIONLOCK", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000014" + ], + "index": 0, + "label": "", + "lowBat": false, + "operationLockActive": true, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -61, + "rssiPeerValue": -59, + "unreach": true + }, + "1": { + "deviceId": "3014F7110000000000000007", + "functionalChannelType": "HEATING_THERMOSTAT_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000023" + ], + "index": 1, + "label": "", + "setPointTemperature": 18.5, + "temperatureOffset": 0.0, + "valvePosition": 0.04, + "valveState": "ADAPTION_DONE" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000007", + "label": "Schlafzimmer", + "lastStatusUpdate": 1544143682242, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 269, + "modelType": "HMIP-eTRV", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000007", + "type": "HEATING_THERMOSTAT", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000008": { + "availableFirmwareVersion": "1.2.10", + "firmwareVersion": "1.2.10", + "firmwareVersionInteger": 66058, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000008", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000020" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -65, + "rssiPeerValue": null, + "sabotage": false, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000008", + "eventDelay": 0, + "functionalChannelType": "ROTARY_HANDLE_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000024", + "00000000-0000-0000-0000-000000000009" + ], + "index": 1, + "label": "", + "windowState": "CLOSED" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000008", + "label": "Griffsensor", + "lastStatusUpdate": 1544478527888, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 286, + "modelType": "HmIP-SRH", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000008", + "type": "ROTARY_HANDLE_SENSOR", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000009": { + "availableFirmwareVersion": "1.10.12", + "firmwareVersion": "1.10.12", + "firmwareVersionInteger": 68108, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000009", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000020" + ], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -65, + "rssiPeerValue": -58, + "unreach": false + }, + "1": { + "currentPowerConsumption": 0.01, + "deviceId": "3014F7110000000000000009", + "energyCounter": 3.7813999999999997, + "functionalChannelType": "SWITCH_MEASURING_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000025", + "00000000-0000-0000-0000-000000000026", + "00000000-0000-0000-0000-000000000027", + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000028", + "00000000-0000-0000-0000-000000000029", + "00000000-0000-0000-0000-000000000030" + ], + "index": 1, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000009", + "label": "Licht", + "lastStatusUpdate": 1544479389228, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 288, + "modelType": "HmIP-BSM", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000009", + "type": "BRAND_SWITCH_MEASURING", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000010": { + "availableFirmwareVersion": "1.10.12", + "firmwareVersion": "1.10.12", + "firmwareVersionInteger": 68108, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000010", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000014" + ], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -66, + "rssiPeerValue": -52, + "unreach": false + }, + "1": { + "currentPowerConsumption": 0.02, + "deviceId": "3014F7110000000000000010", + "energyCounter": 1.7441999999999998, + "functionalChannelType": "SWITCH_MEASURING_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000026", + "00000000-0000-0000-0000-000000000031", + "00000000-0000-0000-0000-000000000032", + "00000000-0000-0000-0000-000000000033", + "00000000-0000-0000-0000-000000000030", + "00000000-0000-0000-0000-000000000034" + ], + "index": 1, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000010", + "label": "Licht zwei", + "lastStatusUpdate": 1544478486312, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 288, + "modelType": "HmIP-BSM", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000010", + "type": "BRAND_SWITCH_MEASURING", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000011": { + "availableFirmwareVersion": "1.4.8", + "firmwareVersion": "1.4.8", + "firmwareVersionInteger": 66568, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000011", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000020", + "00000000-0000-0000-0000-000000000035" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -56, + "rssiPeerValue": -52, + "sabotage": false, + "unreach": false + }, + "1": { + "currentIllumination": null, + "deviceId": "3014F7110000000000000011", + "functionalChannelType": "MOTION_DETECTION_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000024", + "00000000-0000-0000-0000-000000000035" + ], + "illumination": 0.1, + "index": 1, + "label": "", + "motionBufferActive": false, + "motionDetected": true, + "motionDetectionSendInterval": "SECONDS_480", + "numberOfBrightnessMeasurements": 7 + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000011", + "label": "Wohnzimmer", + "lastStatusUpdate": 1544480290322, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 291, + "modelType": "HmIP-SMI", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000011", + "type": "MOTION_DETECTOR_INDOOR", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000012": { + "availableFirmwareVersion": "1.4.8", + "firmwareVersion": "1.4.8", + "firmwareVersionInteger": 66568, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000012", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000014", + "00000000-0000-0000-0000-000000000035" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -37, + "rssiPeerValue": -39, + "sabotage": false, + "unreach": false + }, + "1": { + "currentIllumination": null, + "deviceId": "3014F7110000000000000012", + "functionalChannelType": "MOTION_DETECTION_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000015", + "00000000-0000-0000-0000-000000000035" + ], + "illumination": 0.0, + "index": 1, + "label": "", + "motionBufferActive": false, + "motionDetected": false, + "motionDetectionSendInterval": "SECONDS_480", + "numberOfBrightnessMeasurements": 7 + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000012", + "label": "Schlafzimmer", + "lastStatusUpdate": 1544480460068, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 291, + "modelType": "HmIP-SMI", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000012", + "type": "MOTION_DETECTOR_INDOOR", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000013": { + "availableFirmwareVersion": "1.4.8", + "firmwareVersion": "1.4.8", + "firmwareVersionInteger": 66568, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000013", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000009", + "00000000-0000-0000-0000-000000000016", + "00000000-0000-0000-0000-000000000035" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -59, + "rssiPeerValue": -59, + "sabotage": false, + "unreach": false + }, + "1": { + "currentIllumination": null, + "deviceId": "3014F7110000000000000013", + "functionalChannelType": "MOTION_DETECTION_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000017", + "00000000-0000-0000-0000-000000000035" + ], + "illumination": 0.0, + "index": 1, + "label": "", + "motionBufferActive": false, + "motionDetected": true, + "motionDetectionSendInterval": "SECONDS_480", + "numberOfBrightnessMeasurements": 7 + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000013", + "label": "K\u00fcche", + "lastStatusUpdate": 1544480307099, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 291, + "modelType": "HmIP-SMI", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000013", + "type": "MOTION_DETECTOR_INDOOR", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000014": { + "automaticValveAdaptionNeeded": false, + "availableFirmwareVersion": "2.0.2", + "firmwareVersion": "2.0.2", + "firmwareVersionInteger": 131074, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000014", + "dutyCycle": false, + "functionalChannelType": "DEVICE_OPERATIONLOCK", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000036" + ], + "index": 0, + "label": "", + "lowBat": false, + "operationLockActive": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -53, + "rssiPeerValue": -55, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000014", + "functionalChannelType": "HEATING_THERMOSTAT_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000037" + ], + "index": 1, + "label": "", + "setPointTemperature": 19.0, + "temperatureOffset": 0.0, + "valvePosition": 0.0, + "valveState": "ADAPTION_DONE" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000014", + "label": "Badezimmer", + "lastStatusUpdate": 1544480470447, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 295, + "modelType": "HmIP-eTRV-2", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000014", + "type": "HEATING_THERMOSTAT", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000015": { + "availableFirmwareVersion": "0.0.0", + "firmwareVersion": "1.0.11", + "firmwareVersionInteger": 65547, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000015", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000016", + "00000000-0000-0000-0000-000000000035" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -52, + "rssiPeerValue": null, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000015", + "functionalChannelType": "SMOKE_DETECTOR_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000038", + "00000000-0000-0000-0000-000000000017" + ], + "index": 1, + "label": "", + "smokeDetectorAlarmType": "IDLE_OFF" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000015", + "label": "K\u00fcche", + "lastStatusUpdate": 1544428759360, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 296, + "modelType": "HmIP-SWSD", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000015", + "type": "SMOKE_DETECTOR", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000016": { + "availableFirmwareVersion": "1.0.19", + "firmwareVersion": "1.0.19", + "firmwareVersionInteger": 65555, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000016", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000020" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -42, + "rssiPeerValue": null, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000027", + "00000000-0000-0000-0000-000000000021" + ], + "index": 1, + "label": "" + }, + "2": { + "deviceId": "3014F7110000000000000016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000027", + "00000000-0000-0000-0000-000000000021" + ], + "index": 2, + "label": "" + }, + "3": { + "deviceId": "3014F7110000000000000016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 2, + "groups": [ + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000033" + ], + "index": 3, + "label": "" + }, + "4": { + "deviceId": "3014F7110000000000000016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 2, + "groups": [ + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000033" + ], + "index": 4, + "label": "" + }, + "5": { + "deviceId": "3014F7110000000000000016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 3, + "groups": [ + "00000000-0000-0000-0000-000000000039", + "00000000-0000-0000-0000-000000000021" + ], + "index": 5, + "label": "" + }, + "6": { + "deviceId": "3014F7110000000000000016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 3, + "groups": [ + "00000000-0000-0000-0000-000000000039", + "00000000-0000-0000-0000-000000000021" + ], + "index": 6, + "label": "" + }, + "7": { + "deviceId": "3014F7110000000000000016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 4, + "groups": [ + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000030" + ], + "index": 7, + "label": "" + }, + "8": { + "deviceId": "3014F7110000000000000016", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 4, + "groups": [ + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000030" + ], + "index": 8, + "label": "" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000016", + "label": "Fernbedienung - 8 Tasten", + "lastStatusUpdate": 1544479483638, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 299, + "modelType": "HmIP-RC8", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000016", + "type": "REMOTE_CONTROL_8", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000017": { + "availableFirmwareVersion": "1.0.19", + "firmwareVersion": "1.0.19", + "firmwareVersionInteger": 65555, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000017", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000020" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -61, + "rssiPeerValue": null, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000040" + ], + "index": 1, + "label": "" + }, + "2": { + "deviceId": "3014F7110000000000000017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000040" + ], + "index": 2, + "label": "" + }, + "3": { + "deviceId": "3014F7110000000000000017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 2, + "groups": [ + "00000000-0000-0000-0000-000000000025", + "00000000-0000-0000-0000-000000000021" + ], + "index": 3, + "label": "" + }, + "4": { + "deviceId": "3014F7110000000000000017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 2, + "groups": [ + "00000000-0000-0000-0000-000000000025", + "00000000-0000-0000-0000-000000000021" + ], + "index": 4, + "label": "" + }, + "5": { + "deviceId": "3014F7110000000000000017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 3, + "groups": [ + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000032" + ], + "index": 5, + "label": "" + }, + "6": { + "deviceId": "3014F7110000000000000017", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 3, + "groups": [ + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000032" + ], + "index": 6, + "label": "" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000017", + "label": "Wandtaster - 6-fach", + "lastStatusUpdate": 1544475961687, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 300, + "modelType": "HmIP-WRC6", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000017", + "type": "PUSH_BUTTON_6", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000018": { + "availableFirmwareVersion": "0.0.0", + "firmwareVersion": "1.8.12", + "firmwareVersionInteger": 67596, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000018", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000041" + ], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -35, + "rssiPeerValue": -36, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000018", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 1, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "2": { + "deviceId": "3014F7110000000000000018", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 2, + "groups": [ + "00000000-0000-0000-0000-000000000042", + "00000000-0000-0000-0000-000000000040" + ], + "index": 2, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "3": { + "deviceId": "3014F7110000000000000018", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 3, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 3, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "4": { + "deviceId": "3014F7110000000000000018", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 4, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 4, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "5": { + "deviceId": "3014F7110000000000000018", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 5, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 5, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "6": { + "deviceId": "3014F7110000000000000018", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 6, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 6, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "7": { + "deviceId": "3014F7110000000000000018", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 7, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 7, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "8": { + "deviceId": "3014F7110000000000000018", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 8, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 8, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000018", + "label": "ioBroker", + "lastStatusUpdate": 1543746604446, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 307, + "modelType": "HmIP-MOD-OC8", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000018", + "type": "OPEN_COLLECTOR_8_MODULE", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000019": { + "availableFirmwareVersion": "0.0.0", + "firmwareVersion": "1.8.12", + "firmwareVersionInteger": 67596, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000019", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000043" + ], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -40, + "rssiPeerValue": -39, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000019", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000044" + ], + "index": 1, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "2": { + "deviceId": "3014F7110000000000000019", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 2, + "groups": [ + "00000000-0000-0000-0000-000000000044" + ], + "index": 2, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "3": { + "deviceId": "3014F7110000000000000019", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 3, + "groups": [ + "00000000-0000-0000-0000-000000000044" + ], + "index": 3, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "4": { + "deviceId": "3014F7110000000000000019", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 4, + "groups": [ + "00000000-0000-0000-0000-000000000044" + ], + "index": 4, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "5": { + "deviceId": "3014F7110000000000000019", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 5, + "groups": [ + "00000000-0000-0000-0000-000000000044" + ], + "index": 5, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "6": { + "deviceId": "3014F7110000000000000019", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 6, + "groups": [ + "00000000-0000-0000-0000-000000000044" + ], + "index": 6, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "7": { + "deviceId": "3014F7110000000000000019", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 7, + "groups": [ + "00000000-0000-0000-0000-000000000044" + ], + "index": 7, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "8": { + "deviceId": "3014F7110000000000000019", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 8, + "groups": [ + "00000000-0000-0000-0000-000000000044" + ], + "index": 8, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000019", + "label": "Radio", + "lastStatusUpdate": 1543746829532, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 307, + "modelType": "HmIP-MOD-OC8", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000019", + "type": "OPEN_COLLECTOR_8_MODULE", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000020": { + "availableFirmwareVersion": "1.4.8", + "firmwareVersion": "1.4.8", + "firmwareVersionInteger": 66568, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000020", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000014" + ], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -52, + "rssiPeerValue": -48, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000020", + "dimLevel": 0.0, + "functionalChannelType": "DIMMER_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000039", + "00000000-0000-0000-0000-000000000031", + "00000000-0000-0000-0000-000000000045", + "00000000-0000-0000-0000-000000000030" + ], + "index": 1, + "label": "", + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000020", + "label": "Tischlampe", + "lastStatusUpdate": 1544479084154, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 310, + "modelType": "HmIP-PDT", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000020", + "type": "PLUGGABLE_DIMMER", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000021": { + "availableFirmwareVersion": "2.2.2", + "firmwareVersion": "2.2.2", + "firmwareVersionInteger": 131586, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000021", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000014" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -63, + "rssiPeerValue": -55, + "unreach": false + }, + "1": { + "actualTemperature": 19.5, + "deviceId": "3014F7110000000000000021", + "display": "ACTUAL_HUMIDITY", + "functionalChannelType": "WALL_MOUNTED_THERMOSTAT_PRO_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000023" + ], + "humidity": 70, + "index": 1, + "label": "", + "setPointTemperature": 18.5, + "temperatureOffset": 0.0 + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000021", + "label": "SchlafZ.- Temperatur- und Luftfeuchtigkeitssensor", + "lastStatusUpdate": 1544480413257, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 313, + "modelType": "HmIP-STHD", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000021", + "type": "TEMPERATURE_HUMIDITY_SENSOR_DISPLAY", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000022": { + "availableFirmwareVersion": "2.2.2", + "firmwareVersion": "2.2.2", + "firmwareVersionInteger": 131586, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000022", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000020" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -61, + "rssiPeerValue": -58, + "unreach": false + }, + "1": { + "actualTemperature": 21.1, + "deviceId": "3014F7110000000000000022", + "display": "ACTUAL_HUMIDITY", + "functionalChannelType": "WALL_MOUNTED_THERMOSTAT_PRO_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000022" + ], + "humidity": 64, + "index": 1, + "label": "", + "setPointTemperature": 19.0, + "temperatureOffset": 0.0 + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000022", + "label": "WZ - Temperatur- und Luftfeuchtigkeitssensor", + "lastStatusUpdate": 1544480467605, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 313, + "modelType": "HmIP-STHD", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000022", + "type": "TEMPERATURE_HUMIDITY_SENSOR_DISPLAY", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000023": { + "availableFirmwareVersion": "1.6.4", + "firmwareVersion": "1.6.4", + "firmwareVersionInteger": 67076, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000023", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000016" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -63, + "rssiPeerValue": -60, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000023", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000046", + "00000000-0000-0000-0000-000000000047" + ], + "index": 1, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "MANUAL" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000023", + "label": "Kaffeemaschine", + "lastStatusUpdate": 1544480026802, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 320, + "modelType": "HmIP-PCBS-BAT", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000023", + "type": "PRINTED_CIRCUIT_BOARD_SWITCH_BATTERY", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000024": { + "availableFirmwareVersion": "0.0.0", + "firmwareVersion": "1.0.12", + "firmwareVersionInteger": 65548, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000024", + "dutyCycle": false, + "functionalChannelType": "DEVICE_PERMANENT_FULL_RX", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000010" + ], + "index": 0, + "label": "", + "lowBat": false, + "permanentFullRx": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -46, + "rssiPeerValue": -51, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000000000024", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000048", + "00000000-0000-0000-0000-000000000034" + ], + "index": 1, + "label": "" + }, + "2": { + "deviceId": "3014F7110000000000000024", + "functionalChannelType": "SINGLE_KEY_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000048", + "00000000-0000-0000-0000-000000000034" + ], + "index": 2, + "label": "" + }, + "3": { + "currentIllumination": null, + "deviceId": "3014F7110000000000000024", + "functionalChannelType": "MOTION_DETECTION_CHANNEL", + "groupIndex": 2, + "groups": [], + "illumination": 0.0, + "index": 3, + "label": "", + "motionBufferActive": true, + "motionDetected": false, + "motionDetectionSendInterval": "SECONDS_240", + "numberOfBrightnessMeasurements": 7 + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000024", + "label": "Bewegungsmelder f\u00fcr 55er Rahmen \u2013 innen", + "lastStatusUpdate": 1544478382207, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 338, + "modelType": "HmIP-SMI55", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000024", + "type": "MOTION_DETECTOR_PUSH_BUTTON", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000025": { + "availableFirmwareVersion": "1.0.14", + "firmwareVersion": "1.0.14", + "firmwareVersionInteger": 65550, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000025", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000012" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -55, + "rssiPeerValue": null, + "unreach": false + }, + "1": { + "actualTemperature": 4.3, + "deviceId": "3014F7110000000000000025", + "functionalChannelType": "WEATHER_SENSOR_PRO_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000049" + ], + "humidity": 76, + "illumination": 0.0, + "illuminationThresholdSunshine": 3500.0, + "index": 1, + "label": "", + "raining": false, + "storm": false, + "sunshine": false, + "todayRainCounter": 2.0, + "todaySunshineDuration": 32, + "totalRainCounter": 240.4, + "totalSunshineDuration": 57698, + "weathervaneAlignmentNeeded": false, + "windDirection": 317.5, + "windDirectionVariation": 56.25, + "windSpeed": 4.1, + "windValueType": "MAX_VALUE", + "yesterdayRainCounter": 5.300000000000011, + "yesterdaySunshineDuration": 32 + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000025", + "label": "Wettersensor \u2013 pro", + "lastStatusUpdate": 1544480354027, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 352, + "modelType": "HmIP-SWO-PR", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000025", + "type": "WEATHER_SENSOR_PRO", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000026": { + "availableFirmwareVersion": "0.0.0", + "firmwareVersion": "1.0.2", + "firmwareVersionInteger": 65538, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000026", + "dutyCycle": false, + "functionalChannelType": "DEVICE_INCORRECT_POSITIONED", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000036", + "00000000-0000-0000-0000-000000000035" + ], + "incorrectPositioned": false, + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -65, + "rssiPeerValue": null, + "unreach": false + }, + "1": { + "acousticAlarmSignal": "FREQUENCY_RISING", + "acousticAlarmTiming": "THREE_MINUTES", + "acousticWaterAlarmTrigger": "WATER_MOISTURE_DETECTION", + "deviceId": "3014F7110000000000000026", + "functionalChannelType": "WATER_SENSOR_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000050" + ], + "inAppWaterAlarmTrigger": "WATER_MOISTURE_DETECTION", + "index": 1, + "label": "", + "moistureDetected": false, + "sirenWaterAlarmTrigger": "WATER_MOISTURE_DETECTION", + "waterlevelDetected": false + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000026", + "label": "H2O Badewanne", + "lastStatusUpdate": 1544476978933, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 353, + "modelType": "HmIP-SWD", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000026", + "type": "WATER_SENSOR", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000000000027": { + "availableFirmwareVersion": "0.0.0", + "firmwareVersion": "1.0.2", + "firmwareVersionInteger": 65538, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000027", + "dutyCycle": false, + "functionalChannelType": "DEVICE_INCORRECT_POSITIONED", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000016", + "00000000-0000-0000-0000-000000000035" + ], + "incorrectPositioned": false, + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -64, + "rssiPeerValue": null, + "unreach": false + }, + "1": { + "acousticAlarmSignal": "FREQUENCY_RISING", + "acousticAlarmTiming": "THREE_MINUTES", + "acousticWaterAlarmTrigger": "WATER_MOISTURE_DETECTION", + "deviceId": "3014F7110000000000000027", + "functionalChannelType": "WATER_SENSOR_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000017" + ], + "inAppWaterAlarmTrigger": "WATER_MOISTURE_DETECTION", + "index": 1, + "label": "", + "moistureDetected": false, + "sirenWaterAlarmTrigger": "WATER_MOISTURE_DETECTION", + "waterlevelDetected": false + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000027", + "label": "H2O K\u00fcche", + "lastStatusUpdate": 1544477018101, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 353, + "modelType": "HmIP-SWD", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110000000000000027", + "type": "WATER_SENSOR", + "updateState": "UP_TO_DATE" + } + }, + "groups": { + "00000000-0000-0000-0000-000000000039": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000020" + }, + { + "channelIndex": 6, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 5, + "deviceId": "3014F7110000000000000016" + } + ], + "dimLevel": 0.0, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000039", + "label": "FB Dimmer", + "lastStatusUpdate": 1544479483638, + "lowBat": false, + "metaGroupId": null, + "on": false, + "onLevel": 1.005, + "onTime": 111600.0, + "sensorSpecificParameters": {}, + "type": "EXTENDED_LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000032": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000010" + }, + { + "channelIndex": 6, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 5, + "deviceId": "3014F7110000000000000017" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000032", + "label": "6x Wand Schlafzimmer", + "lastStatusUpdate": 1544478486312, + "lowBat": false, + "metaGroupId": null, + "on": false, + "onLevel": 1.005, + "onTime": 111600.0, + "sensorSpecificParameters": {}, + "type": "EXTENDED_LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000033": { + "channels": [ + { + "channelIndex": 3, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000010" + }, + { + "channelIndex": 4, + "deviceId": "3014F7110000000000000016" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000033", + "label": "FB Licht Schlaffzimmer", + "lastStatusUpdate": 1544479483638, + "lowBat": false, + "metaGroupId": null, + "on": false, + "onLevel": 1.005, + "onTime": 111600.0, + "sensorSpecificParameters": {}, + "type": "EXTENDED_LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000051": { + "channels": [], + "dutyCycle": null, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000051", + "label": "HEATING_TEMPERATURE_LIMITER", + "lastStatusUpdate": 0, + "lowBat": null, + "metaGroupId": null, + "type": "HEATING_TEMPERATURE_LIMITER", + "unreach": null + }, + "00000000-0000-0000-0000-000000000014": { + "channels": [ + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000021" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000010" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000002" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000012" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000020" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000007" + } + ], + "configPending": false, + "dutyCycle": false, + "groups": [ + "00000000-0000-0000-0000-000000000023", + "00000000-0000-0000-0000-000000000031", + "00000000-0000-0000-0000-000000000015" + ], + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000014", + "incorrectPositioned": null, + "label": "Schlafen", + "lastStatusUpdate": 1544480460068, + "lowBat": false, + "metaGroupId": null, + "sabotage": false, + "type": "META", + "unreach": true + }, + "00000000-0000-0000-0000-000000000037": { + "activeProfile": "PROFILE_1", + "actualTemperature": null, + "boostDuration": 30, + "boostMode": false, + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000014" + } + ], + "controlMode": "AUTOMATIC", + "controllable": true, + "cooling": null, + "coolingAllowed": false, + "coolingIgnored": false, + "dutyCycle": false, + "ecoAllowed": true, + "ecoIgnored": false, + "externalClockCoolingTemperature": 23.0, + "externalClockEnabled": false, + "externalClockHeatingTemperature": 19.0, + "floorHeatingMode": "FLOOR_HEATING_STANDARD", + "homeId": "00000000-0000-0000-0000-000000000001", + "humidity": null, + "humidityLimitEnabled": true, + "humidityLimitValue": 60, + "id": "00000000-0000-0000-0000-000000000037", + "label": "Badezimmer", + "lastStatusUpdate": 1544480470447, + "lowBat": false, + "maxTemperature": 30.0, + "metaGroupId": "00000000-0000-0000-0000-000000000036", + "minTemperature": 5.0, + "partyMode": false, + "profiles": { + "PROFILE_1": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000037", + "index": "PROFILE_1", + "name": "Winter Modus", + "profileId": "00000000-0000-0000-0000-000000000052", + "visible": true + }, + "PROFILE_2": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000037", + "index": "PROFILE_2", + "name": "Sommer Modus", + "profileId": "00000000-0000-0000-0000-000000000053", + "visible": true + }, + "PROFILE_3": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000037", + "index": "PROFILE_3", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000054", + "visible": false + }, + "PROFILE_4": { + "enabled": false, + "groupId": "00000000-0000-0000-0000-000000000037", + "index": "PROFILE_4", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000055", + "visible": true + }, + "PROFILE_5": { + "enabled": false, + "groupId": "00000000-0000-0000-0000-000000000037", + "index": "PROFILE_5", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000056", + "visible": true + }, + "PROFILE_6": { + "enabled": false, + "groupId": "00000000-0000-0000-0000-000000000037", + "index": "PROFILE_6", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000057", + "visible": false + } + }, + "sabotage": null, + "setPointTemperature": 19.0, + "type": "HEATING", + "unreach": false, + "valvePosition": 0.0, + "windowOpenTemperature": 12.0, + "windowState": null + }, + "00000000-0000-0000-0000-000000000058": { + "boilerFollowUpTime": 0, + "boilerLeadTime": 0, + "channels": [], + "dutyCycle": null, + "heatDemand": null, + "heatDemandRuleEnabled": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000058", + "label": "HEATING_COOLING_DEMAND_BOILER", + "lastStatusUpdate": 0, + "lowBat": null, + "metaGroupId": null, + "on": null, + "triggered": false, + "type": "HEATING_COOLING_DEMAND_BOILER", + "unreach": null + }, + "00000000-0000-0000-0000-000000000022": { + "activeProfile": "PROFILE_1", + "actualTemperature": 21.1, + "boostDuration": 30, + "boostMode": false, + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000022" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000006" + } + ], + "controlMode": "AUTOMATIC", + "controllable": true, + "cooling": null, + "coolingAllowed": false, + "coolingIgnored": false, + "dutyCycle": false, + "ecoAllowed": true, + "ecoIgnored": false, + "externalClockCoolingTemperature": 23.0, + "externalClockEnabled": false, + "externalClockHeatingTemperature": 19.0, + "floorHeatingMode": "FLOOR_HEATING_STANDARD", + "homeId": "00000000-0000-0000-0000-000000000001", + "humidity": 64, + "humidityLimitEnabled": true, + "humidityLimitValue": 60, + "id": "00000000-0000-0000-0000-000000000022", + "label": "Wohnzimmer", + "lastStatusUpdate": 1544480467605, + "lowBat": false, + "maxTemperature": 23.0, + "metaGroupId": "00000000-0000-0000-0000-000000000020", + "minTemperature": 10.0, + "partyMode": false, + "profiles": { + "PROFILE_1": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000022", + "index": "PROFILE_1", + "name": "Winter Modus", + "profileId": "00000000-0000-0000-0000-000000000059", + "visible": true + }, + "PROFILE_2": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000022", + "index": "PROFILE_2", + "name": "Sommer Modus", + "profileId": "00000000-0000-0000-0000-000000000060", + "visible": true + }, + "PROFILE_3": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000022", + "index": "PROFILE_3", + "name": "Kamin Modus", + "profileId": "00000000-0000-0000-0000-000000000061", + "visible": false + }, + "PROFILE_4": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000022", + "index": "PROFILE_4", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000062", + "visible": true + }, + "PROFILE_5": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000022", + "index": "PROFILE_5", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000063", + "visible": true + }, + "PROFILE_6": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000022", + "index": "PROFILE_6", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000064", + "visible": false + } + }, + "sabotage": null, + "setPointTemperature": 19.0, + "type": "HEATING", + "unreach": false, + "valvePosition": 0.0, + "windowOpenTemperature": 12.0, + "windowState": null + }, + "00000000-0000-0000-0000-000000000048": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000024" + }, + { + "channelIndex": 2, + "deviceId": "3014F7110000000000000024" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000048", + "label": "Flur", + "lastStatusUpdate": 1544478382207, + "lowBat": false, + "metaGroupId": "00000000-0000-0000-0000-000000000010", + "on": null, + "processing": null, + "shutterLevel": null, + "slatsLevel": null, + "type": "SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000009": { + "active": false, + "channels": [ + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000013" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000012" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000000" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000000" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000011" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000002" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000002" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000008" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000008" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000001" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000001" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000003" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000003" + } + ], + "configPending": false, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000009", + "ignorableDevices": [], + "label": "EXTERNAL", + "lastStatusUpdate": 1544480460068, + "lowBat": false, + "metaGroupId": null, + "motionDetected": null, + "presenceDetected": null, + "sabotage": false, + "silent": false, + "type": "SECURITY_ZONE", + "unreach": false, + "windowState": "CLOSED", + "zoneAssignmentIndex": "ALARM_MODE_ZONE_2" + }, + "00000000-0000-0000-0000-000000000065": { + "channels": [], + "dutyCycle": null, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000065", + "label": "HEATING_CHANGEOVER", + "lastStatusUpdate": 0, + "lowBat": null, + "metaGroupId": null, + "on": null, + "type": "HEATING_CHANGEOVER", + "unreach": null + }, + "00000000-0000-0000-0000-000000000011": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000000" + } + ], + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000011", + "label": "Flur", + "lastStatusUpdate": 1544479257057, + "lowBat": false, + "metaGroupId": "00000000-0000-0000-0000-000000000010", + "moistureDetected": null, + "motionDetected": null, + "powerMainsFailure": null, + "presenceDetected": null, + "sabotage": false, + "smokeDetectorAlarmType": null, + "type": "SECURITY", + "unreach": false, + "waterlevelDetected": null, + "windowState": "CLOSED" + }, + "00000000-0000-0000-0000-000000000020": { + "channels": [ + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000005" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000011" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000008" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000006" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000022" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000009" + } + ], + "configPending": false, + "dutyCycle": false, + "groups": [ + "00000000-0000-0000-0000-000000000024", + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000022" + ], + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000020", + "incorrectPositioned": null, + "label": "Wohnzimmer", + "lastStatusUpdate": 1544480467605, + "lowBat": false, + "metaGroupId": null, + "sabotage": false, + "type": "META", + "unreach": false + }, + "00000000-0000-0000-0000-000000000026": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000010" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000009" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000026", + "label": "PANIC", + "lastStatusUpdate": 1544479389228, + "lowBat": null, + "metaGroupId": null, + "on": false, + "type": "LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000010": { + "channels": [ + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000024" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000000" + } + ], + "configPending": false, + "dutyCycle": false, + "groups": [ + "00000000-0000-0000-0000-000000000011", + "00000000-0000-0000-0000-000000000048" + ], + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000010", + "incorrectPositioned": null, + "label": "Flur", + "lastStatusUpdate": 1544479257057, + "lowBat": false, + "metaGroupId": null, + "sabotage": false, + "type": "META", + "unreach": false + }, + "00000000-0000-0000-0000-000000000034": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000010" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000024" + }, + { + "channelIndex": 2, + "deviceId": "3014F7110000000000000024" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000034", + "label": "55", + "lastStatusUpdate": 1544478486312, + "lowBat": false, + "metaGroupId": null, + "on": false, + "onLevel": 1.005, + "onTime": 111600.0, + "sensorSpecificParameters": {}, + "type": "EXTENDED_LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000043": { + "channels": [ + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000019" + } + ], + "configPending": false, + "dutyCycle": false, + "groups": [ + "00000000-0000-0000-0000-000000000044" + ], + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000043", + "incorrectPositioned": null, + "label": "Internet Radio", + "lastStatusUpdate": 1543746829532, + "lowBat": null, + "metaGroupId": null, + "sabotage": null, + "type": "META", + "unreach": false + }, + "00000000-0000-0000-0000-000000000041": { + "channels": [ + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000018" + } + ], + "configPending": false, + "dutyCycle": false, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000041", + "incorrectPositioned": null, + "label": "ioBroker", + "lastStatusUpdate": 1543746604288, + "lowBat": null, + "metaGroupId": null, + "sabotage": null, + "type": "META", + "unreach": false + }, + "00000000-0000-0000-0000-000000000066": { + "channels": [], + "dutyCycle": null, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000066", + "label": "INBOX", + "lastStatusUpdate": 1544211904778, + "lowBat": null, + "metaGroupId": null, + "type": "INBOX", + "unreach": null + }, + "00000000-0000-0000-0000-000000000028": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000009" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000028", + "label": "COMING_HOME", + "lastStatusUpdate": 1544479389228, + "lowBat": null, + "metaGroupId": null, + "on": false, + "type": "LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000012": { + "channels": [ + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000025" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000001" + } + ], + "configPending": false, + "dutyCycle": false, + "groups": [ + "00000000-0000-0000-0000-000000000049", + "00000000-0000-0000-0000-000000000013" + ], + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000012", + "incorrectPositioned": null, + "label": "Terrasse", + "lastStatusUpdate": 1544480354027, + "lowBat": false, + "metaGroupId": null, + "sabotage": false, + "type": "META", + "unreach": false + }, + "00000000-0000-0000-0000-000000000067": { + "channels": [], + "dutyCycle": null, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000067", + "label": "HEATING_HUMIDITY_LIMITER", + "lastStatusUpdate": 0, + "lowBat": null, + "metaGroupId": null, + "type": "HEATING_HUMIDITY_LIMITER", + "unreach": null + }, + "00000000-0000-0000-0000-000000000030": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000010" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000009" + }, + { + "channelIndex": 8, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000020" + }, + { + "channelIndex": 7, + "deviceId": "3014F7110000000000000016" + } + ], + "dimLevel": 0.0, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000030", + "label": "FB Ganzes Licht ", + "lastStatusUpdate": 1544479483638, + "lowBat": false, + "metaGroupId": null, + "on": false, + "onLevel": 1.005, + "onTime": 111600.0, + "sensorSpecificParameters": {}, + "type": "EXTENDED_LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000016": { + "channels": [ + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000027" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000013" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000015" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000023" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000003" + } + ], + "configPending": false, + "dutyCycle": false, + "groups": [ + "00000000-0000-0000-0000-000000000017", + "00000000-0000-0000-0000-000000000047" + ], + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000016", + "incorrectPositioned": false, + "label": "K\u00fcche", + "lastStatusUpdate": 1544480307099, + "lowBat": false, + "metaGroupId": null, + "sabotage": false, + "type": "META", + "unreach": false + }, + "00000000-0000-0000-0000-000000000068": { + "acousticFeedbackEnabled": true, + "channels": [], + "dimLevel": null, + "dutyCycle": null, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000068", + "label": "BACKUP_ALARM_SIREN", + "lastStatusUpdate": 0, + "lowBat": null, + "metaGroupId": null, + "on": null, + "onTime": 180.0, + "signalAcoustic": "FREQUENCY_RISING", + "signalOptical": "DISABLE_OPTICAL_SIGNAL", + "smokeDetectorAlarmType": null, + "type": "SECURITY_BACKUP_ALARM_SWITCHING", + "unreach": null + }, + "00000000-0000-0000-0000-000000000024": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000011" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000008" + } + ], + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000024", + "label": "Wohnzimmer", + "lastStatusUpdate": 1544480290322, + "lowBat": false, + "metaGroupId": "00000000-0000-0000-0000-000000000020", + "moistureDetected": null, + "motionDetected": true, + "powerMainsFailure": null, + "presenceDetected": null, + "sabotage": false, + "smokeDetectorAlarmType": null, + "type": "SECURITY", + "unreach": false, + "waterlevelDetected": null, + "windowState": "CLOSED" + }, + "00000000-0000-0000-0000-000000000046": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000023" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000046", + "label": "Kaffeemaschine (Gruppen)", + "lastStatusUpdate": 1544480026802, + "lowBat": false, + "metaGroupId": null, + "on": false, + "onLevel": 1.005, + "onTime": 5.0, + "sensorSpecificParameters": {}, + "type": "EXTENDED_LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000035": { + "active": false, + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000011" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000027" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000011" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000013" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000013" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000012" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000015" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000026" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000012" + } + ], + "configPending": false, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000035", + "ignorableDevices": [], + "label": "INTERNAL", + "lastStatusUpdate": 1544480460068, + "lowBat": false, + "metaGroupId": null, + "motionDetected": true, + "presenceDetected": null, + "sabotage": false, + "silent": false, + "type": "SECURITY_ZONE", + "unreach": false, + "windowState": null, + "zoneAssignmentIndex": "ALARM_MODE_ZONE_3" + }, + "00000000-0000-0000-0000-000000000031": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000010" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000020" + } + ], + "dimLevel": 0.0, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000031", + "label": "Schlafen", + "lastStatusUpdate": 1544479084154, + "lowBat": null, + "metaGroupId": "00000000-0000-0000-0000-000000000014", + "on": false, + "processing": null, + "shutterLevel": null, + "slatsLevel": null, + "type": "SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000021": { + "channels": [ + { + "channelIndex": 2, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 3, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 6, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 4, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 5, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000009" + }, + { + "channelIndex": 8, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 7, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 6, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 5, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 4, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 3, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000005" + }, + { + "channelIndex": 2, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000016" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000021", + "label": "Wohnzimmer", + "lastStatusUpdate": 1544479988534, + "lowBat": false, + "metaGroupId": "00000000-0000-0000-0000-000000000020", + "on": false, + "processing": null, + "shutterLevel": null, + "slatsLevel": null, + "type": "SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000044": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000019" + }, + { + "channelIndex": 2, + "deviceId": "3014F7110000000000000019" + }, + { + "channelIndex": 3, + "deviceId": "3014F7110000000000000019" + }, + { + "channelIndex": 4, + "deviceId": "3014F7110000000000000019" + }, + { + "channelIndex": 5, + "deviceId": "3014F7110000000000000019" + }, + { + "channelIndex": 6, + "deviceId": "3014F7110000000000000019" + }, + { + "channelIndex": 7, + "deviceId": "3014F7110000000000000019" + }, + { + "channelIndex": 8, + "deviceId": "3014F7110000000000000019" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000044", + "label": "Internet Radio", + "lastStatusUpdate": 1543746829532, + "lowBat": null, + "metaGroupId": "00000000-0000-0000-0000-000000000043", + "on": false, + "processing": null, + "shutterLevel": null, + "slatsLevel": null, + "type": "SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000040": { + "channels": [ + { + "channelIndex": 2, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 2, + "deviceId": "3014F7110000000000000018" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000040", + "label": "6x Wand K\u00fcche", + "lastStatusUpdate": 1544475961687, + "lowBat": false, + "metaGroupId": null, + "on": false, + "onLevel": 1.005, + "onTime": 111600.0, + "sensorSpecificParameters": {}, + "type": "EXTENDED_LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000027": { + "channels": [ + { + "channelIndex": 2, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000016" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000009" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000027", + "label": "FB Licht WZ", + "lastStatusUpdate": 1544479483638, + "lowBat": false, + "metaGroupId": null, + "on": false, + "onLevel": 1.005, + "onTime": 111600.0, + "sensorSpecificParameters": {}, + "type": "EXTENDED_LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000019": { + "activeProfile": "PROFILE_1", + "actualTemperature": null, + "boostDuration": 5, + "boostMode": false, + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000004" + } + ], + "controlMode": "AUTOMATIC", + "controllable": false, + "cooling": null, + "coolingAllowed": true, + "coolingIgnored": false, + "dutyCycle": false, + "ecoAllowed": true, + "ecoIgnored": true, + "externalClockCoolingTemperature": 23.0, + "externalClockEnabled": false, + "externalClockHeatingTemperature": 19.0, + "floorHeatingMode": "FLOOR_HEATING_STANDARD", + "homeId": "00000000-0000-0000-0000-000000000001", + "humidity": null, + "humidityLimitEnabled": true, + "humidityLimitValue": 60, + "id": "00000000-0000-0000-0000-000000000019", + "label": "Support", + "lastStatusUpdate": 1544479325761, + "lowBat": false, + "maxTemperature": 30.0, + "metaGroupId": "00000000-0000-0000-0000-000000000018", + "minTemperature": 5.0, + "partyMode": false, + "profiles": { + "PROFILE_1": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000019", + "index": "PROFILE_1", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000069", + "visible": true + }, + "PROFILE_2": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000019", + "index": "PROFILE_2", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000070", + "visible": false + }, + "PROFILE_3": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000019", + "index": "PROFILE_3", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000071", + "visible": false + }, + "PROFILE_4": { + "enabled": false, + "groupId": "00000000-0000-0000-0000-000000000019", + "index": "PROFILE_4", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000072", + "visible": true + }, + "PROFILE_5": { + "enabled": false, + "groupId": "00000000-0000-0000-0000-000000000019", + "index": "PROFILE_5", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000073", + "visible": false + }, + "PROFILE_6": { + "enabled": false, + "groupId": "00000000-0000-0000-0000-000000000019", + "index": "PROFILE_6", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000074", + "visible": false + } + }, + "sabotage": false, + "setPointTemperature": null, + "type": "HEATING", + "unreach": false, + "valvePosition": null, + "windowOpenTemperature": 12.0, + "windowState": "OPEN" + }, + "00000000-0000-0000-0000-000000000075": { + "channels": [], + "dutyCycle": null, + "heatDemand": null, + "heatDemandRuleEnabled": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000075", + "label": "HEATING_COOLING_DEMAND_PUMP", + "lastStatusUpdate": 0, + "lowBat": null, + "metaGroupId": null, + "on": null, + "pumpFollowUpTime": 2, + "pumpLeadTime": 2, + "pumpProtectionDuration": 1, + "pumpProtectionSwitchingInterval": 14, + "triggered": false, + "type": "HEATING_COOLING_DEMAND_PUMP", + "unreach": null + }, + "00000000-0000-0000-0000-000000000076": { + "channels": [], + "dutyCycle": null, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000076", + "label": "HEATING_DEHUMIDIFIER", + "lastStatusUpdate": 0, + "lowBat": null, + "metaGroupId": null, + "on": null, + "type": "HEATING_DEHUMIDIFIER", + "unreach": null + }, + "00000000-0000-0000-0000-000000000029": { + "acousticFeedbackEnabled": true, + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000009" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000029", + "label": "ALARM", + "lastStatusUpdate": 1544479389228, + "lowBat": null, + "metaGroupId": null, + "on": false, + "onTime": 20.0, + "signalAcoustic": "FREQUENCY_RISING", + "signalOptical": "DOUBLE_FLASHING_REPEATING", + "smokeDetectorAlarmType": null, + "type": "ALARM_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000013": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000001" + } + ], + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000013", + "label": "Terrasse", + "lastStatusUpdate": 1544477850708, + "lowBat": false, + "metaGroupId": "00000000-0000-0000-0000-000000000012", + "moistureDetected": null, + "motionDetected": null, + "powerMainsFailure": null, + "presenceDetected": null, + "sabotage": false, + "smokeDetectorAlarmType": null, + "type": "SECURITY", + "unreach": false, + "waterlevelDetected": null, + "windowState": "CLOSED" + }, + "00000000-0000-0000-0000-000000000077": { + "channels": [], + "dutyCycle": null, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000077", + "label": "HEATING_EXTERNAL_CLOCK", + "lastStatusUpdate": 0, + "lowBat": null, + "metaGroupId": null, + "type": "HEATING_EXTERNAL_CLOCK", + "unreach": null + }, + "00000000-0000-0000-0000-000000000050": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000026" + } + ], + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000050", + "label": "Badezimmer", + "lastStatusUpdate": 1544476978933, + "lowBat": false, + "metaGroupId": "00000000-0000-0000-0000-000000000036", + "moistureDetected": false, + "motionDetected": null, + "powerMainsFailure": null, + "presenceDetected": null, + "sabotage": null, + "smokeDetectorAlarmType": null, + "type": "SECURITY", + "unreach": false, + "waterlevelDetected": false, + "windowState": null + }, + "00000000-0000-0000-0000-000000000047": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000023" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000047", + "label": "K\u00fcche", + "lastStatusUpdate": 1544480026802, + "lowBat": false, + "metaGroupId": "00000000-0000-0000-0000-000000000016", + "on": false, + "processing": null, + "shutterLevel": null, + "slatsLevel": null, + "type": "SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000017": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000027" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000013" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000003" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000015" + } + ], + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000017", + "label": "K\u00fcche", + "lastStatusUpdate": 1544480307099, + "lowBat": false, + "metaGroupId": "00000000-0000-0000-0000-000000000016", + "moistureDetected": false, + "motionDetected": true, + "powerMainsFailure": null, + "presenceDetected": null, + "sabotage": false, + "smokeDetectorAlarmType": "IDLE_OFF", + "type": "SECURITY", + "unreach": false, + "waterlevelDetected": false, + "windowState": "CLOSED" + }, + "00000000-0000-0000-0000-000000000049": { + "actualTemperature": 4.3, + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000025" + } + ], + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "humidity": 76, + "id": "00000000-0000-0000-0000-000000000049", + "illumination": 8836.0, + "label": "Terrasse", + "lastStatusUpdate": 1544480354027, + "lowBat": false, + "metaGroupId": "00000000-0000-0000-0000-000000000012", + "raining": false, + "type": "ENVIRONMENT", + "unreach": false, + "windSpeed": 26.9 + }, + "00000000-0000-0000-0000-000000000038": { + "acousticFeedbackEnabled": false, + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000015" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000038", + "label": "SIREN", + "lastStatusUpdate": 1544428759360, + "lowBat": false, + "metaGroupId": null, + "on": false, + "onTime": 180.0, + "signalAcoustic": "FREQUENCY_RISING", + "signalOptical": "DISABLE_OPTICAL_SIGNAL", + "smokeDetectorAlarmType": "IDLE_OFF", + "type": "ALARM_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000025": { + "channels": [ + { + "channelIndex": 3, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 4, + "deviceId": "3014F7110000000000000017" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000009" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000025", + "label": "6x Wand Wohnzimmer", + "lastStatusUpdate": 1544479389228, + "lowBat": false, + "metaGroupId": null, + "on": false, + "onLevel": 1.005, + "onTime": 111600.0, + "sensorSpecificParameters": {}, + "type": "EXTENDED_LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000015": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000002" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000012" + } + ], + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000015", + "label": "Schlafen", + "lastStatusUpdate": 1544480460068, + "lowBat": false, + "metaGroupId": "00000000-0000-0000-0000-000000000014", + "moistureDetected": null, + "motionDetected": false, + "powerMainsFailure": null, + "presenceDetected": null, + "sabotage": false, + "smokeDetectorAlarmType": null, + "type": "SECURITY", + "unreach": false, + "waterlevelDetected": null, + "windowState": "CLOSED" + }, + "00000000-0000-0000-0000-000000000023": { + "activeProfile": "PROFILE_1", + "actualTemperature": 19.5, + "boostDuration": 5, + "boostMode": false, + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000021" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000007" + } + ], + "controlMode": "MANUAL", + "controllable": true, + "cooling": null, + "coolingAllowed": false, + "coolingIgnored": false, + "dutyCycle": false, + "ecoAllowed": true, + "ecoIgnored": false, + "externalClockCoolingTemperature": 23.0, + "externalClockEnabled": false, + "externalClockHeatingTemperature": 19.0, + "floorHeatingMode": "FLOOR_HEATING_STANDARD", + "homeId": "00000000-0000-0000-0000-000000000001", + "humidity": 70, + "humidityLimitEnabled": true, + "humidityLimitValue": 60, + "id": "00000000-0000-0000-0000-000000000023", + "label": "Schlafen", + "lastStatusUpdate": 1544480413257, + "lowBat": false, + "maxTemperature": 19.5, + "metaGroupId": "00000000-0000-0000-0000-000000000014", + "minTemperature": 10.0, + "partyMode": false, + "profiles": { + "PROFILE_1": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000023", + "index": "PROFILE_1", + "name": "Winter Modus", + "profileId": "00000000-0000-0000-0000-000000000078", + "visible": true + }, + "PROFILE_2": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000023", + "index": "PROFILE_2", + "name": "Sommer Modus", + "profileId": "00000000-0000-0000-0000-000000000079", + "visible": true + }, + "PROFILE_3": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000023", + "index": "PROFILE_3", + "name": "0", + "profileId": "00000000-0000-0000-0000-000000000080", + "visible": false + }, + "PROFILE_4": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000023", + "index": "PROFILE_4", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000081", + "visible": true + }, + "PROFILE_5": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000023", + "index": "PROFILE_5", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000082", + "visible": true + }, + "PROFILE_6": { + "enabled": true, + "groupId": "00000000-0000-0000-0000-000000000023", + "index": "PROFILE_6", + "name": "", + "profileId": "00000000-0000-0000-0000-000000000083", + "visible": false + } + }, + "sabotage": null, + "setPointTemperature": 18.5, + "type": "HEATING", + "unreach": true, + "valvePosition": 0.04, + "windowOpenTemperature": 18.0, + "windowState": null + }, + "00000000-0000-0000-0000-000000000042": { + "channels": [ + { + "channelIndex": 6, + "deviceId": "3014F7110000000000000018" + }, + { + "channelIndex": 7, + "deviceId": "3014F7110000000000000018" + }, + { + "channelIndex": 8, + "deviceId": "3014F7110000000000000018" + }, + { + "channelIndex": 2, + "deviceId": "3014F7110000000000000018" + }, + { + "channelIndex": 3, + "deviceId": "3014F7110000000000000018" + }, + { + "channelIndex": 4, + "deviceId": "3014F7110000000000000018" + }, + { + "channelIndex": 5, + "deviceId": "3014F7110000000000000018" + }, + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000018" + } + ], + "dimLevel": null, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000042", + "label": "ioBroker", + "lastStatusUpdate": 1543746604288, + "lowBat": null, + "metaGroupId": "00000000-0000-0000-0000-000000000041", + "on": false, + "processing": null, + "shutterLevel": null, + "slatsLevel": null, + "type": "SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000036": { + "channels": [ + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000026" + }, + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000014" + } + ], + "configPending": false, + "dutyCycle": false, + "groups": [ + "00000000-0000-0000-0000-000000000050", + "00000000-0000-0000-0000-000000000037" + ], + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000036", + "incorrectPositioned": false, + "label": "Badezimmer", + "lastStatusUpdate": 1544480470447, + "lowBat": false, + "metaGroupId": null, + "sabotage": null, + "type": "META", + "unreach": false + }, + "00000000-0000-0000-0000-000000000045": { + "channels": [ + { + "channelIndex": 1, + "deviceId": "3014F7110000000000000020" + } + ], + "dimLevel": 0.0, + "dutyCycle": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000045", + "label": "Dimmer letzter Zustand(Gruppen)", + "lastStatusUpdate": 1544479084154, + "lowBat": null, + "metaGroupId": null, + "on": false, + "onLevel": 1.005, + "onTime": 111600.0, + "sensorSpecificParameters": {}, + "type": "EXTENDED_LINKED_SWITCHING", + "unreach": false + }, + "00000000-0000-0000-0000-000000000018": { + "channels": [ + { + "channelIndex": 0, + "deviceId": "3014F7110000000000000004" + } + ], + "configPending": false, + "dutyCycle": false, + "groups": [ + "00000000-0000-0000-0000-000000000019" + ], + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000018", + "incorrectPositioned": null, + "label": "Support", + "lastStatusUpdate": 1544479325761, + "lowBat": false, + "metaGroupId": null, + "sabotage": false, + "type": "META", + "unreach": false + } + }, + "home": { + "apExchangeClientId": null, + "apExchangeState": "NONE", + "availableAPVersion": null, + "carrierSense": 0.0, + "clients": [ + "00000000-0000-0000-0000-000000000007", + "00000000-0000-0000-0000-000000000008", + "00000000-0000-0000-0000-000000000002", + "00000000-0000-0000-0000-000000000006", + "00000000-0000-0000-0000-000000000000", + "00000000-0000-0000-0000-000000000005", + "00000000-0000-0000-0000-000000000003", + "00000000-0000-0000-0000-000000000004" + ], + "connected": true, + "currentAPVersion": "1.2.14", + "deviceUpdateStrategy": "MANUALLY", + "dutyCycle": 12.0, + "functionalHomes": { + "INDOOR_CLIMATE": { + "absenceEndTime": null, + "absenceType": "NOT_ABSENT", + "active": true, + "coolingEnabled": false, + "ecoDuration": "ONE", + "ecoTemperature": 17.0, + "floorHeatingSpecificGroups": { + "HEATING_CHANGEOVER": "00000000-0000-0000-0000-000000000065", + "HEATING_COOLING_DEMAND_BOILER": "00000000-0000-0000-0000-000000000058", + "HEATING_COOLING_DEMAND_PUMP": "00000000-0000-0000-0000-000000000075", + "HEATING_DEHUMIDIFIER": "00000000-0000-0000-0000-000000000076", + "HEATING_EXTERNAL_CLOCK": "00000000-0000-0000-0000-000000000077", + "HEATING_HUMIDITY_LIMITER": "00000000-0000-0000-0000-000000000067", + "HEATING_TEMPERATURE_LIMITER": "00000000-0000-0000-0000-000000000051" + }, + "functionalGroups": [ + "00000000-0000-0000-0000-000000000023", + "00000000-0000-0000-0000-000000000019", + "00000000-0000-0000-0000-000000000037", + "00000000-0000-0000-0000-000000000022" + ], + "optimumStartStopEnabled": false, + "solution": "INDOOR_CLIMATE" + }, + "LIGHT_AND_SHADOW": { + "active": true, + "extendedLinkedShutterGroups": [], + "extendedLinkedSwitchingGroups": [ + "00000000-0000-0000-0000-000000000033", + "00000000-0000-0000-0000-000000000045", + "00000000-0000-0000-0000-000000000039", + "00000000-0000-0000-0000-000000000046", + "00000000-0000-0000-0000-000000000025", + "00000000-0000-0000-0000-000000000027", + "00000000-0000-0000-0000-000000000040", + "00000000-0000-0000-0000-000000000032", + "00000000-0000-0000-0000-000000000030", + "00000000-0000-0000-0000-000000000034" + ], + "functionalGroups": [ + "00000000-0000-0000-0000-000000000048", + "00000000-0000-0000-0000-000000000042", + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000031", + "00000000-0000-0000-0000-000000000047", + "00000000-0000-0000-0000-000000000044" + ], + "shutterProfileGroups": [], + "solution": "LIGHT_AND_SHADOW", + "switchingProfileGroups": [] + }, + "SECURITY_AND_ALARM": { + "activationInProgress": false, + "active": true, + "alarmActive": false, + "alarmEventDeviceId": null, + "alarmEventTimestamp": null, + "alarmSecurityJournalEntryType": null, + "functionalGroups": [ + "00000000-0000-0000-0000-000000000011", + "00000000-0000-0000-0000-000000000024", + "00000000-0000-0000-0000-000000000050", + "00000000-0000-0000-0000-000000000013", + "00000000-0000-0000-0000-000000000017", + "00000000-0000-0000-0000-000000000015" + ], + "intrusionAlertThroughSmokeDetectors": false, + "securitySwitchingGroups": { + "ALARM": "00000000-0000-0000-0000-000000000029", + "BACKUP_ALARM_SIREN": "00000000-0000-0000-0000-000000000068", + "COMING_HOME": "00000000-0000-0000-0000-000000000028", + "PANIC": "00000000-0000-0000-0000-000000000026", + "SIREN": "00000000-0000-0000-0000-000000000038" + }, + "securityZoneActivationMode": "ACTIVATION_WITH_DEVICE_IGNORELIST", + "securityZones": { + "EXTERNAL": "00000000-0000-0000-0000-000000000009", + "INTERNAL": "00000000-0000-0000-0000-000000000035" + }, + "solution": "SECURITY_AND_ALARM", + "zoneActivationDelay": 0.0 + }, + "WEATHER_AND_ENVIRONMENT": { + "active": true, + "functionalGroups": [ + "00000000-0000-0000-0000-000000000049" + ], + "solution": "WEATHER_AND_ENVIRONMENT" + } + }, + "id": "00000000-0000-0000-0000-000000000001", + "inboxGroup": "00000000-0000-0000-0000-000000000066", + "isLiveUpdateSupported": false, + "lastReadyForUpdateTimestamp": 1529081477843, + "liveOTAUStatus": { + "deviceId": null, + "liveOTAUState": "INACTIVE", + "progress": 0.0 + }, + "liveUpdateSupported": false, + "location": { + "city": "1010, Vienna, Austria", + "latitude": "48.208088", + "longitude": "16.358608" + }, + "metaGroups": [ + "00000000-0000-0000-0000-000000000018", + "00000000-0000-0000-0000-000000000016", + "00000000-0000-0000-0000-000000000020", + "00000000-0000-0000-0000-000000000014", + "00000000-0000-0000-0000-000000000036", + "00000000-0000-0000-0000-000000000010", + "00000000-0000-0000-0000-000000000012", + "00000000-0000-0000-0000-000000000041", + "00000000-0000-0000-0000-000000000043" + ], + "pinAssigned": true, + "powerMeterCurrency": "EUR", + "powerMeterUnitPrice": 0.29000000000000004, + "ruleGroups": [ + "00000000-0000-0000-0000-000000000058", + "00000000-0000-0000-0000-000000000075" + ], + "ruleMetaDatas": { + "00000000-0000-0000-0000-000000000084": { + "active": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000084", + "label": "TV aus", + "ruleErrorCategories": [], + "type": "SIMPLE" + }, + "00000000-0000-0000-0000-000000000085": { + "active": true, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000085", + "label": "Koffeemaschine", + "ruleErrorCategories": [], + "type": "SIMPLE" + }, + "00000000-0000-0000-0000-000000000086": { + "active": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000086", + "label": "Voll/Hullschutz AUS dann Licht AUS", + "ruleErrorCategories": [], + "type": "SIMPLE" + }, + "00000000-0000-0000-0000-000000000087": { + "active": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000087", + "label": "Voll/Hullschutz AN dann Licht AUS", + "ruleErrorCategories": [], + "type": "SIMPLE" + }, + "00000000-0000-0000-0000-000000000088": { + "active": true, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000088", + "label": "Lichtzeit SchlafZ", + "ruleErrorCategories": [], + "type": "SIMPLE" + }, + "00000000-0000-0000-0000-000000000089": { + "active": true, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000089", + "label": "Lichtzeit WohnZ.", + "ruleErrorCategories": [], + "type": "SIMPLE" + }, + "00000000-0000-0000-0000-000000000090": { + "active": true, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000090", + "label": "Heizung Winter Modus", + "ruleErrorCategories": [], + "type": "SIMPLE" + }, + "00000000-0000-0000-0000-000000000091": { + "active": true, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000091", + "label": "STROM!!! Restart", + "ruleErrorCategories": [], + "type": "SIMPLE" + }, + "00000000-0000-0000-0000-000000000092": { + "active": false, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000092", + "label": "TV an", + "ruleErrorCategories": [], + "type": "SIMPLE" + }, + "00000000-0000-0000-0000-000000000093": { + "active": true, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000093", + "label": "Heizung Sommer Betrieb", + "ruleErrorCategories": [], + "type": "SIMPLE" + }, + "00000000-0000-0000-0000-000000000094": { + "active": true, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "00000000-0000-0000-0000-000000000094", + "label": "STROM !!!", + "ruleErrorCategories": [], + "type": "SIMPLE" + } + }, + "timeZoneId": "Europe/Berlin", + "updateState": "UP_TO_DATE", + "voiceControlSettings": { + "allowedActiveSecurityZoneIds": [ + "EXTERNAL", + "INTERNAL" + ], + "language": "GERMAN", + "stateReportEnabled": { + "conrad_connect": "YES", + "hmip_alexa_skill": "UNKNOWN" + } + }, + "weather": { + "humidity": 80, + "maxTemperature": 4.0, + "minTemperature": 4.0, + "temperature": 4.0, + "weatherCondition": "CLOUDY", + "weatherDayTime": "NIGHT", + "windDirection": 260, + "windSpeed": 18.36 + } + } +} + From 031cfa2ea9b3d1c29ea4d91c1c46842791d66936 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 17:59:07 +0100 Subject: [PATCH 14/21] added FunctionalChannels Dimmer,WeatherSensor & WeatherSensorPro added WindValueType Enum --- homematicip/base/enums.py | 9 +++- homematicip/class_maps.py | 4 ++ homematicip/device.py | 8 ++-- homematicip/functionalChannels.py | 74 ++++++++++++++++++++++++++++++- tests/test_devices.py | 2 +- 5 files changed, 90 insertions(+), 7 deletions(-) diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index cc90e73d..22975539 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -266,6 +266,11 @@ class OpticalAlarmSignal(AutoNameEnum): CONFIRMATION_SIGNAL_1 = auto() CONFIRMATION_SIGNAL_2 = auto() +class WindValueType(AutoNameEnum): + CURRENT_VALUE = auto() + MIN_VALUE = auto() + MAX_VALUE = auto() + AVERAGE_VALUE = auto() class FunctionalChannelType(AutoNameEnum): FUNCTIONAL_CHANNEL = auto() @@ -275,6 +280,7 @@ class FunctionalChannelType(AutoNameEnum): DEVICE_INCORRECT_POSITIONED = auto() DEVICE_OPERATIONLOCK = auto() DEVICE_SABOTAGE = auto() + DIMMER_CHANNEL = auto() HEATING_THERMOSTAT_CHANNEL = auto() MOTION_DETECTION_CHANNEL = auto() PRESENCE_DETECTION_CHANNEL = auto() @@ -287,5 +293,6 @@ class FunctionalChannelType(AutoNameEnum): WALL_MOUNTED_THERMOSTAT_PRO_CHANNEL = auto() WALL_MOUNTED_THERMOSTAT_WITHOUT_DISPLAY_CHANNEL = auto() WATER_SENSOR_CHANNEL = auto() - + WEATHER_SENSOR_CHANNEL = auto() + WEATHER_SENSOR_PRO_CHANNEL = auto() diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index 3cf478ee..52958de4 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -111,6 +111,7 @@ FunctionalChannelType.DEVICE_SABOTAGE: DeviceSabotageChannel, FunctionalChannelType.DEVICE_OPERATIONLOCK : DeviceOperationLockChannel, FunctionalChannelType.DEVICE_INCORRECT_POSITIONED : DeviceIncorrectPositionedChannel, + FunctionalChannelType.DIMMER_CHANNEL: DimmerChannel, FunctionalChannelType.HEATING_THERMOSTAT_CHANNEL : HeatingThermostatChannel, FunctionalChannelType.MOTION_DETECTION_CHANNEL : MotionDetectionChannel, FunctionalChannelType.PRESENCE_DETECTION_CHANNEL : PresenceDetectionChannel, @@ -123,4 +124,7 @@ FunctionalChannelType.WALL_MOUNTED_THERMOSTAT_WITHOUT_DISPLAY_CHANNEL : WallMountedThermostatWithoutDisplayChannel, FunctionalChannelType.WALL_MOUNTED_THERMOSTAT_PRO_CHANNEL : WallMountedThermostatProChannel, FunctionalChannelType.WATER_SENSOR_CHANNEL : WaterSensorChannel, + FunctionalChannelType.WEATHER_SENSOR_CHANNEL : WeatherSensorChannel, + FunctionalChannelType.WEATHER_SENSOR_PRO_CHANNEL : WeatherSensorProChannel, + } \ No newline at end of file diff --git a/homematicip/device.py b/homematicip/device.py index 5f326123..b546fc45 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -606,7 +606,7 @@ def __init__(self,connection): self.todaySunshineDuration = 0 self.totalSunshineDuration = 0 self.windSpeed = 0 - self.windValueType = "AVERAGE_VALUE" + self.windValueType = WindValueType.AVERAGE_VALUE self.yesterdaySunshineDuration = 0 def from_json(self, js): @@ -623,7 +623,7 @@ def from_json(self, js): self.todaySunshineDuration = c["todaySunshineDuration"] self.totalSunshineDuration = c["totalSunshineDuration"] self.windSpeed = c["windSpeed"] - self.windValueType = c["windValueType"] + self.windValueType = WindValueType.from_str(c["windValueType"]) self.yesterdaySunshineDuration = c["yesterdaySunshineDuration"] def __str__(self): @@ -662,7 +662,7 @@ def __init__(self,connection): self.windDirection = 0 self.windDirectionVariation = 0 self.windSpeed = 0 - self.windValueType = "AVERAGE_VALUE" + self.windValueType = WindValueType.AVERAGE_VALUE self.yesterdayRainCounter = 0 self.yesterdaySunshineDuration = 0 @@ -686,7 +686,7 @@ def from_json(self, js): self.windDirection = c["windDirection"] self.windDirectionVariation = c["windDirectionVariation"] self.windSpeed = c["windSpeed"] - self.windValueType = c["windValueType"] + self.windValueType = WindValueType.from_str(c["windValueType"]) self.yesterdayRainCounter = c["yesterdayRainCounter"] self.yesterdaySunshineDuration = c["yesterdaySunshineDuration"] diff --git a/homematicip/functionalChannels.py b/homematicip/functionalChannels.py index ad4521b1..f524e4a4 100644 --- a/homematicip/functionalChannels.py +++ b/homematicip/functionalChannels.py @@ -305,4 +305,76 @@ def from_json(self, js, groups: Iterable[Group]): super().from_json(js,groups) self.shutterLevel = js["shutterLevel"] self.bottomToTopReferenceTime = js["bottomToTopReferenceTime"] - self.topToBottomReferenceTime = js["topToBottomReferenceTime"] \ No newline at end of file + self.topToBottomReferenceTime = js["topToBottomReferenceTime"] + +class DimmerChannel(FunctionalChannel): + """ this is the representive of the DIMMER_CHANNEL channel""" + def __init__(self): + super().__init__() + self.dimLevel = 0 + self.profileMode = None + self.userDesiredProfileMode = None + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.dimLevel = js["dimLevel"] + self.profileMode = js["profileMode"] + self.userDesiredProfileMode = js["userDesiredProfileMode"] + +class WeatherSensorChannel(FunctionalChannel): + """ this is the representive of the WEATHER_SENSOR_CHANNEL channel""" + def __init__(self): + super().__init__() + self.actualTemperature = 0 + self.humidity = 0 + self.illumination = 0 + self.illuminationThresholdSunshine = 0 + self.storm = False + self.sunshine = False + self.todaySunshineDuration = 0 + self.totalSunshineDuration = 0 + self.windSpeed = 0 + self.windValueType = WindValueType.AVERAGE_VALUE + self.yesterdaySunshineDuration = 0 + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.actualTemperature = c["actualTemperature"] + self.humidity = c["humidity"] + self.illumination = c["illumination"] + self.illuminationThresholdSunshine = c["illuminationThresholdSunshine"] + self.storm = c["storm"] + self.sunshine = c["sunshine"] + self.todaySunshineDuration = c["todaySunshineDuration"] + self.totalSunshineDuration = c["totalSunshineDuration"] + self.windSpeed = c["windSpeed"] + self.windValueType = WindValueType.from_str(c["windValueType"]) + self.yesterdaySunshineDuration = c["yesterdaySunshineDuration"] + +class WeatherSensorProChannel(WeatherSensorChannel): + """ this is the representive of the WEATHER_SENSOR_PRO_CHANNEL channel""" + def __init__(self): + super().__init__() + self.raining = False + self.todayRainCounter = 0 + self.totalRainCounter = 0 + self.weathervaneAlignmentNeeded = False + self.windDirection = 0 + self.windDirectionVariation = 0 + self.yesterdayRainCounter = 0 + + def from_json(self, js, groups: Iterable[Group]): + """ this function will load the functional channel object + from a json object and the given groups """ + super().from_json(js,groups) + self.raining = c["raining"] + self.todayRainCounter = c["todayRainCounter"] + self.totalRainCounter = c["totalRainCounter"] + self.weathervaneAlignmentNeeded = c["weathervaneAlignmentNeeded"] + self.windDirection = c["windDirection"] + self.windDirectionVariation = c["windDirectionVariation"] + self.yesterdayRainCounter = c["yesterdayRainCounter"] \ No newline at end of file diff --git a/tests/test_devices.py b/tests/test_devices.py index 2e50fd5c..f7d53900 100644 --- a/tests/test_devices.py +++ b/tests/test_devices.py @@ -297,7 +297,7 @@ def test_weather_sensor(fake_home : Home): assert d.todaySunshineDuration == 51 assert d.totalSunshineDuration == 54 assert d.windSpeed == 6.6 - assert d.windValueType == "MAX_VALUE" + assert d.windValueType == WindValueType.MAX_VALUE assert d.yesterdaySunshineDuration == 3 assert d.actualTemperature == 15.2 assert d.label == "Wettersensor" From 328a013b32a0e91a5240f1e47b50c2c5982d8247 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 18:01:58 +0100 Subject: [PATCH 15/21] fixed WeatherSensor test --- tests/test_devices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_devices.py b/tests/test_devices.py index f7d53900..be20acb5 100644 --- a/tests/test_devices.py +++ b/tests/test_devices.py @@ -255,7 +255,7 @@ def test_weather_sensor_pro(fake_home : Home): assert d.windDirection == 295.0 assert d.windDirectionVariation == 56.25 assert d.windSpeed == 2.6 - assert d.windValueType == "AVERAGE_VALUE" + assert d.windValueType == WindValueType.AVERAGE_VALUE assert d.yesterdayRainCounter == 0.0 assert d.yesterdaySunshineDuration == 0 assert d.actualTemperature == 15.4 From b0a0f523dd0b2a483b8210ead0a65bb9db0a8726 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 18:07:11 +0100 Subject: [PATCH 16/21] added SingleKeyChannel --- homematicip/base/enums.py | 1 + homematicip/class_maps.py | 1 + homematicip/device.py | 6 ------ homematicip/functionalChannels.py | 5 ++++- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index 22975539..2ecf38d2 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -287,6 +287,7 @@ class FunctionalChannelType(AutoNameEnum): ROTARY_HANDLE_CHANNEL = auto() SHUTTER_CHANNEL = auto() SHUTTER_CONTACT_CHANNEL = auto() + SINGLE_KEY_CHANNEL = auto() SMOKE_DETECTOR_CHANNEL = auto() SWITCH_CHANNEL = auto() SWITCH_MEASURING_CHANNEL = auto() diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index 52958de4..23f0caf9 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -118,6 +118,7 @@ FunctionalChannelType.ROTARY_HANDLE_CHANNEL : RotaryHandleChannel, FunctionalChannelType.SHUTTER_CHANNEL : ShutterChannel, FunctionalChannelType.SHUTTER_CONTACT_CHANNEL : ShutterContactChannel, + FunctionalChannelType.SINGLE_KEY_CHANNEL : SingleKeyChannel, FunctionalChannelType.SMOKE_DETECTOR_CHANNEL: SmokeDetectorChannel, FunctionalChannelType.SWITCH_CHANNEL: SwitchChannel, FunctionalChannelType.SWITCH_MEASURING_CHANNEL: SwitchMeasuringChannel, diff --git a/homematicip/device.py b/homematicip/device.py index b546fc45..db7161b2 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -440,12 +440,6 @@ class PushButton(Device): class PushButton6(PushButton): """ HMIP-WRC6 (Wall-mount Remote Control - 6-button) """ - def from_json(self, js): - super().from_json(js) - #TODO: PUSH_BUTTON_6 has 6 functional Channels of "SINGLE_KEY_CHANNEL" - #They don't provide any information except for the groups. - #Maybe the functional channels should get there own class and be added as class member? - class RemoteControl8(PushButton): """ HmIP-RC8 (Remote Control - 8 buttons) """ diff --git a/homematicip/functionalChannels.py b/homematicip/functionalChannels.py index f524e4a4..da659748 100644 --- a/homematicip/functionalChannels.py +++ b/homematicip/functionalChannels.py @@ -377,4 +377,7 @@ def from_json(self, js, groups: Iterable[Group]): self.weathervaneAlignmentNeeded = c["weathervaneAlignmentNeeded"] self.windDirection = c["windDirection"] self.windDirectionVariation = c["windDirectionVariation"] - self.yesterdayRainCounter = c["yesterdayRainCounter"] \ No newline at end of file + self.yesterdayRainCounter = c["yesterdayRainCounter"] + +class SingleKeyChannel(FunctionalChannel): + """ this is the representive of the SINGLE_KEY_CHANNEL channel""" \ No newline at end of file From f6d8ab923617d37676b6913a33cc77f742db471f Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 18:10:15 +0100 Subject: [PATCH 17/21] fixied copy & paste issue. I should hav elearned from the last time --- homematicip/functionalChannels.py | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/homematicip/functionalChannels.py b/homematicip/functionalChannels.py index da659748..565ee6e7 100644 --- a/homematicip/functionalChannels.py +++ b/homematicip/functionalChannels.py @@ -343,17 +343,17 @@ def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.actualTemperature = c["actualTemperature"] - self.humidity = c["humidity"] - self.illumination = c["illumination"] - self.illuminationThresholdSunshine = c["illuminationThresholdSunshine"] - self.storm = c["storm"] - self.sunshine = c["sunshine"] - self.todaySunshineDuration = c["todaySunshineDuration"] - self.totalSunshineDuration = c["totalSunshineDuration"] - self.windSpeed = c["windSpeed"] - self.windValueType = WindValueType.from_str(c["windValueType"]) - self.yesterdaySunshineDuration = c["yesterdaySunshineDuration"] + self.actualTemperature = js["actualTemperature"] + self.humidity = js["humidity"] + self.illumination = js["illumination"] + self.illuminationThresholdSunshine = js["illuminationThresholdSunshine"] + self.storm = js["storm"] + self.sunshine = js["sunshine"] + self.todaySunshineDuration = js["todaySunshineDuration"] + self.totalSunshineDuration = js["totalSunshineDuration"] + self.windSpeed = js["windSpeed"] + self.windValueType = WindValueType.from_str(js["windValueType"]) + self.yesterdaySunshineDuration = js["yesterdaySunshineDuration"] class WeatherSensorProChannel(WeatherSensorChannel): """ this is the representive of the WEATHER_SENSOR_PRO_CHANNEL channel""" @@ -371,13 +371,13 @@ def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.raining = c["raining"] - self.todayRainCounter = c["todayRainCounter"] - self.totalRainCounter = c["totalRainCounter"] - self.weathervaneAlignmentNeeded = c["weathervaneAlignmentNeeded"] - self.windDirection = c["windDirection"] - self.windDirectionVariation = c["windDirectionVariation"] - self.yesterdayRainCounter = c["yesterdayRainCounter"] + self.raining = js["raining"] + self.todayRainCounter = js["todayRainCounter"] + self.totalRainCounter = js["totalRainCounter"] + self.weathervaneAlignmentNeeded = js["weathervaneAlignmentNeeded"] + self.windDirection = js["windDirection"] + self.windDirectionVariation = js["windDirectionVariation"] + self.yesterdayRainCounter = js["yesterdayRainCounter"] class SingleKeyChannel(FunctionalChannel): """ this is the representive of the SINGLE_KEY_CHANNEL channel""" \ No newline at end of file From 0246afc2af7738a11d39ec89b6f100a4bf0128db Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 18:44:59 +0100 Subject: [PATCH 18/21] added HmIP-MOD-OC8 ( Open Collector Module ) --- README.rst | 1 + homematicip/aio/class_maps.py | 3 +- homematicip/aio/device.py | 3 + homematicip/base/enums.py | 559 +++++++++++++++--------------- homematicip/class_maps.py | 3 +- homematicip/device.py | 3 + homematicip/functionalChannels.py | 374 ++++++++++---------- tests/json_data/home.json | 143 ++++++++ tests/test_devices.py | 29 +- 9 files changed, 649 insertions(+), 469 deletions(-) diff --git a/README.rst b/README.rst index d381fc99..2702504e 100644 --- a/README.rst +++ b/README.rst @@ -72,6 +72,7 @@ Devices: - [X] HMIP-FDT (Dimming Actuator flush-mount) - [X] HMIP-FROLL (Shutter Actuator - flush-mount) - [X] HMIP-KRCA (Key Ring Remote Control & alarm) +- [X] HmIP-MOD-OC8 ( Open Collector Module ) - [X] HMIP-RC8 (Remote Control - 8 buttons) - [X] HMIP-PCBS-BAT (Printed Curcuit Board Switch Battery) - [X] HMIP-PDT (Pluggable Dimmer) diff --git a/homematicip/aio/class_maps.py b/homematicip/aio/class_maps.py index b3101451..a4b6da5f 100644 --- a/homematicip/aio/class_maps.py +++ b/homematicip/aio/class_maps.py @@ -37,7 +37,8 @@ DeviceType.SHUTTER_CONTACT_MAGNETIC: AsyncShutterContact, DeviceType.FULL_FLUSH_DIMMER : AsyncFullFlushDimmer, DeviceType.PUSH_BUTTON_6 : AsyncPushButton6, - DeviceType.REMOTE_CONTROL_8 : AsyncRemoteControl8 + DeviceType.REMOTE_CONTROL_8 : AsyncRemoteControl8, + DeviceType.OPEN_COLLECTOR_8_MODULE : AsyncOpenCollector8Module } TYPE_GROUP_MAP = { diff --git a/homematicip/aio/device.py b/homematicip/aio/device.py index 0c947544..359822d7 100644 --- a/homematicip/aio/device.py +++ b/homematicip/aio/device.py @@ -52,6 +52,9 @@ class AsyncPlugableSwitch(PlugableSwitch, AsyncSwitch): class AsyncSabotageDevice(SabotageDevice, AsyncDevice): pass +class AsyncOpenCollector8Module(OpenCollector8Module, AsyncSwitch): + """ Async implementation of HmIP-MOD-OC8 ( Open Collector Module ) """ + class AsyncOperationLockableDevice(OperationLockableDevice, AsyncDevice): async def set_operation_lock(self, operationLock=True): diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index 2ecf38d2..1cde5982 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -1,280 +1,281 @@ -# coding=utf-8 -from aenum import auto, Enum - -class AutoNameEnum(Enum): - """ auto() will generate the name of the attribute as value """ - def _generate_next_value_(name, start, count, last_values): - return name - def __str__(self): - return self.value - - @classmethod - def from_str(cls, text): - if text is None: - return None - return cls(text) - - -class AcousticAlarmTiming(AutoNameEnum): - PERMANENT = auto() - THREE_MINUTES = auto() - SIX_MINUTES = auto() - ONCE_PER_MINUTE = auto() - -class WaterAlarmTrigger(AutoNameEnum): - NO_ALARM = auto() - MOISTURE_DETECTION = auto() - WATER_DETECTION = auto() - WATER_MOISTURE_DETECTION = auto() - -class AcousticAlarmSignal(AutoNameEnum): - DISABLE_ACOUSTIC_SIGNAL = auto() - FREQUENCY_RISING = auto() - FREQUENCY_FALLING = auto() - FREQUENCY_RISING_AND_FALLING = auto() - FREQUENCY_ALTERNATING_LOW_HIGH = auto() - FREQUENCY_ALTERNATING_LOW_MID_HIGH = auto() - FREQUENCY_HIGHON_OFF = auto() - FREQUENCY_HIGHON_LONGOFF = auto() - FREQUENCY_LOWON_OFF_HIGHON_OFF = auto() - FREQUENCY_LOWON_LONGOFF_HIGHON_LONGOFF = auto() - -class ClimateControlDisplay(AutoNameEnum): - ACTUAL = auto() - SETPOINT = auto() - ACTUAL_HUMIDITY = auto() - -class WindowState(AutoNameEnum): - OPEN = auto() - CLOSED = auto() - TILTED = auto() - -class ValveState(AutoNameEnum): - STATE_NOT_AVAILABLE = auto() - RUN_TO_START = auto() - WAIT_FOR_ADAPTION = auto() - ADAPTION_IN_PROGRESS = auto() - ADAPTION_DONE = auto() - TOO_TIGHT = auto() - ADJUSTMENT_TOO_BIG = auto() - ADJUSTMENT_TOO_SMALL = auto() - ERROR_POSITION = auto() - -class HeatingValveType(AutoNameEnum): - NORMALLY_CLOSE = auto() - NORMALLY_OPEN = auto() - -class RGBColorState(AutoNameEnum): - BLACK = auto() - BLUE = auto() - GREEN = auto() - TURQUOISE = auto() - RED = auto() - PURPLE = auto() - YELLOW = auto() - WHITE = auto() - -class DeviceUpdateStrategy(AutoNameEnum): - MANUALLY = auto() - AUTOMATICALLY_IF_POSSIBLE = auto() - -class ApExchangeState(AutoNameEnum): - NONE = auto() - REQUESTED = auto() - IN_PROGRESS = auto() - DONE = auto() - REJECTED = auto() - -class HomeUpdateState(AutoNameEnum): - UP_TO_DATE = auto() - UPDATE_AVAILABLE = auto() - PERFORM_UPDATE_SENT = auto() - PERFORMING_UPDATE = auto() - -class WeatherCondition(AutoNameEnum): - CLEAR = auto() - LIGHT_CLOUDY = auto() - CLOUDY = auto() - CLOUDY_WITH_RAIN = auto() - CLOUDY_WITH_SNOW_RAIN = auto() - HEAVILY_CLOUDY = auto() - HEAVILY_CLOUDY_WITH_RAIN = auto() - HEAVILY_CLOUDY_WITH_STRONG_RAIN = auto() - HEAVILY_CLOUDY_WITH_SNOW = auto() - HEAVILY_CLOUDY_WITH_SNOW_RAIN = auto() - HEAVILY_CLOUDY_WITH_THUNDER = auto() - HEAVILY_CLOUDY_WITH_RAIN_AND_THUNDER = auto() - FOGGY = auto() - UNKNOWN = auto() - -class WeatherDayTime(AutoNameEnum): - DAY = auto() - TWILIGHT = auto() - NIGHT = auto() - -class AbsenceType(AutoNameEnum): - NOT_ABSENT = auto() - PERIOD = auto() - PERMANENT = auto() - VACATION = auto() - PARTY = auto() - -class EcoDuration(AutoNameEnum): - ONE = auto() - TWO = auto() - FOUR = auto() - SIX = auto() - PERMANENT = auto() - - -class SecurityZoneActivationMode(AutoNameEnum): - ACTIVATION_WITH_DEVICE_IGNORELIST = auto() - ACTIVATION_IF_ALL_IN_VALID_STATE = auto() - -class ClientType(AutoNameEnum): - APP = auto() - C2C = auto() - -class DeviceType(AutoNameEnum): - DEVICE = auto() - FULL_FLUSH_SHUTTER = auto() - PLUGABLE_SWITCH = auto() - KEY_REMOTE_CONTROL_ALARM = auto() - MOTION_DETECTOR_INDOOR = auto() - ALARM_SIREN_INDOOR = auto() - PUSH_BUTTON = auto() - TEMPERATURE_HUMIDITY_SENSOR_DISPLAY = auto() - PLUGABLE_SWITCH_MEASURING = auto() - FLOOR_TERMINAL_BLOCK_6 = auto() - SMOKE_DETECTOR = auto() - WALL_MOUNTED_THERMOSTAT_PRO = auto() - SHUTTER_CONTACT = auto() - HEATING_THERMOSTAT = auto() - SHUTTER_CONTACT_INVISIBLE = auto() - BRAND_WALL_MOUNTED_THERMOSTAT = auto() - TEMPERATURE_HUMIDITY_SENSOR = auto() - BRAND_SHUTTER = auto() - PRECENCE_DETECTOR_INDOOR = auto() - PLUGGABLE_DIMMER = auto() - BRAND_DIMMER = auto() - BRAND_SWITCH_MEASURING = auto() - PRINTED_CIRCUIT_BOARD_SWITCH_BATTERY = auto() - ROOM_CONTROL_DEVICE = auto() - TEMPERATURE_HUMIDITY_SENSOR_OUTDOOR = auto() - WEATHER_SENSOR = auto() - WEATHER_SENSOR_PRO = auto() - ROTARY_HANDLE_SENSOR = auto() - FULL_FLUSH_SWITCH_MEASURING = auto() - MOTION_DETECTOR_PUSH_BUTTON = auto() - WATER_SENSOR = auto() - SHUTTER_CONTACT_MAGNETIC = auto() - FULL_FLUSH_DIMMER = auto() - PUSH_BUTTON_6 = auto() - REMOTE_CONTROL_8 = auto() - -class GroupType(AutoNameEnum): - GROUP = auto() - EXTENDED_LINKED_SHUTTER = auto() - SHUTTER_WIND_PROTECTION_RULE = auto() - LOCK_OUT_PROTECTION_RULE = auto() - SMOKE_ALARM_DETECTION_RULE = auto() - OVER_HEAT_PROTECTION_RULE = auto() - SWITCHING_PROFILE = auto() - HEATING_COOLING_DEMAND_PUMP = auto() - HEATING_COOLING_DEMAND_BOILER = auto() - HEATING_DEHUMIDIFIER = auto() - HEATING_EXTERNAL_CLOCK = auto() - HEATING_COOLING_DEMAND = auto() - HEATING = auto() - SECURITY_ZONE = auto() - INBOX = auto() - HEATING_CHANGEOVER = auto() - HEATING_TEMPERATURE_LIMITER = auto() - HEATING_HUMIDITY_LIMITER = auto() - ALARM_SWITCHING = auto() - LINKED_SWITCHING = auto() - EXTENDED_LINKED_SWITCHING = auto() - SWITCHING = auto() - SECURITY = auto() - ENVIRONMENT = auto() - SECURITY_BACKUP_ALARM_SWITCHING = auto() - -class SecurityEventType(AutoNameEnum): - SENSOR_EVENT = auto() - ACCESS_POINT_DISCONNECTED = auto() - ACCESS_POINT_CONNECTED = auto() - ACTIVATION_CHANGED = auto() - SILENCE_CHANGED = auto() - SABOTAGE = auto() - MOISTURE_DETECTION_EVENT = auto() - SMOKE_ALARM = auto() - EXTERNAL_TRIGGERED = auto() - OFFLINE_ALARM = auto() - WATER_DETECTION_EVENT = auto() - MAINS_FAILURE_EVENT = auto() - OFFLINE_WATER_DETECTION_EVENT = auto() - -class AutomationRuleType(AutoNameEnum): - SIMPLE = auto() - -class FunctionalHomeType(AutoNameEnum): - INDOOR_CLIMATE = auto() - LIGHT_AND_SHADOW = auto() - SECURITY_AND_ALARM = auto() - WEATHER_AND_ENVIRONMENT = auto() - -class EventType(AutoNameEnum): - SECURITY_JOURNAL_CHANGED = auto() - GROUP_ADDED = auto() - GROUP_REMOVED = auto() - DEVICE_REMOVED = auto() - DEVICE_CHANGED = auto() - DEVICE_ADDED = auto() - CLIENT_REMOVED = auto() - CLIENT_CHANGED = auto() - CLIENT_ADDED = auto() - HOME_CHANGED = auto() - GROUP_CHANGED = auto() - - -class MotionDetectionSendInterval(AutoNameEnum): - SECONDS_30 = auto() - SECONDS_60 = auto() - SECONDS_120 = auto() - SECONDS_240 = auto() - SECONDS_480 = auto() - -class SmokeDetectorAlarmType(AutoNameEnum): - IDLE_OFF = auto() - PRIMARY_ALARM = auto() - INTRUSION_ALARM = auto() - SECONDARY_ALARM = auto() - -class LiveUpdateState(AutoNameEnum): - UP_TO_DATE = auto() - UPDATE_AVAILABLE = auto() - UPDATE_INCOMPLETE = auto() - LIVE_UPDATE_NOT_SUPPORTED = auto() - -class OpticalAlarmSignal(AutoNameEnum): - DISABLE_OPTICAL_SIGNAL = auto() - BLINKING_ALTERNATELY_REPEATING = auto() - BLINKING_BOTH_REPEATING = auto() - DOUBLE_FLASHING_REPEATING = auto() - FLASHING_BOTH_REPEATING = auto() - CONFIRMATION_SIGNAL_0 = auto() - CONFIRMATION_SIGNAL_1 = auto() - CONFIRMATION_SIGNAL_2 = auto() - -class WindValueType(AutoNameEnum): - CURRENT_VALUE = auto() - MIN_VALUE = auto() - MAX_VALUE = auto() - AVERAGE_VALUE = auto() - -class FunctionalChannelType(AutoNameEnum): - FUNCTIONAL_CHANNEL = auto() - CLIMATE_SENSOR_CHANNEL = auto() +# coding=utf-8 +from aenum import auto, Enum + +class AutoNameEnum(Enum): + """ auto() will generate the name of the attribute as value """ + def _generate_next_value_(name, start, count, last_values): + return name + def __str__(self): + return self.value + + @classmethod + def from_str(cls, text): + if text is None: + return None + return cls(text) + + +class AcousticAlarmTiming(AutoNameEnum): + PERMANENT = auto() + THREE_MINUTES = auto() + SIX_MINUTES = auto() + ONCE_PER_MINUTE = auto() + +class WaterAlarmTrigger(AutoNameEnum): + NO_ALARM = auto() + MOISTURE_DETECTION = auto() + WATER_DETECTION = auto() + WATER_MOISTURE_DETECTION = auto() + +class AcousticAlarmSignal(AutoNameEnum): + DISABLE_ACOUSTIC_SIGNAL = auto() + FREQUENCY_RISING = auto() + FREQUENCY_FALLING = auto() + FREQUENCY_RISING_AND_FALLING = auto() + FREQUENCY_ALTERNATING_LOW_HIGH = auto() + FREQUENCY_ALTERNATING_LOW_MID_HIGH = auto() + FREQUENCY_HIGHON_OFF = auto() + FREQUENCY_HIGHON_LONGOFF = auto() + FREQUENCY_LOWON_OFF_HIGHON_OFF = auto() + FREQUENCY_LOWON_LONGOFF_HIGHON_LONGOFF = auto() + +class ClimateControlDisplay(AutoNameEnum): + ACTUAL = auto() + SETPOINT = auto() + ACTUAL_HUMIDITY = auto() + +class WindowState(AutoNameEnum): + OPEN = auto() + CLOSED = auto() + TILTED = auto() + +class ValveState(AutoNameEnum): + STATE_NOT_AVAILABLE = auto() + RUN_TO_START = auto() + WAIT_FOR_ADAPTION = auto() + ADAPTION_IN_PROGRESS = auto() + ADAPTION_DONE = auto() + TOO_TIGHT = auto() + ADJUSTMENT_TOO_BIG = auto() + ADJUSTMENT_TOO_SMALL = auto() + ERROR_POSITION = auto() + +class HeatingValveType(AutoNameEnum): + NORMALLY_CLOSE = auto() + NORMALLY_OPEN = auto() + +class RGBColorState(AutoNameEnum): + BLACK = auto() + BLUE = auto() + GREEN = auto() + TURQUOISE = auto() + RED = auto() + PURPLE = auto() + YELLOW = auto() + WHITE = auto() + +class DeviceUpdateStrategy(AutoNameEnum): + MANUALLY = auto() + AUTOMATICALLY_IF_POSSIBLE = auto() + +class ApExchangeState(AutoNameEnum): + NONE = auto() + REQUESTED = auto() + IN_PROGRESS = auto() + DONE = auto() + REJECTED = auto() + +class HomeUpdateState(AutoNameEnum): + UP_TO_DATE = auto() + UPDATE_AVAILABLE = auto() + PERFORM_UPDATE_SENT = auto() + PERFORMING_UPDATE = auto() + +class WeatherCondition(AutoNameEnum): + CLEAR = auto() + LIGHT_CLOUDY = auto() + CLOUDY = auto() + CLOUDY_WITH_RAIN = auto() + CLOUDY_WITH_SNOW_RAIN = auto() + HEAVILY_CLOUDY = auto() + HEAVILY_CLOUDY_WITH_RAIN = auto() + HEAVILY_CLOUDY_WITH_STRONG_RAIN = auto() + HEAVILY_CLOUDY_WITH_SNOW = auto() + HEAVILY_CLOUDY_WITH_SNOW_RAIN = auto() + HEAVILY_CLOUDY_WITH_THUNDER = auto() + HEAVILY_CLOUDY_WITH_RAIN_AND_THUNDER = auto() + FOGGY = auto() + UNKNOWN = auto() + +class WeatherDayTime(AutoNameEnum): + DAY = auto() + TWILIGHT = auto() + NIGHT = auto() + +class AbsenceType(AutoNameEnum): + NOT_ABSENT = auto() + PERIOD = auto() + PERMANENT = auto() + VACATION = auto() + PARTY = auto() + +class EcoDuration(AutoNameEnum): + ONE = auto() + TWO = auto() + FOUR = auto() + SIX = auto() + PERMANENT = auto() + + +class SecurityZoneActivationMode(AutoNameEnum): + ACTIVATION_WITH_DEVICE_IGNORELIST = auto() + ACTIVATION_IF_ALL_IN_VALID_STATE = auto() + +class ClientType(AutoNameEnum): + APP = auto() + C2C = auto() + +class DeviceType(AutoNameEnum): + DEVICE = auto() + FULL_FLUSH_SHUTTER = auto() + PLUGABLE_SWITCH = auto() + KEY_REMOTE_CONTROL_ALARM = auto() + MOTION_DETECTOR_INDOOR = auto() + ALARM_SIREN_INDOOR = auto() + PUSH_BUTTON = auto() + TEMPERATURE_HUMIDITY_SENSOR_DISPLAY = auto() + PLUGABLE_SWITCH_MEASURING = auto() + FLOOR_TERMINAL_BLOCK_6 = auto() + SMOKE_DETECTOR = auto() + WALL_MOUNTED_THERMOSTAT_PRO = auto() + SHUTTER_CONTACT = auto() + HEATING_THERMOSTAT = auto() + SHUTTER_CONTACT_INVISIBLE = auto() + BRAND_WALL_MOUNTED_THERMOSTAT = auto() + TEMPERATURE_HUMIDITY_SENSOR = auto() + BRAND_SHUTTER = auto() + PRECENCE_DETECTOR_INDOOR = auto() + PLUGGABLE_DIMMER = auto() + BRAND_DIMMER = auto() + BRAND_SWITCH_MEASURING = auto() + PRINTED_CIRCUIT_BOARD_SWITCH_BATTERY = auto() + ROOM_CONTROL_DEVICE = auto() + TEMPERATURE_HUMIDITY_SENSOR_OUTDOOR = auto() + WEATHER_SENSOR = auto() + WEATHER_SENSOR_PRO = auto() + ROTARY_HANDLE_SENSOR = auto() + FULL_FLUSH_SWITCH_MEASURING = auto() + MOTION_DETECTOR_PUSH_BUTTON = auto() + WATER_SENSOR = auto() + SHUTTER_CONTACT_MAGNETIC = auto() + FULL_FLUSH_DIMMER = auto() + PUSH_BUTTON_6 = auto() + REMOTE_CONTROL_8 = auto() + OPEN_COLLECTOR_8_MODULE = auto() + +class GroupType(AutoNameEnum): + GROUP = auto() + EXTENDED_LINKED_SHUTTER = auto() + SHUTTER_WIND_PROTECTION_RULE = auto() + LOCK_OUT_PROTECTION_RULE = auto() + SMOKE_ALARM_DETECTION_RULE = auto() + OVER_HEAT_PROTECTION_RULE = auto() + SWITCHING_PROFILE = auto() + HEATING_COOLING_DEMAND_PUMP = auto() + HEATING_COOLING_DEMAND_BOILER = auto() + HEATING_DEHUMIDIFIER = auto() + HEATING_EXTERNAL_CLOCK = auto() + HEATING_COOLING_DEMAND = auto() + HEATING = auto() + SECURITY_ZONE = auto() + INBOX = auto() + HEATING_CHANGEOVER = auto() + HEATING_TEMPERATURE_LIMITER = auto() + HEATING_HUMIDITY_LIMITER = auto() + ALARM_SWITCHING = auto() + LINKED_SWITCHING = auto() + EXTENDED_LINKED_SWITCHING = auto() + SWITCHING = auto() + SECURITY = auto() + ENVIRONMENT = auto() + SECURITY_BACKUP_ALARM_SWITCHING = auto() + +class SecurityEventType(AutoNameEnum): + SENSOR_EVENT = auto() + ACCESS_POINT_DISCONNECTED = auto() + ACCESS_POINT_CONNECTED = auto() + ACTIVATION_CHANGED = auto() + SILENCE_CHANGED = auto() + SABOTAGE = auto() + MOISTURE_DETECTION_EVENT = auto() + SMOKE_ALARM = auto() + EXTERNAL_TRIGGERED = auto() + OFFLINE_ALARM = auto() + WATER_DETECTION_EVENT = auto() + MAINS_FAILURE_EVENT = auto() + OFFLINE_WATER_DETECTION_EVENT = auto() + +class AutomationRuleType(AutoNameEnum): + SIMPLE = auto() + +class FunctionalHomeType(AutoNameEnum): + INDOOR_CLIMATE = auto() + LIGHT_AND_SHADOW = auto() + SECURITY_AND_ALARM = auto() + WEATHER_AND_ENVIRONMENT = auto() + +class EventType(AutoNameEnum): + SECURITY_JOURNAL_CHANGED = auto() + GROUP_ADDED = auto() + GROUP_REMOVED = auto() + DEVICE_REMOVED = auto() + DEVICE_CHANGED = auto() + DEVICE_ADDED = auto() + CLIENT_REMOVED = auto() + CLIENT_CHANGED = auto() + CLIENT_ADDED = auto() + HOME_CHANGED = auto() + GROUP_CHANGED = auto() + + +class MotionDetectionSendInterval(AutoNameEnum): + SECONDS_30 = auto() + SECONDS_60 = auto() + SECONDS_120 = auto() + SECONDS_240 = auto() + SECONDS_480 = auto() + +class SmokeDetectorAlarmType(AutoNameEnum): + IDLE_OFF = auto() + PRIMARY_ALARM = auto() + INTRUSION_ALARM = auto() + SECONDARY_ALARM = auto() + +class LiveUpdateState(AutoNameEnum): + UP_TO_DATE = auto() + UPDATE_AVAILABLE = auto() + UPDATE_INCOMPLETE = auto() + LIVE_UPDATE_NOT_SUPPORTED = auto() + +class OpticalAlarmSignal(AutoNameEnum): + DISABLE_OPTICAL_SIGNAL = auto() + BLINKING_ALTERNATELY_REPEATING = auto() + BLINKING_BOTH_REPEATING = auto() + DOUBLE_FLASHING_REPEATING = auto() + FLASHING_BOTH_REPEATING = auto() + CONFIRMATION_SIGNAL_0 = auto() + CONFIRMATION_SIGNAL_1 = auto() + CONFIRMATION_SIGNAL_2 = auto() + +class WindValueType(AutoNameEnum): + CURRENT_VALUE = auto() + MIN_VALUE = auto() + MAX_VALUE = auto() + AVERAGE_VALUE = auto() + +class FunctionalChannelType(AutoNameEnum): + FUNCTIONAL_CHANNEL = auto() + CLIMATE_SENSOR_CHANNEL = auto() DEVICE_BASE = auto() DEVICE_GLOBAL_PUMP_CONTROL = auto() DEVICE_INCORRECT_POSITIONED = auto() @@ -295,5 +296,5 @@ class FunctionalChannelType(AutoNameEnum): WALL_MOUNTED_THERMOSTAT_WITHOUT_DISPLAY_CHANNEL = auto() WATER_SENSOR_CHANNEL = auto() WEATHER_SENSOR_CHANNEL = auto() - WEATHER_SENSOR_PRO_CHANNEL = auto() - + WEATHER_SENSOR_PRO_CHANNEL = auto() + diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index 23f0caf9..c2ddb747 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -45,7 +45,8 @@ DeviceType.SHUTTER_CONTACT_MAGNETIC: ShutterContact, DeviceType.FULL_FLUSH_DIMMER : FullFlushDimmer, DeviceType.PUSH_BUTTON_6: PushButton6, - DeviceType.REMOTE_CONTROL_8 : RemoteControl8 + DeviceType.REMOTE_CONTROL_8 : RemoteControl8, + DeviceType.OPEN_COLLECTOR_8_MODULE : OpenCollector8Module, } TYPE_GROUP_MAP = { diff --git a/homematicip/device.py b/homematicip/device.py index db7161b2..0f91b320 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -398,6 +398,9 @@ class PlugableSwitch(Switch): class PrintedCircuitBoardSwitchBattery(Switch): """ HmIP-PCBS-BAT (Printed Curcuit Board Switch Battery) """ +class OpenCollector8Module(Switch): + """ HmIP-MOD-OC8 ( Open Collector Module ) """ + class SwitchMeasuring(Switch): """ Generic class for Switch and Meter """ diff --git a/homematicip/functionalChannels.py b/homematicip/functionalChannels.py index 565ee6e7..110ced6c 100644 --- a/homematicip/functionalChannels.py +++ b/homematicip/functionalChannels.py @@ -1,4 +1,4 @@ -from homematicip.group import Group +from homematicip.group import Group from homematicip.base.enums import * from typing import Iterable @@ -32,352 +32,352 @@ class DeviceBaseChannel(FunctionalChannel): """ this is the representive of the DEVICE_BASE channel""" def __init__(self): super().__init__() - self.unreach = None - self.lowBat = None - self.routerModuleSupported = False - self.routerModuleEnabled = False - self.rssiDeviceValue = 0 - self.rssiPeerValue = 0 - self.dutyCycle = False + self.unreach = None + self.lowBat = None + self.routerModuleSupported = False + self.routerModuleEnabled = False + self.rssiDeviceValue = 0 + self.rssiPeerValue = 0 + self.dutyCycle = False self.configPending = False def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.unreach = js["unreach"] - self.lowBat = js["lowBat"] - self.routerModuleSupported = js["routerModuleSupported"] - self.routerModuleEnabled = js["routerModuleEnabled"] - self.rssiDeviceValue = js["rssiDeviceValue"] - self.rssiPeerValue = js["rssiPeerValue"] - self.dutyCycle = js["dutyCycle"] - self.configPending = js["configPending"] - + self.unreach = js["unreach"] + self.lowBat = js["lowBat"] + self.routerModuleSupported = js["routerModuleSupported"] + self.routerModuleEnabled = js["routerModuleEnabled"] + self.rssiDeviceValue = js["rssiDeviceValue"] + self.rssiPeerValue = js["rssiPeerValue"] + self.dutyCycle = js["dutyCycle"] + self.configPending = js["configPending"] + class DeviceSabotageChannel(DeviceBaseChannel): """ this is the representive of the DEVICE_SABOTAGE channel""" def __init__(self): - super().__init__() + super().__init__() self.sabotage = False def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.sabotage = js["sabotage"] - + super().from_json(js,groups) + self.sabotage = js["sabotage"] + class DeviceOperationLockChannel(DeviceBaseChannel): """ this is the representive of the DEVICE_OPERATIONLOCK channel""" def __init__(self): - super().__init__() + super().__init__() self.operationLockActive = False def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.operationLockActive = js["operationLockActive"] - + super().from_json(js,groups) + self.operationLockActive = js["operationLockActive"] + class DeviceIncorrectPositionedChannel(DeviceBaseChannel): """ this is the representive of the DEVICE_INCORRECT_POSITIONED channel""" def __init__(self): - super().__init__() + super().__init__() self.incorrectPositioned = False def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.incorrectPositioned = js["incorrectPositioned"] - + super().from_json(js,groups) + self.incorrectPositioned = js["incorrectPositioned"] + class WaterSensorChannel(FunctionalChannel): """ this is the representive of the WATER_SENSOR_CHANNEL channel""" def __init__(self): - super().__init__() - self.acousticAlarmSignal = AcousticAlarmSignal.DISABLE_ACOUSTIC_SIGNAL - self.acousticAlarmTiming = AcousticAlarmTiming.PERMANENT - self.acousticWaterAlarmTrigger = WaterAlarmTrigger.NO_ALARM - self.inAppWaterAlarmTrigger = WaterAlarmTrigger.NO_ALARM - self.moistureDetected = False - self.sirenWateralarmTrigger = WaterAlarmTrigger.NO_ALARM + super().__init__() + self.acousticAlarmSignal = AcousticAlarmSignal.DISABLE_ACOUSTIC_SIGNAL + self.acousticAlarmTiming = AcousticAlarmTiming.PERMANENT + self.acousticWaterAlarmTrigger = WaterAlarmTrigger.NO_ALARM + self.inAppWaterAlarmTrigger = WaterAlarmTrigger.NO_ALARM + self.moistureDetected = False + self.sirenWateralarmTrigger = WaterAlarmTrigger.NO_ALARM self.waterlevelDetected = False def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.acousticAlarmSignal = AcousticAlarmSignal.from_str(js["acousticAlarmSignal"]) - self.acousticAlarmTiming = AcousticAlarmTiming.from_str(js["acousticAlarmTiming"]) - self.acousticWaterAlarmTrigger = WaterAlarmTrigger.from_str(js["acousticWaterAlarmTrigger"]) - self.inAppWaterAlarmTrigger = WaterAlarmTrigger.from_str(js["inAppWaterAlarmTrigger"]) - self.moistureDetected = js["moistureDetected"] - self.sirenWaterAlarmTrigger = WaterAlarmTrigger.from_str(js["sirenWaterAlarmTrigger"]) - self.waterlevelDetected = js["waterlevelDetected"] - - + super().from_json(js,groups) + self.acousticAlarmSignal = AcousticAlarmSignal.from_str(js["acousticAlarmSignal"]) + self.acousticAlarmTiming = AcousticAlarmTiming.from_str(js["acousticAlarmTiming"]) + self.acousticWaterAlarmTrigger = WaterAlarmTrigger.from_str(js["acousticWaterAlarmTrigger"]) + self.inAppWaterAlarmTrigger = WaterAlarmTrigger.from_str(js["inAppWaterAlarmTrigger"]) + self.moistureDetected = js["moistureDetected"] + self.sirenWaterAlarmTrigger = WaterAlarmTrigger.from_str(js["sirenWaterAlarmTrigger"]) + self.waterlevelDetected = js["waterlevelDetected"] + + class HeatingThermostatChannel(FunctionalChannel): """ this is the representive of the HEATING_THERMOSTAT_CHANNEL channel""" def __init__(self): - super().__init__() - self.temperatureOffset = 0 - self.valvePosition = 0.0 - self.valveState = ValveState.ERROR_POSITION - self.setPointTemperature = 0.0 + super().__init__() + self.temperatureOffset = 0 + self.valvePosition = 0.0 + self.valveState = ValveState.ERROR_POSITION + self.setPointTemperature = 0.0 self.automaticValveAdaptionNeeded = False def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.temperatureOffset = js["temperatureOffset"] - self.valvePosition = js["valvePosition"] - self.valveState = ValveState.from_str(js["valveState"]) - self.setPointTemperature = js["setPointTemperature"] - + super().from_json(js,groups) + self.temperatureOffset = js["temperatureOffset"] + self.valvePosition = js["valvePosition"] + self.valveState = ValveState.from_str(js["valveState"]) + self.setPointTemperature = js["setPointTemperature"] + class ShutterContactChannel(FunctionalChannel): """ this is the representive of the SHUTTER_CONTACT_CHANNEL channel""" def __init__(self): - super().__init__() - self.windowState = WindowState.CLOSED + super().__init__() + self.windowState = WindowState.CLOSED self.eventDelay = None def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.windowState = WindowState.from_str(js["windowState"]) - self.eventDelay = js["eventDelay"] - + super().from_json(js,groups) + self.windowState = WindowState.from_str(js["windowState"]) + self.eventDelay = js["eventDelay"] + class RotaryHandleChannel(ShutterContactChannel): """ this is the representive of the ROTARY_HANDLE_CHANNEL channel""" class ClimateSensorChannel(FunctionalChannel): """ this is the representive of the CLIMATE_SENSOR_CHANNEL channel""" def __init__(self): - super().__init__() - self.actualTemperature = 0 + super().__init__() + self.actualTemperature = 0 self.humidity = 0 def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.actualTemperature = js["actualTemperature"] - self.humidity = js["humidity"] - + super().from_json(js,groups) + self.actualTemperature = js["actualTemperature"] + self.humidity = js["humidity"] + class WallMountedThermostatWithoutDisplayChannel(ClimateSensorChannel): """ this is the representive of the WALL_MOUNTED_THERMOSTAT_WITHOUT_DISPLAY_CHANNEL channel""" def __init__(self): - super().__init__() + super().__init__() self.temperatureOffset = 0 def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.temperatureOffset = js["temperatureOffset"] - + super().from_json(js,groups) + self.temperatureOffset = js["temperatureOffset"] + class WallMountedThermostatProChannel(WallMountedThermostatWithoutDisplayChannel): """ this is the representive of the WALL_MOUNTED_THERMOSTAT_PRO_CHANNEL channel""" def __init__(self): - super().__init__() - self.display = ClimateControlDisplay.ACTUAL + super().__init__() + self.display = ClimateControlDisplay.ACTUAL self.setPointTemperature = 0 def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.setPointTemperature = js["setPointTemperature"] - self.display = ClimateControlDisplay.from_str(js["display"]) - + super().from_json(js,groups) + self.setPointTemperature = js["setPointTemperature"] + self.display = ClimateControlDisplay.from_str(js["display"]) + class SmokeDetectorChannel(FunctionalChannel): """ this is the representive of the SMOKE_DETECTOR_CHANNEL channel""" def __init__(self): - super().__init__() + super().__init__() self.smokeDetectorAlarmType = SmokeDetectorAlarmType.IDLE_OFF def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.smokeDetectorAlarmType = SmokeDetectorAlarmType.from_str(js["smokeDetectorAlarmType"]) - - - + super().from_json(js,groups) + self.smokeDetectorAlarmType = SmokeDetectorAlarmType.from_str(js["smokeDetectorAlarmType"]) + + + class SwitchChannel(FunctionalChannel): """ this is the representive of the SWITCH_CHANNEL channel""" def __init__(self): - super().__init__() - self.on = False - self.profileMode = None + super().__init__() + self.on = False + self.profileMode = None self.userDesiredProfileMode = None def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.on = js["on"] - self.profileMode = js["profileMode"] - self.userDesiredProfileMode = js["userDesiredProfileMode"] - - - + super().from_json(js,groups) + self.on = js["on"] + self.profileMode = js["profileMode"] + self.userDesiredProfileMode = js["userDesiredProfileMode"] + + + class SwitchMeasuringChannel(SwitchChannel): """ this is the representive of the SWITCH_MEASURING_CHANNEL channel""" def __init__(self): - super().__init__() - self.energyCounter = 0 + super().__init__() + self.energyCounter = 0 self.currentPowerConsumption = 0 def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.energyCounter = js["energyCounter"] - self.currentPowerConsumption = js["currentPowerConsumption"] - + super().from_json(js,groups) + self.energyCounter = js["energyCounter"] + self.currentPowerConsumption = js["currentPowerConsumption"] + class DeviceGlobalPumpControlChannel(FunctionalChannel): """ this is the representive of the DEVICE_GLOBAL_PUMP_CONTROL channel""" def __init__(self): - super().__init__() - self.globalPumpControl = None + super().__init__() + self.globalPumpControl = None self.heatingValveType = HeatingValveType.NORMALLY_CLOSE def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.globalPumpControl = js["globalPumpControl"] - self.heatingValveType = HeatingValveType.from_str(js["heatingValveType"]) - - + super().from_json(js,groups) + self.globalPumpControl = js["globalPumpControl"] + self.heatingValveType = HeatingValveType.from_str(js["heatingValveType"]) + + class MotionDetectionChannel(FunctionalChannel): """ this is the representive of the MOTION_DETECTION_CHANNEL channel""" def __init__(self): - super().__init__() - self.currentIllumination = None - self.motionDetected = None - self.illumination = None - self.motionBufferActive = False - self.motionDetected = False - self.motionDetectionSendInterval = MotionDetectionSendInterval.SECONDS_30 + super().__init__() + self.currentIllumination = None + self.motionDetected = None + self.illumination = None + self.motionBufferActive = False + self.motionDetected = False + self.motionDetectionSendInterval = MotionDetectionSendInterval.SECONDS_30 self.numberOfBrightnessMeasurements = 0 def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.motionDetected = js["motionDetected"] - self.illumination = js["illumination"] - self.motionBufferActive = js["motionBufferActive"] - self.motionDetected = js["motionDetected"] - self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(js["motionDetectionSendInterval"]) - self.numberOfBrightnessMeasurements = js["numberOfBrightnessMeasurements"] - self.currentIllumination = js["currentIllumination"] - - + super().from_json(js,groups) + self.motionDetected = js["motionDetected"] + self.illumination = js["illumination"] + self.motionBufferActive = js["motionBufferActive"] + self.motionDetected = js["motionDetected"] + self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(js["motionDetectionSendInterval"]) + self.numberOfBrightnessMeasurements = js["numberOfBrightnessMeasurements"] + self.currentIllumination = js["currentIllumination"] + + class PresenceDetectionChannel(FunctionalChannel): """ this is the representive of the PRESENCE_DETECTION_CHANNEL channel""" def __init__(self): - super().__init__() - self.presenceDetected = False + super().__init__() + self.presenceDetected = False self.illumination = 0 def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.presenceDetected = js["presenceDetected"] - self.illumination = js["illumination"] - + super().from_json(js,groups) + self.presenceDetected = js["presenceDetected"] + self.illumination = js["illumination"] + class ShutterChannel(FunctionalChannel): """ this is the representive of the SHUTTER_CHANNEL channel""" def __init__(self): - super().__init__() - self.shutterLevel = None - self.bottomToTopReferenceTime = None + super().__init__() + self.shutterLevel = None + self.bottomToTopReferenceTime = None self.topToBottomReferenceTime = None def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.shutterLevel = js["shutterLevel"] - self.bottomToTopReferenceTime = js["bottomToTopReferenceTime"] - self.topToBottomReferenceTime = js["topToBottomReferenceTime"] - + super().from_json(js,groups) + self.shutterLevel = js["shutterLevel"] + self.bottomToTopReferenceTime = js["bottomToTopReferenceTime"] + self.topToBottomReferenceTime = js["topToBottomReferenceTime"] + class DimmerChannel(FunctionalChannel): """ this is the representive of the DIMMER_CHANNEL channel""" def __init__(self): - super().__init__() - self.dimLevel = 0 - self.profileMode = None + super().__init__() + self.dimLevel = 0 + self.profileMode = None self.userDesiredProfileMode = None def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.dimLevel = js["dimLevel"] - self.profileMode = js["profileMode"] - self.userDesiredProfileMode = js["userDesiredProfileMode"] - + super().from_json(js,groups) + self.dimLevel = js["dimLevel"] + self.profileMode = js["profileMode"] + self.userDesiredProfileMode = js["userDesiredProfileMode"] + class WeatherSensorChannel(FunctionalChannel): """ this is the representive of the WEATHER_SENSOR_CHANNEL channel""" def __init__(self): - super().__init__() - self.actualTemperature = 0 - self.humidity = 0 - self.illumination = 0 - self.illuminationThresholdSunshine = 0 - self.storm = False - self.sunshine = False - self.todaySunshineDuration = 0 - self.totalSunshineDuration = 0 - self.windSpeed = 0 - self.windValueType = WindValueType.AVERAGE_VALUE + super().__init__() + self.actualTemperature = 0 + self.humidity = 0 + self.illumination = 0 + self.illuminationThresholdSunshine = 0 + self.storm = False + self.sunshine = False + self.todaySunshineDuration = 0 + self.totalSunshineDuration = 0 + self.windSpeed = 0 + self.windValueType = WindValueType.AVERAGE_VALUE self.yesterdaySunshineDuration = 0 def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.actualTemperature = js["actualTemperature"] - self.humidity = js["humidity"] - self.illumination = js["illumination"] - self.illuminationThresholdSunshine = js["illuminationThresholdSunshine"] - self.storm = js["storm"] - self.sunshine = js["sunshine"] - self.todaySunshineDuration = js["todaySunshineDuration"] - self.totalSunshineDuration = js["totalSunshineDuration"] - self.windSpeed = js["windSpeed"] - self.windValueType = WindValueType.from_str(js["windValueType"]) - self.yesterdaySunshineDuration = js["yesterdaySunshineDuration"] - + super().from_json(js,groups) + self.actualTemperature = js["actualTemperature"] + self.humidity = js["humidity"] + self.illumination = js["illumination"] + self.illuminationThresholdSunshine = js["illuminationThresholdSunshine"] + self.storm = js["storm"] + self.sunshine = js["sunshine"] + self.todaySunshineDuration = js["todaySunshineDuration"] + self.totalSunshineDuration = js["totalSunshineDuration"] + self.windSpeed = js["windSpeed"] + self.windValueType = WindValueType.from_str(js["windValueType"]) + self.yesterdaySunshineDuration = js["yesterdaySunshineDuration"] + class WeatherSensorProChannel(WeatherSensorChannel): """ this is the representive of the WEATHER_SENSOR_PRO_CHANNEL channel""" def __init__(self): - super().__init__() - self.raining = False - self.todayRainCounter = 0 - self.totalRainCounter = 0 - self.weathervaneAlignmentNeeded = False - self.windDirection = 0 - self.windDirectionVariation = 0 + super().__init__() + self.raining = False + self.todayRainCounter = 0 + self.totalRainCounter = 0 + self.weathervaneAlignmentNeeded = False + self.windDirection = 0 + self.windDirectionVariation = 0 self.yesterdayRainCounter = 0 def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.raining = js["raining"] - self.todayRainCounter = js["todayRainCounter"] - self.totalRainCounter = js["totalRainCounter"] - self.weathervaneAlignmentNeeded = js["weathervaneAlignmentNeeded"] - self.windDirection = js["windDirection"] - self.windDirectionVariation = js["windDirectionVariation"] - self.yesterdayRainCounter = js["yesterdayRainCounter"] - + super().from_json(js,groups) + self.raining = js["raining"] + self.todayRainCounter = js["todayRainCounter"] + self.totalRainCounter = js["totalRainCounter"] + self.weathervaneAlignmentNeeded = js["weathervaneAlignmentNeeded"] + self.windDirection = js["windDirection"] + self.windDirectionVariation = js["windDirectionVariation"] + self.yesterdayRainCounter = js["yesterdayRainCounter"] + class SingleKeyChannel(FunctionalChannel): """ this is the representive of the SINGLE_KEY_CHANNEL channel""" \ No newline at end of file diff --git a/tests/json_data/home.json b/tests/json_data/home.json index 66c2ae22..1ed549cc 100644 --- a/tests/json_data/home.json +++ b/tests/json_data/home.json @@ -1973,6 +1973,149 @@ "serializedGlobalTradeItemNumber": "3014F711BBBBBBBBBBBBB016", "type": "REMOTE_CONTROL_8", "updateState": "UP_TO_DATE" + }, + "3014F711BBBBBBBBBBBBB18": { + "availableFirmwareVersion": "0.0.0", + "firmwareVersion": "1.8.12", + "firmwareVersionInteger": 67596, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F711BBBBBBBBBBBBB18", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000041" + ], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -35, + "rssiPeerValue": -36, + "unreach": false + }, + "1": { + "deviceId": "3014F711BBBBBBBBBBBBB18", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 1, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "2": { + "deviceId": "3014F711BBBBBBBBBBBBB18", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 2, + "groups": [ + "00000000-0000-0000-0000-000000000042", + "00000000-0000-0000-0000-000000000040" + ], + "index": 2, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "3": { + "deviceId": "3014F711BBBBBBBBBBBBB18", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 3, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 3, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "4": { + "deviceId": "3014F711BBBBBBBBBBBBB18", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 4, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 4, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "5": { + "deviceId": "3014F711BBBBBBBBBBBBB18", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 5, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 5, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "6": { + "deviceId": "3014F711BBBBBBBBBBBBB18", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 6, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 6, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "7": { + "deviceId": "3014F711BBBBBBBBBBBBB18", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 7, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 7, + "label": "", + "on": false, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + }, + "8": { + "deviceId": "3014F711BBBBBBBBBBBBB18", + "functionalChannelType": "SWITCH_CHANNEL", + "groupIndex": 8, + "groups": [ + "00000000-0000-0000-0000-000000000042" + ], + "index": 8, + "label": "", + "on": true, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F711BBBBBBBBBBBBB18", + "label": "ioBroker", + "lastStatusUpdate": 1543746604446, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 307, + "modelType": "HmIP-MOD-OC8", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F711BBBBBBBBBBBBB18", + "type": "OPEN_COLLECTOR_8_MODULE", + "updateState": "UP_TO_DATE" } }, "groups": { diff --git a/tests/test_devices.py b/tests/test_devices.py index be20acb5..86364617 100644 --- a/tests/test_devices.py +++ b/tests/test_devices.py @@ -6,6 +6,7 @@ from homematicip.base.base_connection import BaseConnection from homematicip.base.enums import * from homematicip.device import * +from homematicip.functionalChannels import * import json from datetime import datetime, timedelta, timezone @@ -508,4 +509,30 @@ def test_remote_control_8(fake_home:Home): d = fake_home.search_device_by_id("3014F711BBBBBBBBBBBBB016") assert d.modelId == 299 - assert d.label == "Fernbedienung - 8 Tasten" \ No newline at end of file + assert d.label == "Fernbedienung - 8 Tasten" + +def test_open_collector_8(fake_home:Home): + with no_ssl_verification(): + d = OpenCollector8Module(fake_home._connection) + d = fake_home.search_device_by_id("3014F711BBBBBBBBBBBBB18") + + c = d.functionalChannels[2] + + assert isinstance(c,SwitchChannel) + assert c.index == 2 + assert c.on == False + assert c.profileMode == "AUTOMATIC" + + c = d.functionalChannels[8] + + assert isinstance(c,SwitchChannel) + assert c.index == 8 + assert c.on == True + assert c.profileMode == "AUTOMATIC" + + d.turn_off(8) + fake_home.get_current_state() + d = fake_home.search_device_by_id("3014F711BBBBBBBBBBBBB18") + c = d.functionalChannels[8] + assert c.on == False + From 8676e5c94924e784a45e9bf496d4123fa41fd929 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 20:36:20 +0100 Subject: [PATCH 19/21] fixed naming of PRESENCE_DETECTOR_INDOOR added test for PRESENCE_DETECTOR_INDOOR added missing properties for PRESENCE_DETECTOR_INDOOR --- homematicip/aio/class_maps.py | 2 +- homematicip/base/enums.py | 2 +- homematicip/class_maps.py | 2 +- homematicip/device.py | 20 +++++++---- homematicip/functionalChannels.py | 18 +++++++--- tests/json_data/home.json | 57 +++++++++++++++++++++++++++++++ tests/test_devices.py | 17 ++++++++- 7 files changed, 103 insertions(+), 15 deletions(-) diff --git a/homematicip/aio/class_maps.py b/homematicip/aio/class_maps.py index a4b6da5f..b731b7eb 100644 --- a/homematicip/aio/class_maps.py +++ b/homematicip/aio/class_maps.py @@ -24,7 +24,7 @@ DeviceType.PLUGABLE_SWITCH: AsyncPlugableSwitch, DeviceType.FULL_FLUSH_SHUTTER: AsyncFullFlushShutter, DeviceType.BRAND_SHUTTER: AsyncFullFlushShutter, - DeviceType.PRECENCE_DETECTOR_INDOOR: AsyncPresenceDetectorIndoor, + DeviceType.PRESENCE_DETECTOR_INDOOR: AsyncPresenceDetectorIndoor, DeviceType.PLUGGABLE_DIMMER: AsyncPluggableDimmer, DeviceType.FULL_FLUSH_SWITCH_MEASURING: AsyncFullFlushSwitchMeasuring, DeviceType.WEATHER_SENSOR: AsyncWeatherSensor, diff --git a/homematicip/base/enums.py b/homematicip/base/enums.py index 1cde5982..e80ea15a 100644 --- a/homematicip/base/enums.py +++ b/homematicip/base/enums.py @@ -154,7 +154,7 @@ class DeviceType(AutoNameEnum): BRAND_WALL_MOUNTED_THERMOSTAT = auto() TEMPERATURE_HUMIDITY_SENSOR = auto() BRAND_SHUTTER = auto() - PRECENCE_DETECTOR_INDOOR = auto() + PRESENCE_DETECTOR_INDOOR = auto() PLUGGABLE_DIMMER = auto() BRAND_DIMMER = auto() BRAND_SWITCH_MEASURING = auto() diff --git a/homematicip/class_maps.py b/homematicip/class_maps.py index c2ddb747..0ffea996 100644 --- a/homematicip/class_maps.py +++ b/homematicip/class_maps.py @@ -30,7 +30,7 @@ DeviceType.PLUGABLE_SWITCH: PlugableSwitch, DeviceType.FULL_FLUSH_SHUTTER: FullFlushShutter, DeviceType.BRAND_SHUTTER: FullFlushShutter, - DeviceType.PRECENCE_DETECTOR_INDOOR: PresenceDetectorIndoor, + DeviceType.PRESENCE_DETECTOR_INDOOR: PresenceDetectorIndoor, DeviceType.PLUGGABLE_DIMMER: PluggableDimmer, DeviceType.BRAND_DIMMER: BrandDimmer, DeviceType.BRAND_SWITCH_MEASURING: BrandSwitchMeasuring, diff --git a/homematicip/device.py b/homematicip/device.py index 0f91b320..46f1ee9f 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -460,7 +460,6 @@ def __init__(self,connection): self.motionDetected = None self.illumination = None self.motionBufferActive = False - self.motionDetected = False self.motionDetectionSendInterval = MotionDetectionSendInterval.SECONDS_30 self.numberOfBrightnessMeasurements = 0 @@ -471,17 +470,15 @@ def from_json(self, js): self.motionDetected = c["motionDetected"] self.illumination = c["illumination"] self.motionBufferActive = c["motionBufferActive"] - self.motionDetected = c["motionDetected"] self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(c["motionDetectionSendInterval"]) self.numberOfBrightnessMeasurements = c["numberOfBrightnessMeasurements"] self.currentIllumination = c["currentIllumination"] def __str__(self): - return "{} motionDetected({}) illumination({}) motionBufferActive({}) motionDetected({}) motionDetectionSendInterval({}) numberOfBrightnessMeasurements({})".format(super().__str__(), + return "{} motionDetected({}) illumination({}) motionBufferActive({}) motionDetectionSendInterval({}) numberOfBrightnessMeasurements({})".format(super().__str__(), self.motionDetected, self.illumination, self.motionBufferActive, - self.motionDetected, self.motionDetectionSendInterval, self.numberOfBrightnessMeasurements) @@ -497,19 +494,30 @@ class PresenceDetectorIndoor(SabotageDevice): def __init__(self,connection): super().__init__(connection) self.presenceDetected = False + self.currentIllumination = None self.illumination = 0 + self.motionBufferActive = False + self.motionDetectionSendInterval = MotionDetectionSendInterval.SECONDS_30 + self.numberOfBrightnessMeasurements = 0 def from_json(self, js): super().from_json(js) c = get_functional_channel("PRESENCE_DETECTION_CHANNEL", js) if c: self.presenceDetected = c["presenceDetected"] + self.currentIllumination = c["currentIllumination"] self.illumination = c["illumination"] + self.motionBufferActive = c["motionBufferActive"] + self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(c["motionDetectionSendInterval"]) + self.numberOfBrightnessMeasurements = c["numberOfBrightnessMeasurements"] def __str__(self): - return "{} motionDetected({}) illumination({})".format(super().__str__(), + return "{} presenceDetected({}) illumination({}) motionBufferActive({}) motionDetectionSendInterval({}) numberOfBrightnessMeasurements({})".format(super().__str__(), self.presenceDetected, - self.illumination) + self.illumination, + self.motionBufferActive, + self.motionDetectionSendInterval, + self.numberOfBrightnessMeasurements) class KeyRemoteControlAlarm(Device): diff --git a/homematicip/functionalChannels.py b/homematicip/functionalChannels.py index 110ced6c..99ac5ddf 100644 --- a/homematicip/functionalChannels.py +++ b/homematicip/functionalChannels.py @@ -281,15 +281,23 @@ class PresenceDetectionChannel(FunctionalChannel): """ this is the representive of the PRESENCE_DETECTION_CHANNEL channel""" def __init__(self): super().__init__() - self.presenceDetected = False - self.illumination = 0 + self.presenceDetected = False + self.currentIllumination = None + self.illumination = 0 + self.motionBufferActive = False + self.motionDetectionSendInterval = MotionDetectionSendInterval.SECONDS_30 + self.numberOfBrightnessMeasurements = 0 def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ - super().from_json(js,groups) - self.presenceDetected = js["presenceDetected"] - self.illumination = js["illumination"] + super().from_json(js,groups) + self.presenceDetected = c["presenceDetected"] + self.currentIllumination = c["currentIllumination"] + self.illumination = c["illumination"] + self.motionBufferActive = c["motionBufferActive"] + self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(c["motionDetectionSendInterval"]) + self.numberOfBrightnessMeasurements = c["numberOfBrightnessMeasurements"] class ShutterChannel(FunctionalChannel): """ this is the representive of the SHUTTER_CHANNEL channel""" diff --git a/tests/json_data/home.json b/tests/json_data/home.json index 1ed549cc..9c34c4a4 100644 --- a/tests/json_data/home.json +++ b/tests/json_data/home.json @@ -1974,6 +1974,63 @@ "type": "REMOTE_CONTROL_8", "updateState": "UP_TO_DATE" }, + "3014F711AAAAAAAAAAAAAA51": { + "availableFirmwareVersion": "1.4.0", + "firmwareVersion": "1.4.0", + "firmwareVersionInteger": 66560, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F711AAAAAAAAAAAAAA51", + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000021", + "00000000-0000-0000-0000-000000000060" + ], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -62, + "rssiPeerValue": -61, + "sabotage": false, + "unreach": false + }, + "1": { + "currentIllumination": null, + "deviceId": "3014F711AAAAAAAAAAAAAA51", + "functionalChannelType": "PRESENCE_DETECTION_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000022", + "00000000-0000-0000-0000-000000000060" + ], + "illumination": 1.8, + "index": 1, + "label": "", + "motionBufferActive": false, + "motionDetectionSendInterval": "SECONDS_240", + "numberOfBrightnessMeasurements": 7, + "presenceDetected": false + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F711AAAAAAAAAAAAAA51", + "label": "***", + "lastStatusUpdate": 1542758692234, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 303, + "modelType": "HmIP-SPI", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F711AAAAAAAAAAAAAA51", + "type": "PRESENCE_DETECTOR_INDOOR", + "updateState": "UP_TO_DATE" + }, "3014F711BBBBBBBBBBBBB18": { "availableFirmwareVersion": "0.0.0", "firmwareVersion": "1.8.12", diff --git a/tests/test_devices.py b/tests/test_devices.py index 86364617..8692a7d0 100644 --- a/tests/test_devices.py +++ b/tests/test_devices.py @@ -495,7 +495,22 @@ def test_motion_detector_indoor(fake_home:Home): assert str(d) == ("HmIP-SMI Wohnzimmer lowbat(False) unreach(False) rssiDeviceValue(-56) rssiPeerValue(-52) configPending(False) " "dutyCycle(False): sabotage(False) motionDetected(True) illumination(0.1) motionBufferActive(False) " - "motionDetected(True) motionDetectionSendInterval(SECONDS_480) numberOfBrightnessMeasurements(7)") + "motionDetectionSendInterval(SECONDS_480) numberOfBrightnessMeasurements(7)") + +def test_presence_detector_indoor(fake_home:Home): + d = PresenceDetectorIndoor(fake_home._connection) + d = fake_home.search_device_by_id("3014F711AAAAAAAAAAAAAA51") + + assert d.illumination == 1.8 + assert d.currentIllumination == None + assert d.motionBufferActive == False + assert d.presenceDetected == False + assert d.motionDetectionSendInterval == MotionDetectionSendInterval.SECONDS_240 + assert d.numberOfBrightnessMeasurements == 7 + + assert str(d) == ("HmIP-SPI *** lowbat(False) unreach(False) rssiDeviceValue(-62) rssiPeerValue(-61) configPending(False) " + "dutyCycle(False): sabotage(False) presenceDetected(False) illumination(1.8) motionBufferActive(False) " + "motionDetectionSendInterval(SECONDS_240) numberOfBrightnessMeasurements(7)") def test_push_button_6(fake_home:Home): d = PushButton6(fake_home._connection) From 349afaafa01a04fbcad60d765ac69b44c600b3b3 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 22:04:33 +0100 Subject: [PATCH 20/21] added missing properties to FullFlushShutter added test for FullFlushShutter --- homematicip/device.py | 28 ++++++++++++-- homematicip/functionalChannels.py | 46 ++++++++++++++++------ tests/json_data/home.json | 63 +++++++++++++++++++++++++++++++ tests/test_devices.py | 23 +++++++++++ 4 files changed, 145 insertions(+), 15 deletions(-) diff --git a/homematicip/device.py b/homematicip/device.py index 46f1ee9f..5a498d57 100644 --- a/homematicip/device.py +++ b/homematicip/device.py @@ -540,17 +540,39 @@ class FullFlushShutter(Device): def __init__(self,connection): super().__init__(connection) - self.shutterLevel = None - self.bottomToTopReferenceTime = None - self.topToBottomReferenceTime = None + self.shutterLevel = 0 + self.changeOverDelay = 0.0 + self.bottomToTopReferenceTime = 0.0 + self.topToBottomReferenceTime = 0.0 + self.delayCompensationValue = 0 + self.endpositionAutoDetectionEnabled = False + self.previousShutterLevel = None + self.processing = False + self.profileMode = "AUTOMATIC" + self.selfCalibrationInProgress = None + self.supportingDelayCompensation = False + self.supportingEndpositionAutoDetection = False + self.supportingSelfCalibration = False + self.userDesiredProfileMode = "AUTOMATIC" def from_json(self, js): super().from_json(js) c = get_functional_channel("SHUTTER_CHANNEL", js) if c: self.shutterLevel = c["shutterLevel"] + self.changeOverDelay = c["changeOverDelay"] + self.delayCompensationValue = c["delayCompensationValue"] self.bottomToTopReferenceTime = c["bottomToTopReferenceTime"] self.topToBottomReferenceTime = c["topToBottomReferenceTime"] + self.endpositionAutoDetectionEnabled = c["endpositionAutoDetectionEnabled"] + self.previousShutterLevel = c["previousShutterLevel"] + self.processing = c["processing"] + self.profileMode = c["profileMode"] + self.selfCalibrationInProgress = c["selfCalibrationInProgress"] + self.supportingDelayCompensation = c["supportingDelayCompensation"] + self.supportingEndpositionAutoDetection = c["supportingEndpositionAutoDetection"] + self.supportingSelfCalibration = c["supportingSelfCalibration"] + self.userDesiredProfileMode = c["userDesiredProfileMode"] def __str__(self): return "{} shutterLevel({}) topToBottom({}) bottomToTop({})".format(super().__str__(), self.shutterLevel, self.topToBottomReferenceTime, diff --git a/homematicip/functionalChannels.py b/homematicip/functionalChannels.py index 99ac5ddf..fcbca706 100644 --- a/homematicip/functionalChannels.py +++ b/homematicip/functionalChannels.py @@ -292,28 +292,50 @@ def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.presenceDetected = c["presenceDetected"] - self.currentIllumination = c["currentIllumination"] - self.illumination = c["illumination"] - self.motionBufferActive = c["motionBufferActive"] - self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(c["motionDetectionSendInterval"]) - self.numberOfBrightnessMeasurements = c["numberOfBrightnessMeasurements"] + self.presenceDetected = js["presenceDetected"] + self.currentIllumination = js["currentIllumination"] + self.illumination = js["illumination"] + self.motionBufferActive = js["motionBufferActive"] + self.motionDetectionSendInterval = MotionDetectionSendInterval.from_str(js["motionDetectionSendInterval"]) + self.numberOfBrightnessMeasurements = js["numberOfBrightnessMeasurements"] class ShutterChannel(FunctionalChannel): """ this is the representive of the SHUTTER_CHANNEL channel""" def __init__(self): super().__init__() - self.shutterLevel = None - self.bottomToTopReferenceTime = None - self.topToBottomReferenceTime = None + self.shutterLevel = 0 + self.changeOverDelay = 0.0 + self.bottomToTopReferenceTime = 0.0 + self.topToBottomReferenceTime = 0.0 + self.delayCompensationValue = 0 + self.endpositionAutoDetectionEnabled = False + self.previousShutterLevel = None + self.processing = False + self.profileMode = "AUTOMATIC" + self.selfCalibrationInProgress = None + self.supportingDelayCompensation = False + self.supportingEndpositionAutoDetection = False + self.supportingSelfCalibration = False + self.userDesiredProfileMode = "AUTOMATIC" def from_json(self, js, groups: Iterable[Group]): """ this function will load the functional channel object from a json object and the given groups """ super().from_json(js,groups) - self.shutterLevel = js["shutterLevel"] - self.bottomToTopReferenceTime = js["bottomToTopReferenceTime"] - self.topToBottomReferenceTime = js["topToBottomReferenceTime"] + self.shutterLevel = js["shutterLevel"] + self.changeOverDelay = js["changeOverDelay"] + self.delayCompensationValue = js["delayCompensationValue"] + self.bottomToTopReferenceTime = js["bottomToTopReferenceTime"] + self.topToBottomReferenceTime = js["topToBottomReferenceTime"] + self.endpositionAutoDetectionEnabled = js["endpositionAutoDetectionEnabled"] + self.previousShutterLevel = js["previousShutterLevel"] + self.processing = js["processing"] + self.profileMode = js["profileMode"] + self.selfCalibrationInProgress = js["selfCalibrationInProgress"] + self.supportingDelayCompensation = js["supportingDelayCompensation"] + self.supportingEndpositionAutoDetection = js["supportingEndpositionAutoDetection"] + self.supportingSelfCalibration = js["supportingSelfCalibration"] + self.userDesiredProfileMode = js["userDesiredProfileMode"] class DimmerChannel(FunctionalChannel): """ this is the representive of the DIMMER_CHANNEL channel""" diff --git a/tests/json_data/home.json b/tests/json_data/home.json index 9c34c4a4..4c663c77 100644 --- a/tests/json_data/home.json +++ b/tests/json_data/home.json @@ -2031,6 +2031,69 @@ "type": "PRESENCE_DETECTOR_INDOOR", "updateState": "UP_TO_DATE" }, + "3014F711ACBCDABCADCA66": { + "availableFirmwareVersion": "1.6.2", + "firmwareVersion": "1.6.2", + "firmwareVersionInteger": 67074, + "functionalChannels": { + "0": { + "configPending": false, + "deviceId": "3014F711ACBCDABCADCA66", + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [ + "00000000-0000-0000-0000-000000000024" + ], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -78, + "rssiPeerValue": -77, + "unreach": false + }, + "1": { + "bottomToTopReferenceTime": 30.080000000000002, + "changeOverDelay": 0.5, + "delayCompensationValue": 12.7, + "deviceId": "3014F711ACBCDABCADCA66", + "endpositionAutoDetectionEnabled": true, + "functionalChannelType": "SHUTTER_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000069", + "00000000-0000-0000-0000-000000000070" + ], + "index": 1, + "label": "", + "previousShutterLevel": null, + "processing": false, + "profileMode": "AUTOMATIC", + "selfCalibrationInProgress": null, + "shutterLevel": 1.0, + "supportingDelayCompensation": true, + "supportingEndpositionAutoDetection": true, + "supportingSelfCalibration": true, + "topToBottomReferenceTime": 24.68, + "userDesiredProfileMode": "AUTOMATIC" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F711ACBCDABCADCA66", + "label": "***", + "lastStatusUpdate": 1542756558785, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 323, + "modelType": "HmIP-BROLL", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F711ACBCDABCADCA66", + "type": "BRAND_SHUTTER", + "updateState": "UP_TO_DATE" + }, "3014F711BBBBBBBBBBBBB18": { "availableFirmwareVersion": "0.0.0", "firmwareVersion": "1.8.12", diff --git a/tests/test_devices.py b/tests/test_devices.py index 8692a7d0..6c9abccb 100644 --- a/tests/test_devices.py +++ b/tests/test_devices.py @@ -551,3 +551,26 @@ def test_open_collector_8(fake_home:Home): c = d.functionalChannels[8] assert c.on == False + +def test_full_flush_shutter(fake_home:Home): + with no_ssl_verification(): + d = FullFlushShutter(fake_home._connection) + d = fake_home.search_device_by_id("3014F711ACBCDABCADCA66") + + assert d.bottomToTopReferenceTime == 30.080000000000002 + assert d.changeOverDelay == 0.5 + assert d.delayCompensationValue == 12.7 + assert d.endpositionAutoDetectionEnabled == True + assert d.previousShutterLevel == None + assert d.processing == False + assert d.profileMode == "AUTOMATIC" + assert d.selfCalibrationInProgress == None + assert d.shutterLevel == 1.0 + assert d.supportingDelayCompensation == True + assert d.supportingEndpositionAutoDetection == True + assert d.supportingSelfCalibration == True + assert d.topToBottomReferenceTime == 24.68 + assert d.userDesiredProfileMode == "AUTOMATIC" + + assert str(d) == ("HmIP-BROLL *** lowbat(None) unreach(False) rssiDeviceValue(-78) rssiPeerValue(-77) configPending(False)" + " dutyCycle(False) shutterLevel(1.0) topToBottom(24.68) bottomToTop(30.080000000000002)") From 5464dd74583bb298848877e71f548e965a451751 Mon Sep 17 00:00:00 2001 From: coreGreenberet Date: Sun, 16 Dec 2018 22:42:12 +0100 Subject: [PATCH 21/21] added an unknown functional channel --- tests/json_data/unknown_types.json | 49 +++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/tests/json_data/unknown_types.json b/tests/json_data/unknown_types.json index 8fc93007..0ed491eb 100644 --- a/tests/json_data/unknown_types.json +++ b/tests/json_data/unknown_types.json @@ -12,22 +12,41 @@ "availableFirmwareVersion": "0.0.0", "firmwareVersion": "1.0.2", "firmwareVersionInteger": "65538", - "functionalChannels": {}, - "homeId": "00000000-0000-0000-0000-000000000001", - "id": "3014F7110000000000000050", - "label": "DUMMY_DEVICE", - "lastStatusUpdate": 1530802738493, - "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", - "manufacturerCode": 1, - "modelId": 353, - "modelType": "HmIP-DUMMY", - "oem": "eQ-3", - "permanentlyReachable": true, - "serializedGlobalTradeItemNumber": "3014F7110000000000000050", - "type": "DUMMY_DEVICE", - "updateState": "UP_TO_DATE" + "functionalChannels": { - } + "0": { + "configPending": false, + "deviceId": "3014F7110000000000000050", + "dutyCycle": false, + "functionalChannelType": "DEVICE_UNKNOWN", + "groupIndex": 0, + "groups": [ + ], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -78, + "rssiPeerValue": -77, + "unreach": false + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000000000050", + "label": "DUMMY_DEVICE", + "lastStatusUpdate": 1530802738493, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 353, + "modelType": "HmIP-DUMMY", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000000000050", + "type": "DUMMY_DEVICE", + "updateState": "UP_TO_DATE" + + } }, "groups": { "00000000-0000-0000-0000-000000000020": {