1
- # https://github.com/MrYsLab/s3-extend/blob/master/s3_extend/gateways/arduino_gateway.pys
2
- # 作为node运行
3
- # 上报数据 关注: publish_payload,callback
4
- # python3.7
5
1
import argparse
6
2
import asyncio
7
3
import logging
8
4
import pathlib
9
5
import sys
10
6
import functools
11
7
12
- from codelab_adapter .utils import TokenBucket
13
-
8
+ from codelab_adapter .utils import TokenBucket
14
9
15
10
from pymata_express .private_constants import PrivateConstants
16
11
from pymata_express .pymata_express import PymataExpress
@@ -25,10 +20,12 @@ class ArduinoGateway(GatewayBaseAIO):
25
20
26
21
# NOTE: This class requires the use of Python 3.7 or above
27
22
28
- # serial_port = None
29
-
30
- def __init__ (self , event_loop = None , com_port = None ,
31
- arduino_instance_id = None , keep_alive = False , log = True ):
23
+ def __init__ (self ,
24
+ event_loop = None ,
25
+ com_port = None ,
26
+ arduino_instance_id = None ,
27
+ keep_alive = False ,
28
+ log = True ):
32
29
self .bucket = TokenBucket (10 , 5 )
33
30
self .EXTENSION_ID = "eim/arduino"
34
31
# set the event loop to be used. accept user's if provided
@@ -47,8 +44,9 @@ def __init__(self, event_loop=None, com_port=None,
47
44
com_port = com_port )
48
45
# if user wants to set an instance id, then pass it in
49
46
elif arduino_instance_id :
50
- self .arduino = PymataExpress (loop = self .event_loop ,
51
- arduino_instance_id = arduino_instance_id )
47
+ self .arduino = PymataExpress (
48
+ loop = self .event_loop ,
49
+ arduino_instance_id = arduino_instance_id )
52
50
# default settings
53
51
else :
54
52
self .arduino = PymataExpress (loop = self .event_loop )
@@ -65,11 +63,10 @@ def __init__(self, event_loop=None, com_port=None,
65
63
66
64
# Initialize the parent
67
65
super ().__init__ ()
68
-
69
66
70
67
self .first_analog_pin = self .arduino .first_analog_pin
71
68
self .keep_alive = keep_alive
72
-
69
+
73
70
# self.event_loop.create_task(pub_notification_coroutine)
74
71
75
72
def init_pins_dictionary (self ):
@@ -80,7 +77,8 @@ def init_pins_dictionary(self):
80
77
81
78
NOTE: that this a a non-asyncio method.
82
79
"""
83
- report = self .event_loop .run_until_complete (self .arduino .get_capability_report ())
80
+ report = self .event_loop .run_until_complete (
81
+ self .arduino .get_capability_report ())
84
82
x = 0
85
83
pin = 0
86
84
while x < len (report ):
@@ -98,14 +96,14 @@ def init_pins_dictionary(self):
98
96
# set up entry for i2c as pin 200 ( a pseudo pin number)
99
97
self .pins_dictionary [200 ] = GatewayBaseAIO .DIGITAL_INPUT_MODE
100
98
101
-
102
99
async def digital_write (self , topic , payload ):
103
100
"""
104
101
This method performs a digital write
105
102
:param topic: message topic
106
103
:param payload content: {"command": "digital_write", "pin": “PIN”, "value": “VALUE”}
107
104
"""
108
- await self .arduino .digital_write (payload ['content' ]["pin" ], payload ['content' ]['value' ])
105
+ await self .arduino .digital_write (payload ['content' ]["pin" ],
106
+ payload ['content' ]['value' ])
109
107
110
108
async def disable_analog_reporting (self , topic , payload ):
111
109
"""
@@ -157,7 +155,8 @@ async def i2c_read(self, topic, payload):
157
155
158
156
await self .arduino .i2c_read (payload ['content' ]['addr' ],
159
157
payload ['content' ]['register' ],
160
- payload ['content' ]['number_of_bytes' ], callback = self .i2c_callback )
158
+ payload ['content' ]['number_of_bytes' ],
159
+ callback = self .i2c_callback )
161
160
162
161
async def i2c_write (self , topic , payload ):
163
162
"""
@@ -172,7 +171,8 @@ async def i2c_write(self, topic, payload):
172
171
"addr": “I2C ADDRESS, "register": “I2C REGISTER”,
173
172
"data": [“DATA IN LIST FORM”]}
174
173
"""
175
- await self .arduino .i2c_write (payload ['content' ]['addr' ], payload ['content' ]['data' ])
174
+ await self .arduino .i2c_write (payload ['content' ]['addr' ],
175
+ payload ['content' ]['data' ])
176
176
177
177
async def play_tone (self , topic , payload ):
178
178
"""
@@ -198,7 +198,8 @@ async def pwm_write(self, topic, payload):
198
198
"tag":”TAG”,
199
199
“value”: “VALUE”}
200
200
"""
201
- await self .arduino .analog_write (payload ['content' ]["pin" ], payload ['content' ]['value' ])
201
+ await self .arduino .analog_write (payload ['content' ]["pin" ],
202
+ payload ['content' ]['value' ])
202
203
203
204
async def servo_position (self , topic , payload ):
204
205
"""
@@ -211,7 +212,8 @@ async def servo_position(self, topic, payload):
211
212
"pin": “PIN”,'tag': 'servo',
212
213
“position”: “POSITION”}
213
214
"""
214
- await self .arduino .servo_write (payload ['content' ]["pin" ], payload ['content' ]["position" ])
215
+ await self .arduino .servo_write (payload ['content' ]["pin" ],
216
+ payload ['content' ]["position" ])
215
217
216
218
async def set_mode_analog_input (self , topic , payload ):
217
219
"""
@@ -222,7 +224,8 @@ async def set_mode_analog_input(self, topic, payload):
222
224
pin = payload ['content' ]["pin" ]
223
225
self .pins_dictionary [pin + self .first_analog_pin ][GatewayBaseAIO .PIN_MODE ] = \
224
226
GatewayBaseAIO .ANALOG_INPUT_MODE
225
- await self .arduino .set_pin_mode_analog_input (pin , self .analog_input_callback )
227
+ await self .arduino .set_pin_mode_analog_input (
228
+ pin , self .analog_input_callback )
226
229
227
230
async def set_mode_digital_input (self , topic , payload ):
228
231
"""
@@ -231,8 +234,10 @@ async def set_mode_digital_input(self, topic, payload):
231
234
:param payload content: {"command": "set_mode_digital_input", "pin": “PIN”, "tag":”TAG” }
232
235
"""
233
236
pin = payload ['content' ]["pin" ]
234
- self .pins_dictionary [pin ][GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .DIGITAL_INPUT_MODE
235
- await self .arduino .set_pin_mode_digital_input (pin , self .digital_input_callback )
237
+ self .pins_dictionary [pin ][
238
+ GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .DIGITAL_INPUT_MODE
239
+ await self .arduino .set_pin_mode_digital_input (
240
+ pin , self .digital_input_callback )
236
241
237
242
async def set_mode_digital_input_pullup (self , topic , payload ):
238
243
"""
@@ -241,8 +246,10 @@ async def set_mode_digital_input_pullup(self, topic, payload):
241
246
:param payload content: message payload
242
247
"""
243
248
pin = payload ['content' ]["pin" ]
244
- self .pins_dictionary [pin ][GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .DIGITAL_INPUT_PULLUP_MODE
245
- await self .arduino .set_pin_mode_digital_input_pullup (pin , self .digital_input_callback )
249
+ self .pins_dictionary [pin ][
250
+ GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .DIGITAL_INPUT_PULLUP_MODE
251
+ await self .arduino .set_pin_mode_digital_input_pullup (
252
+ pin , self .digital_input_callback )
246
253
247
254
async def set_mode_digital_output (self , topic , payload ):
248
255
"""
@@ -251,7 +258,8 @@ async def set_mode_digital_output(self, topic, payload):
251
258
:param payload content: {"command": "set_mode_digital_output", "pin": PIN, "tag":”TAG” }
252
259
"""
253
260
pin = payload ['content' ]["pin" ]
254
- self .pins_dictionary [pin ][GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .DIGITAL_OUTPUT_MODE
261
+ self .pins_dictionary [pin ][
262
+ GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .DIGITAL_OUTPUT_MODE
255
263
await self .arduino .set_pin_mode_digital_output (pin )
256
264
257
265
async def set_mode_i2c (self , topic , payload ):
@@ -260,7 +268,8 @@ async def set_mode_i2c(self, topic, payload):
260
268
:param topic: message topic
261
269
:param payload content: {"command": "set_mode_i2c"}
262
270
"""
263
- self .pins_dictionary [200 ][GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .I2C_MODE
271
+ self .pins_dictionary [200 ][
272
+ GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .I2C_MODE
264
273
await self .arduino .set_pin_mode_i2c ()
265
274
266
275
async def set_mode_pwm (self , topic , payload ):
@@ -270,7 +279,8 @@ async def set_mode_pwm(self, topic, payload):
270
279
:param payload content: {"command": "set_mode_pwm", "pin": “PIN”, "tag":”TAG” }
271
280
"""
272
281
pin = payload ['content' ]["pin" ]
273
- self .pins_dictionary [pin ][GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .PWM_OUTPUT_MODE
282
+ self .pins_dictionary [pin ][
283
+ GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .PWM_OUTPUT_MODE
274
284
await self .arduino .set_pin_mode_pwm (pin )
275
285
276
286
async def set_mode_servo (self , topic , payload ):
@@ -280,7 +290,8 @@ async def set_mode_servo(self, topic, payload):
280
290
:param payload content: {"command": "set_mode_servo", "pin": “PIN”, "tag":”TAG” }
281
291
"""
282
292
pin = payload ['content' ]["pin" ]
283
- self .pins_dictionary [pin ][GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .SERVO_MODE
293
+ self .pins_dictionary [pin ][
294
+ GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .SERVO_MODE
284
295
await self .arduino .set_pin_mode_servo (pin )
285
296
286
297
async def set_mode_sonar (self , topic , payload ):
@@ -293,10 +304,14 @@ async def set_mode_sonar(self, topic, payload):
293
304
294
305
trigger = payload ['content' ]["trigger_pin" ]
295
306
echo = payload ['content' ]["echo_pin" ]
296
- self .pins_dictionary [trigger ][GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .SONAR_MODE
297
- self .pins_dictionary [echo ][GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .SONAR_MODE
307
+ self .pins_dictionary [trigger ][
308
+ GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .SONAR_MODE
309
+ self .pins_dictionary [echo ][
310
+ GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .SONAR_MODE
298
311
299
- await self .arduino .set_pin_mode_sonar (trigger , echo , cb = self .sonar_callback )
312
+ await self .arduino .set_pin_mode_sonar (trigger ,
313
+ echo ,
314
+ cb = self .sonar_callback )
300
315
301
316
async def set_mode_stepper (self , topic , payload ):
302
317
"""
@@ -307,9 +322,11 @@ async def set_mode_stepper(self, topic, payload):
307
322
"steps_per_revolution": “NUMBER OF STEPS”}
308
323
"""
309
324
for pin in payload ['content' ]['pins' ]:
310
- self .pins_dictionary [pin ][GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .STEPPER_MODE
311
- await self .arduino .set_pin_mode_stepper (payload ['content' ]['steps_per_revolution' ],
312
- payload ['content' ]['pins' ])
325
+ self .pins_dictionary [pin ][
326
+ GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .STEPPER_MODE
327
+ await self .arduino .set_pin_mode_stepper (
328
+ payload ['content' ]['steps_per_revolution' ],
329
+ payload ['content' ]['pins' ])
313
330
314
331
async def set_mode_tone (self , topic , payload ):
315
332
"""
@@ -318,7 +335,8 @@ async def set_mode_tone(self, topic, payload):
318
335
:param payload content:{"command": "set_mode_tone", "pin": “PIN”, "tag":”TAG” }
319
336
"""
320
337
pin = payload ['content' ]["pin" ]
321
- self .pins_dictionary [pin ][GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .TONE_MODE
338
+ self .pins_dictionary [pin ][
339
+ GatewayBaseAIO .PIN_MODE ] = GatewayBaseAIO .TONE_MODE
322
340
await self .arduino .set_pin_mode_tone (pin )
323
341
324
342
async def stepper_write (self , topic , payload ):
@@ -340,18 +358,27 @@ async def digital_input_callback(self, data):
340
358
"""
341
359
# data = [pin, current reported value, pin_mode, timestamp]
342
360
self .pins_dictionary [data [0 ]][GatewayBaseAIO .LAST_VALUE ] = data [1 ]
343
-
361
+
344
362
message = self .message_template ()
345
- message ["payload" ]["content" ] = {'report' : 'digital_input' , 'pin' : data [0 ],
346
- 'value' : data [1 ], 'timestamp' : data [3 ]}
363
+ message ["payload" ]["content" ] = {
364
+ 'report' : 'digital_input' ,
365
+ 'pin' : data [0 ],
366
+ 'value' : data [1 ],
367
+ 'timestamp' : data [3 ]
368
+ }
347
369
await self .publish_with_tokenbucket (message )
348
370
349
371
async def analog_input_callback (self , data ):
350
372
# data = [pin, current reported value, pin_mode, timestamp]
351
- self .pins_dictionary [data [0 ] + self .arduino .first_analog_pin ][GatewayBaseAIO .LAST_VALUE ] = data [1 ]
373
+ self .pins_dictionary [data [0 ] + self .arduino .first_analog_pin ][
374
+ GatewayBaseAIO .LAST_VALUE ] = data [1 ]
352
375
message = self .message_template ()
353
- message ["payload" ]["content" ] = {'report' : 'analog_input' , 'pin' : data [0 ],
354
- 'value' : data [1 ], 'timestamp' : data [3 ]}
376
+ message ["payload" ]["content" ] = {
377
+ 'report' : 'analog_input' ,
378
+ 'pin' : data [0 ],
379
+ 'value' : data [1 ],
380
+ 'timestamp' : data [3 ]
381
+ }
355
382
await self .publish_with_tokenbucket (message )
356
383
357
384
async def i2c_callback (self , data ):
@@ -377,7 +404,10 @@ async def sonar_callback(self, data):
377
404
"""
378
405
self .pins_dictionary [data [0 ]][GatewayBaseAIO .LAST_VALUE ] = data [1 ]
379
406
message = self .message_template ()
380
- message ["payload" ]["content" ] = {'report' : 'sonar_data' , 'value' : data [1 ]}
407
+ message ["payload" ]["content" ] = {
408
+ 'report' : 'sonar_data' ,
409
+ 'value' : data [1 ]
410
+ }
381
411
await self .publish_with_tokenbucket (message )
382
412
383
413
def my_handler (self , tp , value , tb ):
@@ -390,7 +420,7 @@ def my_handler(self, tp, value, tb):
390
420
"""
391
421
self .logger .exception ("Uncaught exception: {0}" .format (str (value )))
392
422
393
- async def publish_with_tokenbucket (self ,message ):
423
+ async def publish_with_tokenbucket (self , message ):
394
424
if self .bucket .consume (1 ):
395
425
await self .publish (message )
396
426
@@ -402,37 +432,30 @@ async def main(self):
402
432
if self .keep_alive :
403
433
await self .arduino .keep_alive ()
404
434
# sit in an endless loop to receive protocol messages
405
- await self .receive_loop () # pub_notification should after receive_loop
435
+ await self .receive_loop () # pub_notification should after receive_loop
406
436
# 在此之后才能发送,publisher先建立起来,消息可以后发
437
+
407
438
# The following methods and are called
408
439
# by the gateway base class in its incoming_message_processing
409
440
# method. They overwrite the default methods in the gateway_base.
410
441
411
-
412
442
# noinspection DuplicatedCode
413
443
def run (self ):
414
444
# get the event loop
415
445
# this is for python 3.8
416
446
if sys .platform == 'win32' :
417
- asyncio .set_event_loop_policy (asyncio .WindowsSelectorEventLoopPolicy ())
418
-
419
- # loop = asyncio.get_event_loop()
420
-
447
+ asyncio .set_event_loop_policy (
448
+ asyncio .WindowsSelectorEventLoopPolicy ())
421
449
422
- # replace with the name of your class
423
- # app = ArduinoGateway(event_loop=loop)
424
- # app.pub_notification("Arduino found and connected to port!")
425
450
try :
426
- # 0.5秒后发,如果成功的话
427
- self .event_loop .create_task (self .pub_notification (f'Arduino UNO Connected!' , type = "SUCCESS" ))
428
- self .event_loop .run_until_complete (self .main ()) # thread 之后才允许通信
451
+ self .event_loop .create_task (
452
+ self .pub_notification (f'Arduino UNO Connected!' ,
453
+ type = "SUCCESS" ))
454
+ self .event_loop .run_until_complete (self .main ())
429
455
self .logger .debug ("arduino thread end" )
430
456
self .event_loop .run_until_complete (self .arduino .shutdown ())
431
457
except (KeyboardInterrupt , asyncio .CancelledError , RuntimeError ):
432
458
pass
433
- # self.event_loop.stop()
434
- # self.event_loop.close()
435
- # sys.exit(0)
436
459
437
460
438
461
export = ArduinoGateway
0 commit comments