Skip to content

Commit 0f7eb36

Browse files
committed
Handle ModuleID and Controller parameters automatically
1 parent f99b12f commit 0f7eb36

1 file changed

Lines changed: 41 additions & 16 deletions

File tree

hnap/devices.py

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import logging
2323
from datetime import datetime
2424
from enum import Enum
25-
from typing import List
2625

2726
from .soapclient import MethodCallError, SoapClient
2827

@@ -66,7 +65,7 @@ def DeviceFactory(
6665

6766

6867
class Device:
69-
REQUIRED_MODULE_TYPES: List[str] = []
68+
MODULE_TYPE: str
7069

7170
def __init__(
7271
self,
@@ -80,6 +79,34 @@ def __init__(
8079
self.client = client or SoapClient(
8180
hostname=hostname, password=password, username=username, port=port
8281
)
82+
self._info = None
83+
self._module_id = None
84+
self._controller = None
85+
86+
@property
87+
def info(self):
88+
if not self._info:
89+
self._info = self.client.device_info()
90+
91+
return self._info
92+
93+
@property
94+
def module_id(self):
95+
if not self._module_id:
96+
self._module_id = self.info["ModuleTypes"].find(self.MODULE_TYPE) + 1
97+
98+
return self._module_id
99+
100+
@property
101+
def controller(self):
102+
# NOTE: not sure about this
103+
return self.module_id
104+
105+
def call(self, *args, **kwargs):
106+
kwargs["ModuleID"] = kwargs.get("ModuleID") or self.module_id
107+
kwargs["Controller"] = kwargs.get("Controller") or self.controller
108+
109+
return self.client.call(*args, **kwargs)
83110

84111
# def get_info(self):
85112
# info = self.client.device_info()
@@ -99,7 +126,7 @@ def __init__(
99126

100127

101128
class Camera(Device):
102-
REQUIRED_MODULE_TYPES = ["Camera"]
129+
MODULE_TYPE = "Camera"
103130

104131
def __init__(self, *args, **kwargs):
105132
super().__init__(*args, **kwargs)
@@ -119,7 +146,7 @@ def picture_url(self):
119146

120147

121148
class Motion(Device):
122-
REQUIRED_MODULE_TYPES = ["Motion Sensor"]
149+
MODULE_TYPE = "Motion Sensor"
123150

124151
def __init__(self, *args, **kwargs):
125152
super().__init__(*args, **kwargs)
@@ -128,7 +155,7 @@ def __init__(self, *args, **kwargs):
128155
@property
129156
def backoff(self):
130157
if self._backoff is None:
131-
resp = self.client.call("GetMotionDetectorSettings", ModuleID=1)
158+
resp = self.call("GetMotionDetectorSettings")
132159
try:
133160
self._backoff = int(resp["Backoff"])
134161
except (KeyError, ValueError, TypeError):
@@ -156,7 +183,7 @@ def backoff(self):
156183

157184
@auth_required
158185
def get_latest_detection(self):
159-
res = self.client.call("GetLatestDetection", ModuleID=1)
186+
res = self.call("GetLatestDetection")
160187
return datetime.fromtimestamp(float(res["LatestDetectTime"]))
161188

162189
@auth_required
@@ -170,11 +197,11 @@ def is_active(self):
170197
class Router(Device):
171198
# NOT tested
172199
# See https://github.com/waffelheld/dlink-device-tracker/blob/master/custom_components/dlink_device_tracker/dlink_hnap.py#L95 # noqa: E501
173-
REQUIRED_MODULE_TYPES = ["check-module-types-for-router"]
200+
MODULE_TYPE = "check-module-types-for-router"
174201

175202
@auth_required
176203
def get_clients(self):
177-
res = self.client.call("GetClientInfo", ModuleID=1, Controller=1)
204+
res = self.call("GetClientInfo")
178205
clients = res["ClientInfoLists"]["ClientInfo"]
179206

180207
# Filter out offline clients
@@ -210,19 +237,17 @@ def fromstring(cls, s):
210237

211238

212239
class Siren(Device):
213-
REQUIRED_MODULE_TYPES = ["Audio Renderer"]
240+
MODULE_TYPE = "Audio Renderer"
214241

215242
@auth_required
216243
def is_playing(self):
217-
res = self.client.call("GetSirenAlarmSettings", ModuleID=1, Controller=1)
244+
res = self.call("GetSirenAlarmSettings")
218245
return res["IsSounding"] == "true"
219246

220247
@auth_required
221248
def play(self, sound=SirenSound.EMERGENCY, volume=100, duration=60):
222-
ret = self.client.call(
249+
ret = self.call(
223250
"SetSoundPlay",
224-
ModuleID=1,
225-
Controller=1,
226251
SoundType=sound.value,
227252
Volume=volume,
228253
Duration=duration,
@@ -236,17 +261,17 @@ def beep(self, volume=100, duration=1):
236261

237262
@auth_required
238263
def stop(self):
239-
ret = self.client.call("SetAlarmDismissed", ModuleID=1, Controller=1)
264+
ret = self.call("SetAlarmDismissed")
240265

241266
if ret["SetAlarmDismissedResult"] != "OK":
242267
raise MethodCallError(f"Unable to stop. Response: {ret}")
243268

244269

245270
class Water(Device):
246271
# NOT tested
247-
REQUIRED_MODULE_TYPES = ["check-module-types-for-water-detector"]
272+
MODULE_TYPE = "check-module-types-for-water-detector"
248273

249274
@auth_required
250275
def is_active(self):
251-
ret = self.client.call("GetWaterDetectorState", ModuleID=1)
276+
ret = self.call("GetWaterDetectorState")
252277
return ret.get("IsWater") == "true"

0 commit comments

Comments
 (0)