Skip to content
This repository has been archived by the owner on Feb 4, 2024. It is now read-only.

0.1.68 #319

Merged
merged 8 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
Version 0.1.68 (2020-08-04)
- Support rx_mode @rusitschka
- HomeMatic IP stability @weissm
- Add Sensor-Node for HmIP-Covers @danielperna84
- Add support for HmIPW devices @p0l0
- Add support for HB-UNI-RGB-LED-CTR @lukasriegel

Version 0.1.67 (2020-05-14)
- Refactoring @danielperna84
- Add support for HmIP-SWDO-PL @rgriebl
Expand Down
27 changes: 23 additions & 4 deletions pyhomematic/_hm.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ def listDevices(self, interface_id):
self._devices_raw[remote] = []
if self.systemcallback:
self.systemcallback('listDevices', interface_id)

# return empty list for HmIP, as currently the maximum lenght is limited to 8192 bytes (see #318 for details)
if self.remotes.get(remote, {}).get('port') in [2010, 32010, 42010]:
return []
return self._devices_raw[remote]

def newDevices(self, interface_id, dev_descriptions):
Expand All @@ -295,7 +299,11 @@ def newDevices(self, interface_id, dev_descriptions):
self._devices_raw_dict[remote] = {}
if remote not in self._paramsets:
self._paramsets[remote] = {}
hmip = self.remotes.get(remote, {}).get('port') in [2010, 32010, 42010]
for d in dev_descriptions:
if hmip:
if d in self._devices_raw[remote]:
continue
self._devices_raw[remote].append(d)
self._devices_raw_dict[remote][d['ADDRESS']] = d
self._paramsets[remote][d['ADDRESS']] = {}
Expand Down Expand Up @@ -358,7 +366,10 @@ def jsonRpcPost(self, host, jsonport, method, params={}):

headers = {"Content-Type": 'application/json',
"Content-Length": len(payload)}
apiendpoint = "http://%s:%s%s" % (host, jsonport, JSONRPC_URL)
if jsonport == 443:
apiendpoint = "https://%s:%s%s" % (host, jsonport, JSONRPC_URL)
else:
apiendpoint = "http://%s:%s%s" % (host, jsonport, JSONRPC_URL)
LOG.debug("RPCFunctions.jsonRpcPost: API-Endpoint: %s" %
apiendpoint)
req = urllib.request.Request(apiendpoint, payload, headers)
Expand Down Expand Up @@ -522,7 +533,6 @@ def __getattr__(self, *args, **kwargs):
"""
Magic method dispatcher
"""

return xmlrpc.client._Method(self.__request, *args, **kwargs)

# Restrict to particular paths.
Expand Down Expand Up @@ -669,6 +679,11 @@ def proxyInit(self):
LOG.debug("ServerThread.proxyInit: init('http://%s:%i', '%s')" %
(callbackip, callbackport, interface_id))
try:
# For HomeMatic IP, init is not working correctly. We fetch the device list and create
# the device objects before the init is performed.
if proxy._remoteport in [2010, 32010, 42010]:
dev_list = proxy.listDevices(interface_id)
self._rpcfunctions.newDevices(interface_id=interface_id, dev_descriptions=dev_list)
proxy.init("http://%s:%i" %
(callbackip, callbackport), interface_id)
LOG.info("Proxy for %s initialized", interface_id)
Expand Down Expand Up @@ -982,9 +997,13 @@ def homegearCheckInit(self, remote):
"ServerThread.homegearCheckInit: Exception: %s" % str(err))
return False

def putParamset(self, remote, address, paramset, value):
def putParamset(self, remote, address, paramset, value, rx_mode=None):
"""Set paramsets manually"""
try:
return self.proxies["%s-%s" % (self._interface_id, remote)].putParamset(address, paramset, value)
proxy = self.proxies["%s-%s" % (self._interface_id, remote)]
if rx_mode is None:
return proxy.putParamset(address, paramset, value)
else:
return proxy.putParamset(address, paramset, value, rx_mode)
except Exception as err:
LOG.debug("ServerThread.putParamset: Exception: %s" % str(err))
4 changes: 2 additions & 2 deletions pyhomematic/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def homegearCheckInit(self, remote):
if self._server is not None:
return self._server.homegearCheckInit(remote)

def putParamset(self, remote, address, paramset, value):
def putParamset(self, remote, address, paramset, value, rx_mode=None):
"""Set paramsets manually"""
if self._server is not None:
return self._server.putParamset(remote, address, paramset, value)
return self._server.putParamset(remote, address, paramset, value, rx_mode)
57 changes: 56 additions & 1 deletion pyhomematic/devicetypes/actors.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def __init__(self, device_description, proxy, resolveparamsets=False):
"LEVEL_STATUS": self.ELEMENT,
"SECTION": self.ELEMENT})
self.ACTIONNODE.update({"STOP": self.ELEMENT})
self.SENSORNODE.update({"LEVEL": [3]})
self.WRITENODE.update({"LEVEL": self.ELEMENT})


