Skip to content

Commit d3bc927

Browse files
committed
Reorganization to support DeviceFactory
1 parent 4210221 commit d3bc927

4 files changed

Lines changed: 51 additions & 20 deletions

File tree

hnap/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
# USA.
1919

2020

21-
from .devices import Motion, Router, Siren, Sound, Water
21+
from .devices import Camera, DeviceFactory, Motion, Router, Siren, Sound, Water
2222
from .soapclient import AuthenticationError, MethodCallError
2323

2424
__all__ = [
2525
"AuthenticationError",
2626
"MethodCallError",
27+
"DeviceFactory",
28+
"Camera",
2729
"Motion",
2830
"Router",
2931
"Siren",

hnap/devices.py

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,44 @@
2424
from .soapclient import MethodCallError, SoapClient
2525

2626

27+
def DeviceFactory(hostname, password, username="Admin", port=80, **kwargs):
28+
device = SoapClient(hostname, password, username, port)
29+
device.authenticate()
30+
info = device.device_info()
31+
32+
module_types = info["ModuleTypes"]
33+
if not isinstance(module_types, list):
34+
module_types = [module_types]
35+
36+
if "Audio Renderer" in module_types:
37+
cls = Siren
38+
# 'Optical Recognition', 'Environmental Sensor', 'Camera']
39+
elif "Camera" in module_types:
40+
cls = Camera
41+
elif "Motion Sensor" in module_types:
42+
cls = Motion
43+
else:
44+
raise TypeError(module_types)
45+
46+
return cls(hostname, password, username=username, port=port, **kwargs)
47+
48+
2749
class _Device(SoapClient):
2850
def __init__(self, *args, **kwargs):
2951
super().__init__(*args, **kwargs)
30-
self._device_info = {}
52+
self._info = None
3153

32-
def login(self):
33-
super().login()
34-
info = dict(self.call('GetDeviceSettings'))
35-
for k in ['@xmlns', 'SOAPActions', 'GetDeviceSettingsResult']:
36-
info.pop(k, None)
54+
def authenticate(self):
55+
super().authenticate()
56+
self._info = self.device_info()
3757

38-
try:
39-
info['ModuleTypes'] = info['ModuleTypes']['string']
40-
except KeyError:
41-
pass
58+
@property
59+
def info(self):
60+
return self._info
4261

43-
self._device_info = info
4462

45-
@property
46-
def device_info(self):
47-
return self._device_info
63+
class Camera(_Device):
64+
pass
4865

4966

5067
class Motion(_Device):

hnap/soapclient.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,14 @@ def call(self, method, **parameters):
138138
res = parsed["soap:Envelope"]["soap:Body"][f"{method}Response"][
139139
f"{method}Result"
140140
]
141+
if res.lower() not in ("ok", "success"):
142+
_LOGGER.error(f"{method} returned {res}")
141143
except KeyError:
142144
_LOGGER.warning(f"Missing {method}Result key")
143-
if res.lower() not in ("ok", "success"):
144-
_LOGGER.error(f"{method} returned {res}")
145145

146146
return parsed["soap:Envelope"]["soap:Body"][f"{method}Response"]
147147

148-
def login(self):
148+
def authenticate(self):
149149
url = self.HNAP_AUTH["url"]
150150
method = self.HNAP_METHOD
151151
data = self._build_method_envelope(
@@ -187,7 +187,19 @@ def login(self):
187187
)
188188

189189
if res["LoginResult"] != "success":
190-
raise AuthenticationError()
190+
raise AuthenticationError(res["LoginResult"])
191+
192+
def device_info(self):
193+
info = dict(self.call("GetDeviceSettings"))
194+
for k in ["@xmlns", "SOAPActions", "GetDeviceSettingsResult"]:
195+
info.pop(k, None)
196+
197+
try:
198+
info["ModuleTypes"] = info["ModuleTypes"]["string"]
199+
except KeyError:
200+
pass
201+
202+
return info
191203

192204
def device_actions(self):
193205
idx = len(self.HNAP1_XMLNS)

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[metadata]
44
name = hnap
5-
version = 0.0.3
5+
version = 0.0.5
66
author = Luis López
77
author_email = luis@cuarentaydos.com
88
description = Python clients for HNAP devices

0 commit comments

Comments
 (0)