-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
zwaveplugin.py
187 lines (153 loc) · 4.94 KB
/
zwaveplugin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
"""
Fauxmo plugin that provides access to services exposing by Z-Wave REST API.
Tested on z-way v2.3.8 / SmartHomeUI v1.9.0.
For zway-server see https://z-wave.me/z-way/
See "Z-Way Essentials" doc for API details.
Added by Jorge Rivera in June 2019.
Uses `requests` for a simpler api.
Example config:
```
{
"FAUXMO": {
"ip_address": "auto"
},
"PLUGINS": {
"ZwavePlugin": {
"path": "/path/to/zwaveplugin.py",
"zwave_host" : "localhost",
"zwave_port" : "8083",
"zwave_user" : "admin",
"zwave_pass" : "your_pass",
"fake_state" : false,
"DEVICES": [
{
"name" : "hall light",
"device" : "HTTP_Device_switchBinary_62",
"port" : 49918
},
{
"name" : "bath light",
"device" : "HTTP_Device_switchBinary_63",
"port" : 49919
}
]
}
}
}
```
Dependencies:
requests==2.28.2
"""
from __future__ import annotations
import requests
from fauxmo import logger
from fauxmo.plugins import FauxmoPlugin
ZwavePlugin_version = "v0.3"
response_ok = '{"data":null,"code":200,"message":"200 OK","error":null}'
class ZwavePlugin(FauxmoPlugin):
"""Fauxmo Plugin for Z-WAVE (zway-server) REST API.
Allows users to specify Z-Wave services in their config.json and
toggle these with the Echo. While this can be done with Z-Wave
REST API as well (example included), I find it easier to use the Python
API.
"""
def __init__(
self,
*,
name: str,
port: int,
device: str,
zwave_host: str = "localhost",
zwave_port: int = 8083,
zwave_user: str = "admin",
zwave_pass: str = None,
fake_state: bool = False,
state: str = "unknown",
) -> None:
"""Initialize a ZwaveAPIPlugin instance.
Args:
zwave_host: IP address or dns name of zway-server
zwave_port: TCP port running zway-server (default 8083)
zwave_user: Zwave user
zwave_pass: Zwave user password
fake_state: Set to true for it does not exec a query for status,
it returns the previous status stored
state: Initial device status
"""
self.zwave_host = zwave_host
self.zwave_port = zwave_port
self.zwave_user = zwave_user
self.zwave_pass = zwave_pass
self.zwave_device = device
self.fake_state = fake_state
logger.info(
f"ZwavePlugin: {ZwavePlugin_version} "
+ "name: {name} device: {device} "
+ "port: {port} fake_state: {fake_state}"
)
super().__init__(name=name, port=port)
def _ZwaveCmd(self, cmd: str) -> bool:
url = (
"http://"
+ self.zwave_host
+ ":"
+ str(self.zwave_port)
+ "/ZAutomation/api/v1/devices/"
+ self.zwave_device
+ "/command/"
+ cmd
)
logger.info(f"ZwavePlugin: Getting {url} ")
try:
resp = requests.get(url, auth=(self.zwave_user, self.zwave_pass))
except Exception as e:
logger.error(f"ZwavePlugin: {e}")
return False
if resp.status_code == 200:
if resp.text == response_ok:
self.state = cmd
return True
logger.error(f"ZwavePlugin: {resp.status_code} {resp.text} ")
return False
def on(self) -> bool:
"""Run on command.
Returns:
True if command seems to have run without error.
"""
return self._ZwaveCmd("on")
def off(self) -> bool:
"""Run off command.
Returns:
True if command seems to have run without error.
"""
return self._ZwaveCmd("off")
def get_state(self) -> str:
"""Get device state.
Returns:
"on", "off", or "unknown"
If fake_state is set to true, it does not exec a query for status,
it returns the previous status stored.
"""
if self.fake_state:
logger.info(f"ZwavePlugin: return fake {self.state} ")
return self.state
url = (
"http://"
+ self.zwave_host
+ ":"
+ str(self.zwave_port)
+ "/JS/Run/controller.devices.get('"
+ self.zwave_device
+ "').get('metrics:level')"
)
logger.info(f"ZwavePlugin: Getting {url} ")
try:
resp = requests.get(url, auth=(self.zwave_user, self.zwave_pass))
except Exception as e:
logger.error(f"ZwavePlugin: {e}")
return "unknown"
if resp.status_code == 200:
if resp.text == '"off"' or resp.text == '"on"':
return resp.text.strip('"')
logger.error(f"ZwavePlugin: {resp.status_code} {resp.text} ")
return "unknown"