-
Notifications
You must be signed in to change notification settings - Fork 1
/
python.py
executable file
·241 lines (202 loc) · 7.76 KB
/
python.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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#!/usr/bin/python
from coapthon import defines
from coapthon.messages.option import Option
from coapthon.utils import generate_random_token
from coapthon.client import helperclient
import json
import time
import uuid
# Options
SERVER_HOST = '127.0.0.1'
SERVER_PORT = 5683
# Put your access token
ACCESS_TOKEN = 'YOUR_ACCESS_TOKEN'
# Put your device id
DEVICE_ID = 'CoAP-Python-Test-Device'
DEVICE_COMMAND = 'Test-Command'
DEVICE_NOTIFICATION = 'Test-Notification'
# Message id option
MESSAGE_ID_OPTION = 111
# Register message id option
defines.OptionRegistry.LIST[MESSAGE_ID_OPTION] = \
defines.OptionItem(MESSAGE_ID_OPTION, "MESSAGE_ID", defines.STRING,
False, None)
class HelperClient(helperclient.HelperClient):
"""Helper client"""
def post(self, path, payload, callback=None, timeout=None, *options):
request = self.mk_request(defines.Codes.POST, path)
request.token = generate_random_token(2)
request.payload = payload
for number, value in options:
option = Option()
option.number = number
option.value = value
request.add_option(option)
return self.send_request(request, callback, timeout)
class DeviceHiveCoAPClientException(Exception):
"""DeviceHive CoAP client exception"""
class DeviceHiveCoAPClient(object):
"""DeviceHive CoAP client"""
def __init__(self, host, port, path='/', timeout=None, event_timeout=0.001):
self._host = host
self._port = port
self._path = path
self._timeout = timeout
self._event_timeout = event_timeout
self._events = {}
self._message_id = None
self._event_client = None
self._command_insert_handler = None
self._command_update_handler = None
self._notification_handler = None
self._event_request()
def _client(self):
return HelperClient(server=(self._host, self._port))
def _event_request(self):
self._event_client = self._client()
self._event_client.observe(self._path, self._event_callback,
self._timeout)
def _event_callback(self, response):
if response.payload is None:
return
payload = self._decode_response_payload(response.payload)
if self._message_id is None:
self._message_id = payload['id']
return
request_id = payload.get('requestId')
if request_id is not None:
self._events[request_id] = payload
return
action = payload['action']
if action == 'command/insert' \
and self._command_insert_handler is not None:
self._command_insert_handler(self, payload['command'])
if action == 'command/update' \
and self._command_update_handler is not None:
self._command_update_handler(self, payload['command'])
if action == 'notification/insert' \
and self._notification_handler is not None:
self._notification_handler(self, payload['notification'])
@staticmethod
def _decode_response_payload(payload):
return json.loads(payload)
@staticmethod
def _encode_request_payload(payload):
return json.dumps(payload)
def _wait_message_id(self):
while self._message_id is None:
time.sleep(self._event_timeout)
def _wait_event(self, request_id):
while True:
time.sleep(self._event_timeout)
event = self._events.get(request_id)
if event is not None:
del self._events[request_id]
return event
def _message_id_request(self, payload):
self._wait_message_id()
request_id = str(uuid.uuid4())
payload['requestId'] = request_id
payload = self._encode_request_payload(payload)
request_client = self._client()
def response_callback(_):
request_client.stop()
request_client.post(self._path, payload, response_callback,
self._timeout, (MESSAGE_ID_OPTION,
self._message_id))
return request_id
def _wait_message_id_request(self, payload):
request_id = self._message_id_request(payload)
payload = self._wait_event(request_id)
if payload['status'] != 'success':
raise DeviceHiveCoAPClientException(
'response code: %s, error: %s' % (payload['code'],
payload['error']))
return payload
def authorize(self, access_token):
payload = {
'action': 'authenticate',
'token': access_token,
}
self._wait_message_id_request(payload)
def create_device(self, device_id):
payload = {
'action': 'device/save',
'deviceId': device_id,
'device': {
'name': device_id
}
}
self._wait_message_id_request(payload)
def send_command(self, device_id, command_name):
payload = {
'action': 'command/insert',
'deviceId': device_id,
'command': {
'command': command_name
}
}
return self._wait_message_id_request(payload)['command']['id']
def update_command(self, device_id, command_id, status, result):
payload = {
'action': 'command/update',
'deviceId': device_id,
'commandId': command_id,
'command': {
'status': status,
'result': result
}
}
self._wait_message_id_request(payload)
def send_notification(self, device_id, notification_name, params):
payload = {
'action': 'notification/insert',
'deviceId': device_id,
'notification': {
'notification': notification_name,
'parameters': params
}
}
return self._wait_message_id_request(payload)['notification']['id']
def subscribe_command_insert(self, device_id, handler):
self._command_insert_handler = handler
payload = {
'action': 'command/subscribe',
'deviceId': device_id,
}
return self._wait_message_id_request(payload)['subscriptionId']
def subscribe_command_update(self, device_id, handler):
self._command_update_handler = handler
payload = {
'action': 'command/subscribe',
'deviceId': device_id,
'returnUpdatedCommands': True
}
return self._wait_message_id_request(payload)['subscriptionId']
def subscribe_notification(self, device_id, handler):
self._notification_handler = handler
payload = {
'action': 'notification/subscribe',
'deviceId': device_id
}
return self._wait_message_id_request(payload)['subscriptionId']
def stop(self):
self._event_client.stop()
def handle_command_insert(_, command):
print('---COMMAND-INSERTED---')
print(command)
def handle_command_update(_, command):
print('---COMMAND-UPDATED---')
print(command)
def handle_notification(_, notification):
print('---NOTIFICATION---')
print(notification)
dh_client = DeviceHiveCoAPClient(SERVER_HOST, SERVER_PORT)
dh_client.authorize(ACCESS_TOKEN)
dh_client.create_device(DEVICE_ID)
dh_client.subscribe_command_insert(DEVICE_ID, handle_command_insert)
dh_client.subscribe_command_update(DEVICE_ID, handle_command_update)
dh_client.subscribe_notification(DEVICE_ID, handle_notification)
cmd_id = dh_client.send_command(DEVICE_ID, DEVICE_COMMAND)
dh_client.update_command(DEVICE_ID, cmd_id, 'updated', {'result': True})
dh_client.send_notification(DEVICE_ID, DEVICE_NOTIFICATION, {'param': 'value'})