diff --git a/pyW215/pyW215.py b/pyW215/pyW215.py
index 67075f0..3d22d9f 100644
--- a/pyW215/pyW215.py
+++ b/pyW215/pyW215.py
@@ -58,16 +58,13 @@ def __init__(self, ip, password, user = "admin",
if self.use_legacy_protocol:
_LOGGER.info("Enabled support for legacy firmware.")
self._error_report = False
- self.model_name = self.SOAPAction(Action="GetDeviceSettings", responseElement="ModelName", params = "")
-
- def moduleParameters(self, module):
- """Returns moduleID XML.
-
- :type module: str
- :param module: module number/ID
- :return XML string with moduleID
- """
- return '''{}'''.format(module)
+ self.model_name = self.get_soap_value(Action="GetDeviceSettings", responseElement="ModelName", params = "")
+ self.modules = {
+ 'socket': '1',
+ 'power': '2',
+ 'temperature': '3'
+ }
+ self.refresh_modules()
def controlParameters(self, module, status):
"""Returns control parameters as XML.
@@ -80,10 +77,10 @@ def controlParameters(self, module, status):
"""
if self.use_legacy_protocol :
return '''{}Socket 1Socket 1
- {}1'''.format(self.moduleParameters(module), status)
+ {}1'''.format(module, status)
else:
return '''{}Socket 1Socket 1
- {}'''.format(self.moduleParameters(module), status)
+ {}'''.format(module, status)
def radioParameters(self, radio):
"""Returns RadioID as XML.
@@ -166,7 +163,10 @@ def SOAPAction(self, Action, responseElement, params = "", recursive = False):
return return_value
xmlData = response.read().decode()
- root = ET.fromstring(xmlData)
+ return ET.fromstring(xmlData)
+
+ def get_soap_value(self, Action, responseElement, params = ""):
+ root = self.SOAPAction(Action, responseElement, params)
# Get value from device
try:
@@ -183,6 +183,24 @@ def SOAPAction(self, Action, responseElement, params = "", recursive = False):
self._error_report = False
return value
+ def get_soap_element(self, Action, responseElement, params = ""):
+ root = self.SOAPAction(Action, responseElement, params)
+
+ # Get value from device
+ try:
+ value = root.find('.//{http://purenetworks.com/HNAP1/}%s' % (responseElement))
+ except AttributeError:
+ _LOGGER.warning("Unable to find %s in response." % responseElement)
+ return None
+
+ if value is None and self._error_report is False:
+ _LOGGER.warning("Could not find %s in response." % responseElement)
+ self._error_report = True
+ return None
+
+ self._error_report = False
+ return value.getchildren()
+
def fetchMyCgi(self):
"""Fetches statistics from my_cgi.cgi"""
try:
@@ -195,6 +213,23 @@ def fetchMyCgi(self):
lines = response.readlines()
return {line.decode().split(':')[0].strip(): line.decode().split(':')[1].strip() for line in lines}
+ def refresh_modules(self):
+ if self.use_legacy_protocol:
+ # unsupported
+ return
+ try:
+ profiles = self.get_soap_element('GetModuleProfile', 'ModuleProfileList', params = "")
+ for profile in profiles:
+ id = profile.find('{http://purenetworks.com/HNAP1/}ModuleID').text
+ subtype = profile.find('{http://purenetworks.com/HNAP1/}ModuleSubType').text
+ if subtype == 'Electrical Power Meter':
+ self.modules['power'] = '{}'.format(id)
+ if subtype == 'Temperature Monitor':
+ self.modules['temperature'] = '{}'.format(id)
+ except:
+ # use default module ids
+ return
+
@property
def current_consumption(self):
"""Get the current power consumption in Watt."""
@@ -207,7 +242,7 @@ def current_consumption(self):
return 'N/A'
else:
try:
- res = self.SOAPAction('GetCurrentPowerConsumption', 'CurrentConsumption', self.moduleParameters("2"))
+ res = self.get_soap_value('GetCurrentPowerConsumption', 'CurrentConsumption', self.modules['power'])
except:
return 'N/A'
@@ -231,7 +266,7 @@ def total_consumption(self):
res = 'N/A'
try:
- res = self.SOAPAction("GetPMWarningThreshold", "TotalConsumption", self.moduleParameters("2"))
+ res = self.get_soap_value("GetPMWarningThreshold", "TotalConsumption", self.modules['power'])
except:
return 'N/A'
@@ -249,7 +284,7 @@ def total_consumption(self):
def temperature(self):
"""Get the device temperature in celsius."""
try:
- res = self.SOAPAction('GetCurrentTemperature', 'CurrentTemperature', self.moduleParameters("3"))
+ res = self.get_soap_value('GetCurrentTemperature', 'CurrentTemperature', self.modules['temperature'])
except:
res = 'N/A'
@@ -258,7 +293,7 @@ def temperature(self):
@property
def state(self):
"""Get the device state (i.e. ON or OFF)."""
- response = self.SOAPAction('GetSocketSettings', 'OPStatus', self.moduleParameters("1"))
+ response = self.get_soap_value('GetSocketSettings', 'OPStatus', self.modules['socket'])
if response is None:
return 'unknown'
elif response.lower() == 'true':
@@ -277,9 +312,9 @@ def state(self, value):
:param value: Future state (either ON or OFF)
"""
if value.upper() == ON:
- return self.SOAPAction('SetSocketSettings', 'SetSocketSettingsResult', self.controlParameters("1", "true"))
+ return self.get_soap_value('SetSocketSettings', 'SetSocketSettingsResult', self.controlParameters(self.modules['socket'], "true"))
elif value.upper() == OFF:
- return self.SOAPAction('SetSocketSettings', 'SetSocketSettingsResult', self.controlParameters("1", "false"))
+ return self.get_soap_value('SetSocketSettings', 'SetSocketSettingsResult', self.controlParameters(self.modules['socket'], "false"))
else:
raise TypeError("State %s is not valid." % str(value))