Expand Down Expand Up @@ -326,7 +327,7 @@ def ELEMENT(self):

class IPWSwitch(GenericSwitch, HelperDeviceTemperature, HelperWired):
"""
HomematicIP-Wired Switch units turning attached device on or off.
IP-Wired Switch units turning attached device on or off.
"""
@property
def ELEMENT(self):
Expand All @@ -339,6 +340,56 @@ def ELEMENT(self):
return [1]


class IPWDimmer(GenericDimmer, HelperDeviceTemperature, HelperWired):
"""
IP-Wired Dimmer switch that controls level of light brightness.
"""
@property
def ELEMENT(self):
if "HmIPW-DRD3" in self._TYPE:
# Address correct switching channels for each relais
return [2, 6, 10]
return [1]


class IPWMotionDection(HelperWired):
"""
IP-Wired Motion Detection
"""
def __init__(self, device_description, proxy, resolveparamsets=False):
super().__init__(device_description, proxy, resolveparamsets)

# init metadata
self.BINARYNODE.update({"PRESENCE_DETECTION_STATE": self.ELEMENT,
"PRESENCE_DETECTION_ACTIVE": self.ELEMENT,
"CURRENT_ILLUMINATION_STATUS": self.ELEMENT,
"ILLUMINATION_STATUS": self.ELEMENT})
self.SENSORNODE.update({"ILLUMINATION": self.ELEMENT,
"CURRENT_ILLUMINATION": self.ELEMENT})

@property
def ELEMENT(self):
return [1]


class IPWKeyBlindMulti(KeyBlind, HelperDeviceTemperature, HelperWired):
"""
Multi-blind actor HmIPW-DRBL4
"""
def __init__(self, device_description, proxy, resolveparamsets=False):
super().__init__(device_description, proxy, resolveparamsets)

# init metadata
self.ATTRIBUTENODE.update({"ACTIVITY_STATE": self.ELEMENT,
"LEVEL_STATUS": self.ELEMENT,
"SECTION": self.ELEMENT})
self.ACTIONNODE.update({"STOP": self.ELEMENT})
self.WRITENODE.update({"LEVEL": self.ELEMENT})

@property
def ELEMENT(self):
return [2, 6, 10, 14]

class IPWInputDevice(HMEvent, HelperDeviceTemperature, HelperWired):
"""
IP-Wired component to support long / short press events and state report (e.g. if window contact or on/off switch)
Expand Down Expand Up @@ -947,6 +998,9 @@ def set_color_temp(self, color_temp: float, channel=None):
"HmIPW-DRS8": IPWSwitch,
"HmIPW-DRI32": IPWInputDevice,
"HmIPW-DRI16": IPWInputDevice,
"HmIPW-DRD3": IPWDimmer,
"HmIPW-SPI": IPWMotionDection,
"HmIPW-DRBL4": IPWKeyBlindMulti,
"HMIP-PS": IPSwitch,
"HmIP-PS": IPSwitch,
"HmIP-PS-CH": IPSwitch,
Expand Down Expand Up @@ -985,4 +1039,5 @@ def set_color_temp(self, color_temp: float, channel=None):
"HmIP-MIOB": IPMultiIO,
"HM-DW-WM": Dimmer,
"HM-LC-DW-WM": ColdWarmDimmer,
"HB-UNI-RGB-LED-CTRL": ColorEffectLight,
}
7 changes: 5 additions & 2 deletions pyhomematic/devicetypes/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,18 @@ def updateParamsets(self):
LOG.error("HMGeneric.updateParamsets: Exception: " + str(err))
return False

def putParamset(self, paramset, data={}):
def putParamset(self, paramset, data={}, rx_mode=None):
"""
Some devices act upon changes to paramsets.
A "putted" paramset must not contain all keys available in the specified paramset,
just the ones which are writable and should be changed.
"""
try:
if paramset in self._PARAMSETS and data:
self._proxy.putParamset(self._ADDRESS, paramset, data)
if rx_mode is None:
self._proxy.putParamset(self._ADDRESS, paramset, data)
else:
self._proxy.putParamset(self._ADDRESS, paramset, data, rx_mode)
# We update all paramsets to at least have a temporarily accurate state for the device.
# This might not be true for tasks that take long to complete (lifting a rollershutter completely etc.).
# For this the server-process has to call the updateParamsets-method when it receives events for the device.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def readme():

PACKAGE_NAME = 'pyhomematic'
HERE = os.path.abspath(os.path.dirname(__file__))
VERSION = '0.1.67'
VERSION = '0.1.68'

PACKAGES = find_packages(exclude=['tests', 'tests.*', 'dist', 'build'])

Expand Down