From e034a63e04a0720b90d375de0570f09459dfdcd6 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Sun, 18 Nov 2018 16:49:10 +0100 Subject: [PATCH 01/18] Change loglevel for getValue to warning --- pyhomematic/devicetypes/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyhomematic/devicetypes/generic.py b/pyhomematic/devicetypes/generic.py index 77e7d0775..fcf9ea1f8 100644 --- a/pyhomematic/devicetypes/generic.py +++ b/pyhomematic/devicetypes/generic.py @@ -206,7 +206,7 @@ def getValue(self, key): self._VALUES[key] = returnvalue return returnvalue except Exception as err: - LOG.error("HMGeneric.getValue: %s on %s Exception: %s", key, + LOG.warning("HMGeneric.getValue: %s on %s Exception: %s", key, self._ADDRESS, err) return False From 79a2218264aa11639954e2b795954f8b651884b9 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Sun, 18 Nov 2018 16:50:28 +0100 Subject: [PATCH 02/18] Bump version, update changelog --- changelog.txt | 3 +++ setup.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index e9a35ae2b..5aff91b3f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +Version 0.1.53 () +- Changed loglevel for getValue to `warning` (Issue #153) @danielperna84 + Version 0.1.52 (2018-11-15) - Added HmIP-MOD-TM (Issue #170) @danielperna84 - Added HM-LC-RGBW-WM @chr1st1ank diff --git a/setup.py b/setup.py index 90b7827c8..cac056aa2 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ def readme(): PACKAGE_NAME = 'pyhomematic' HERE = os.path.abspath(os.path.dirname(__file__)) -VERSION = '0.1.52' +VERSION = '0.1.53' PACKAGES = find_packages(exclude=['tests', 'tests.*', 'dist', 'build']) From 881fc4fe07ebf18b23a083aba90118b5ee141539 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Sun, 18 Nov 2018 16:54:02 +0100 Subject: [PATCH 03/18] Lint --- pyhomematic/devicetypes/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyhomematic/devicetypes/generic.py b/pyhomematic/devicetypes/generic.py index fcf9ea1f8..25f5024bd 100644 --- a/pyhomematic/devicetypes/generic.py +++ b/pyhomematic/devicetypes/generic.py @@ -207,7 +207,7 @@ def getValue(self, key): return returnvalue except Exception as err: LOG.warning("HMGeneric.getValue: %s on %s Exception: %s", key, - self._ADDRESS, err) + self._ADDRESS, err) return False From c1c1a2db8831efc83d3f4e8a10956da0bab2c9b4 Mon Sep 17 00:00:00 2001 From: SiwYv Date: Tue, 20 Nov 2018 18:21:00 +0100 Subject: [PATCH 04/18] Adding support for HmIP-eTRV-B to thermostats.py This is the basic thermostat included in HmIP-SK9 (https://www.homematic-ip.com/en/products/detail/starter-set-heating-easy-connect.html). --- pyhomematic/devicetypes/thermostats.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyhomematic/devicetypes/thermostats.py b/pyhomematic/devicetypes/thermostats.py index d7ec0eeb5..e3f82751d 100644 --- a/pyhomematic/devicetypes/thermostats.py +++ b/pyhomematic/devicetypes/thermostats.py @@ -351,6 +351,7 @@ def turnoff(self): "HMIP-eTRV": IPThermostat, "HmIP-eTRV": IPThermostat, "HmIP-eTRV-2": IPThermostat, + "HmIP-eTRV-B": IPThermostat, "HmIP-STHD": IPThermostatWall, "HmIP-STH": IPThermostatWall, "HmIP-WTH-2": IPThermostatWall, From 2a7c4577990ac051765f02267666173f77b3aa23 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Sun, 25 Nov 2018 23:11:52 +0100 Subject: [PATCH 05/18] Set channel for LOW_BAT to 0, fixes #186 --- changelog.txt | 1 + pyhomematic/devicetypes/helper.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 5aff91b3f..1e3dab745 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,6 @@ Version 0.1.53 () - Changed loglevel for getValue to `warning` (Issue #153) @danielperna84 +- Channel for LOW_BAT always is 0 for HmIP devices (Issue #186) @danielperna84 Version 0.1.52 (2018-11-15) - Added HmIP-MOD-TM (Issue #170) @danielperna84 diff --git a/pyhomematic/devicetypes/helper.py b/pyhomematic/devicetypes/helper.py index 10734fdd8..79aacaecd 100644 --- a/pyhomematic/devicetypes/helper.py +++ b/pyhomematic/devicetypes/helper.py @@ -45,7 +45,7 @@ def __init__(self, device_description, proxy, resolveparamsets=False): super().__init__(device_description, proxy, resolveparamsets) # init metadata - self.ATTRIBUTENODE.update({"LOW_BAT": self.ELEMENT}) + self.ATTRIBUTENODE.update({"LOW_BAT": [0]}) def low_batt(self, channel=None): """ Returns if the battery is low. """ From 59ebfdea0bb2acfaf1dba3dca1f90f9e2230de4d Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Sun, 25 Nov 2018 23:18:36 +0100 Subject: [PATCH 06/18] Lint --- pyhomematic/devicetypes/sensors.py | 2 -- pyhomematic/exceptions.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/pyhomematic/devicetypes/sensors.py b/pyhomematic/devicetypes/sensors.py index 1e9108be7..e0c96ce23 100644 --- a/pyhomematic/devicetypes/sensors.py +++ b/pyhomematic/devicetypes/sensors.py @@ -37,7 +37,6 @@ def ELEMENT(self): class ShutterContact(IPShutterContact, HelperSabotage, HelperRssiPeer): """Door / Window contact that emits its open/closed state.""" - pass class MaxShutterContact(HMBinarySensor, HelperBinaryState, HelperLowBat): @@ -282,7 +281,6 @@ def ELEMENT(self): class MotionV2(Motion, HelperSabotage): """Motion detection version 2.""" - pass class MotionIP(HMBinarySensor, HMSensor): diff --git a/pyhomematic/exceptions.py b/pyhomematic/exceptions.py index 99c6485e5..fa32662f5 100644 --- a/pyhomematic/exceptions.py +++ b/pyhomematic/exceptions.py @@ -2,11 +2,9 @@ class HMException(Exception): """ Base exception for all exceptions pyhomeamtic will raise. """ - pass class HMRpcException(HMException): """ Exception for errors while communicating via XML-RPC. """ - pass From d1978f6526c33696c1f016c97363092f8eaab888 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Sun, 25 Nov 2018 23:20:45 +0100 Subject: [PATCH 07/18] Lint --- pyhomematic/devicetypes/actors.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyhomematic/devicetypes/actors.py b/pyhomematic/devicetypes/actors.py index 7b4d2ccb7..2026e891f 100644 --- a/pyhomematic/devicetypes/actors.py +++ b/pyhomematic/devicetypes/actors.py @@ -13,7 +13,6 @@ class HMActor(HMDevice): """ Generic HM Actor Object """ - pass class GenericBlind(HMActor, HelperActorLevel): From b969d8355f930e7e5a08e185c70884445ecf92b4 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Sun, 25 Nov 2018 23:26:58 +0100 Subject: [PATCH 08/18] Nicer parsing of hostname and port (taken from #182) --- pyhomematic/_hm.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyhomematic/_hm.py b/pyhomematic/_hm.py index ec9050095..4eac81ffd 100644 --- a/pyhomematic/_hm.py +++ b/pyhomematic/_hm.py @@ -2,6 +2,7 @@ import threading import json import urllib.request +import urllib.parse import xml.etree.ElementTree as ET from xmlrpc.server import SimpleXMLRPCServer from xmlrpc.server import SimpleXMLRPCRequestHandler @@ -401,8 +402,9 @@ def __init__(self, *args, **kwargs): self._callbackport = kwargs.pop("callbackport", None) self.lock = threading.Lock() xmlrpc.client.ServerProxy.__init__(self, *args, **kwargs) - self._remoteip, self._remoteport = self._ServerProxy__host.split(':') - self._remoteport = int(self._remoteport) + urlcomponents = urllib.parse.urlparse(args[0]) + self._remoteip = urlcomponents.hostname + self._remoteport = urlcomponents.port LOG.debug("LockingServerProxy.__init__: Getting local ip") tmpsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) tmpsocket.connect((self._remoteip, self._remoteport)) From 895b1bc95c4837bee3f784403e4a68553da3cdf3 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Mon, 26 Nov 2018 00:43:57 +0100 Subject: [PATCH 09/18] Prepare authentication and SSL (inspired by #182) --- pyhomematic/_hm.py | 51 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/pyhomematic/_hm.py b/pyhomematic/_hm.py index 4eac81ffd..48a2309da 100644 --- a/pyhomematic/_hm.py +++ b/pyhomematic/_hm.py @@ -46,6 +46,38 @@ working = False +def make_http_credentials(username=None, password=None): + """Build auth part for api_url.""" + credentials = '' + if username is None: + return credentials + if username is not None: + if ':' in username: + return credentials + credentials += username + if credentials and password is not None: + credentials += ":%s" % password + return "%s@" % credentials + + +def build_api_url(host=REMOTES['default']['ip'], + port=REMOTES['default']['port'], + path=REMOTES['default']['port'], + username=None, + password=None, + ssl=False): + """Build API URL from components.""" + credentials = make_http_credentials(username, password) + scheme = 'http' + if not path: + path = '' + if path and not path.startswith('/'): + path = "/%s" % path + if ssl: + scheme += 's' + return "%s://%s%s:%i%s" % (scheme, credentials, host, port, path) + + # Object holding the methods the XML-RPC server should provide. class RPCFunctions(): @@ -476,15 +508,22 @@ def __init__(self, LOG.warning("Skipping proxy: %s" % str(err)) continue if 'path' not in host: - host['path'] = "" - LOG.info("Creating proxy %s. Connecting to http://%s:%i%s" % + host['path'] = '' + LOG.info("Creating proxy %s. Connecting to %s:%i%s" % (remote, host['ip'], host['port'], host['path'])) host['id'] = "%s-%s" % (self._interface_id, remote) try: - self.proxies[host['id']] = LockingServerProxy("http://%s:%i%s" % (host['ip'], host['port'], host['path']), - callbackip=host.get('callbackip', None), - callbackport=host.get('callbackport', None), - skipinit=not host.get('connect', True)) + api_url = build_api_url(host=host['ip'], + port=host['port'], + path=host['path'], + username=host.get('username'), + password=host.get('password'), + ssl=host.get('ssl')) + self.proxies[host['id']] = LockingServerProxy( + api_url, + callbackip=host.get('callbackip', None), + callbackport=host.get('callbackport', None), + skipinit=not host.get('connect', True)) except Exception as err: LOG.warning("Failed connecting to proxy at http://%s:%i%s" % (host['ip'], host['port'], host['path'])) From 4c247e13398c9b67cbb3fece97f12b62f15283ca Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Mon, 26 Nov 2018 01:05:25 +0100 Subject: [PATCH 10/18] Prepare to optionally allow untrusted SSL --- pyhomematic/_hm.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pyhomematic/_hm.py b/pyhomematic/_hm.py index 48a2309da..8238f4897 100644 --- a/pyhomematic/_hm.py +++ b/pyhomematic/_hm.py @@ -1,6 +1,7 @@ import os import threading import json +import ssl import urllib.request import urllib.parse import xml.etree.ElementTree as ET @@ -432,7 +433,11 @@ def __init__(self, *args, **kwargs): self._skipinit = kwargs.pop("skipinit", False) self._callbackip = kwargs.pop("callbackip", None) self._callbackport = kwargs.pop("callbackport", None) + self._ssl = kwargs.pop("ssl", False) + self._verify_ssl = kwargs.pop("verify_ssl", True) self.lock = threading.Lock() + if self._ssl and not self._verify_ssl and self._verify_ssl is not None: + kwargs['context'] = ssl._create_unverified_context() xmlrpc.client.ServerProxy.__init__(self, *args, **kwargs) urlcomponents = urllib.parse.urlparse(args[0]) self._remoteip = urlcomponents.hostname @@ -523,7 +528,9 @@ def __init__(self, api_url, callbackip=host.get('callbackip', None), callbackport=host.get('callbackport', None), - skipinit=not host.get('connect', True)) + skipinit=not host.get('connect', True), + ssl=host.get('ssl', False), + verify_ssl=host.get('verify_ssl', True)) except Exception as err: LOG.warning("Failed connecting to proxy at http://%s:%i%s" % (host['ip'], host['port'], host['path'])) From 66a28438ab7cb177f4875bb69aa3f22e4eba8b13 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Wed, 28 Nov 2018 22:54:34 +0100 Subject: [PATCH 11/18] Allow hostnames as API target --- changelog.txt | 1 + pyhomematic/_hm.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 1e3dab745..5e278e208 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,7 @@ Version 0.1.53 () - Changed loglevel for getValue to `warning` (Issue #153) @danielperna84 - Channel for LOW_BAT always is 0 for HmIP devices (Issue #186) @danielperna84 +- Support hostnames for XML-RPC endpoints @danielperna84 Version 0.1.52 (2018-11-15) - Added HmIP-MOD-TM (Issue #170) @danielperna84 diff --git a/pyhomematic/_hm.py b/pyhomematic/_hm.py index 8238f4897..a2a559f40 100644 --- a/pyhomematic/_hm.py +++ b/pyhomematic/_hm.py @@ -508,7 +508,7 @@ def __init__(self, for remote, host in self.remotes.items(): # Initialize XML-RPC try: - socket.inet_pton(socket.AF_INET, host['ip']) + socket.gethostbyname(host['ip']) except Exception as err: LOG.warning("Skipping proxy: %s" % str(err)) continue From 63a1dd20d41454f94bee9c1b9177af93dd3a284f Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Wed, 28 Nov 2018 23:23:02 +0100 Subject: [PATCH 12/18] Update changelog --- changelog.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 5e278e208..40486ed2e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,7 +1,8 @@ -Version 0.1.53 () +Version 0.1.53 (2018-) - Changed loglevel for getValue to `warning` (Issue #153) @danielperna84 - Channel for LOW_BAT always is 0 for HmIP devices (Issue #186) @danielperna84 - Support hostnames for XML-RPC endpoints @danielperna84 +- Add support for HmIP-eTRV-B @SiwYv Version 0.1.52 (2018-11-15) - Added HmIP-MOD-TM (Issue #170) @danielperna84 From fad44f7773f4ffb1151d4bbdee57283043ff82ee Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Mon, 3 Dec 2018 00:20:00 +0100 Subject: [PATCH 13/18] Add support for the HB-UW-Sen-THPL-[OI] "Univeral Sensor" --- pyhomematic/devicetypes/sensors.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pyhomematic/devicetypes/sensors.py b/pyhomematic/devicetypes/sensors.py index e0c96ce23..6ab6bb5ac 100644 --- a/pyhomematic/devicetypes/sensors.py +++ b/pyhomematic/devicetypes/sensors.py @@ -724,6 +724,23 @@ def __init__(self, device_description, proxy, resolveparamsets=False): self.ATTRIBUTENODE.update({"OPERATING_VOLTAGE": [0]}) +class UniversalSensor(WeatherStation, HelperLowBat, HelperRssiPeer): + """Universal sensor. (https://wiki.fhem.de/wiki/Universalsensor)""" + + def __init__(self, device_description, proxy, resolveparamsets=False): + super().__init__(device_description, proxy, resolveparamsets) + + # init metadata + self.SENSORNODE.update({"BatteryVoltage": [1], + "LUMINOSITY": [1]}) + + def get_luminosity(self, channel=None): + return float(self.getSensorData("LUMINOSITY", channel)) + + def get_battery_voltage(self, channel=None): + return float(self.getSensorData("BatteryVoltage", channel)) + + DEVICETYPES = { "HM-Sec-SC": ShutterContact, "HM-Sec-SC-2": ShutterContact, @@ -809,4 +826,6 @@ def __init__(self, device_description, proxy, resolveparamsets=False): "HmIP-SPDR": IPPassageSensor, "IT-Old-Remote-1-Channel": SmartwareMotion, "HmIP-SLO": IPBrightnessSensor, + "HB-UW-Sen-THPL-O": UniversalSensor, + "HB-UW-Sen-THPL-I": UniversalSensor, } From c11dcdea75372eecaee9ae06eea954237c386bf4 Mon Sep 17 00:00:00 2001 From: DieterChmod Date: Mon, 3 Dec 2018 20:41:09 +0100 Subject: [PATCH 14/18] Adding HmIP-FDT IP Dimmer support. --- pyhomematic/devicetypes/actors.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyhomematic/devicetypes/actors.py b/pyhomematic/devicetypes/actors.py index 7b4d2ccb7..ddf8debc1 100644 --- a/pyhomematic/devicetypes/actors.py +++ b/pyhomematic/devicetypes/actors.py @@ -130,7 +130,9 @@ class IPDimmer(GenericDimmer): """ @property def ELEMENT(self): - return [3] + if "PDT" in self._TYPE: + return [3] + return [2] class IPKeyDimmer(GenericDimmer, HelperWorking, HelperActionPress): @@ -665,6 +667,7 @@ def turn_off_effect(self): "HmIP-BSM": IPKeySwitchPowermeter, "HMIP-BDT": IPKeyDimmer, "HmIP-BDT": IPKeyDimmer, + "HmIP-FDT": IPDimmer, "HmIP-PDT": IPDimmer, "HM-Sec-Key": KeyMatic, "HM-Sec-Key-S": KeyMatic, From 53023236dac7569c0af699074a3fd8d439214bd3 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Mon, 3 Dec 2018 23:09:59 +0100 Subject: [PATCH 15/18] Updated changelog --- changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelog.txt b/changelog.txt index 40486ed2e..06cd12f8b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,6 +3,8 @@ Version 0.1.53 (2018-) - Channel for LOW_BAT always is 0 for HmIP devices (Issue #186) @danielperna84 - Support hostnames for XML-RPC endpoints @danielperna84 - Add support for HmIP-eTRV-B @SiwYv +- Added support for HmIP-FDT @DieterChmod +- Added support for HB-UW-Sen-THPL-O and HB-UW-Sen-THPL-I @rgriebl Version 0.1.52 (2018-11-15) - Added HmIP-MOD-TM (Issue #170) @danielperna84 From 07d6a2e79adcc10e4e322c88eb6ac2be1531a9ea Mon Sep 17 00:00:00 2001 From: Johannes Berrenberg Date: Mon, 3 Dec 2018 17:16:18 +0100 Subject: [PATCH 16/18] add IPThermostat HmIP-B1 to DEVICETYPES To support the HmIP-B1 sold by german discounter Lidl a new IPThermostat entry is added. --- pyhomematic/devicetypes/thermostats.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyhomematic/devicetypes/thermostats.py b/pyhomematic/devicetypes/thermostats.py index e3f82751d..f8d4bc736 100644 --- a/pyhomematic/devicetypes/thermostats.py +++ b/pyhomematic/devicetypes/thermostats.py @@ -352,6 +352,7 @@ def turnoff(self): "HmIP-eTRV": IPThermostat, "HmIP-eTRV-2": IPThermostat, "HmIP-eTRV-B": IPThermostat, + "HmIP-eTRV-B1": IPThermostat, "HmIP-STHD": IPThermostatWall, "HmIP-STH": IPThermostatWall, "HmIP-WTH-2": IPThermostatWall, From 8d056fefb69ccba69e6dceff06d6fe86eb0e0a42 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Wed, 5 Dec 2018 22:08:06 +0100 Subject: [PATCH 17/18] Update changelog --- changelog.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 06cd12f8b..d56e5def2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,10 +1,11 @@ -Version 0.1.53 (2018-) +Version 0.1.53 (2018-12-05) - Changed loglevel for getValue to `warning` (Issue #153) @danielperna84 - Channel for LOW_BAT always is 0 for HmIP devices (Issue #186) @danielperna84 - Support hostnames for XML-RPC endpoints @danielperna84 - Add support for HmIP-eTRV-B @SiwYv - Added support for HmIP-FDT @DieterChmod - Added support for HB-UW-Sen-THPL-O and HB-UW-Sen-THPL-I @rgriebl +- Add support for SSL and authentication with CCU3 @danielperna84 Version 0.1.52 (2018-11-15) - Added HmIP-MOD-TM (Issue #170) @danielperna84 From de789773eaca61ad7189103b1b165ad72cb82190 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Wed, 5 Dec 2018 22:10:40 +0100 Subject: [PATCH 18/18] Update changelog --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index d56e5def2..5dfa17193 100644 --- a/changelog.txt +++ b/changelog.txt @@ -6,6 +6,7 @@ Version 0.1.53 (2018-12-05) - Added support for HmIP-FDT @DieterChmod - Added support for HB-UW-Sen-THPL-O and HB-UW-Sen-THPL-I @rgriebl - Add support for SSL and authentication with CCU3 @danielperna84 +- Added support for HmIP-B1 @jberrenberg Version 0.1.52 (2018-11-15) - Added HmIP-MOD-TM (Issue #170) @danielperna84