-
Notifications
You must be signed in to change notification settings - Fork 0
/
ZSI.py
330 lines (266 loc) · 8.85 KB
/
ZSI.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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
from gpiozero import Button
from signal import pause
from time import sleep, time
import serial as serial
import threading
import queue
import statistics
from enum import Enum
from lcd import Lcd
from buzzer import Buzzer
class Mode(Enum):
START_MODE = '@'
STOP_MODE = '#'
CHANNEL_MODE = '$'
IDLE_MODE = '%'
HOLD_MODE = '^'
POWER_MODE = '&'
class SerialProcess:
def in_Waiting(self):
return self.zigbee_uart.inWaiting()
def flush_Input(self):
self.zigbee_uart.flushInput()
return
def flush_Output(self):
self.zigbee_uart.flushOutput()
return
def __init__(self):
self.zigbee_uart = serial.Serial(port='/dev/ttyAMA0',
baudrate=115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
writeTimeout=5,
rtscts=True,
timeout=5)
if self.zigbee_uart.is_open:
input_queue.put('setchannel '+format(channel, 'X'))
if is_tx():
input_queue.put('setTxPowMode 1 0')
input_queue.put('settxpower ' + format(power, 'X'))
input_queue.put("setTxLength 6")
input_queue.put("setTxPayload 0 0x1b 0x61 0x98 0x00")
else:
input_queue.put("showPayload 1")
input_queue.put('e')
def is_open(self):
return self.zigbee_uart.isOpen()
def close(self):
self.zigbee_uart.close()
def write(self, data):
print("> " + data)
data += '\r\n'
self.zigbee_uart.write(data.encode())
def read(self):
data = self.zigbee_uart.readline().strip().decode('utf8')
return data
def is_tx():
return not jmp.is_pressed
def set_power():
global current_mode, power
if current_mode != Mode.POWER_MODE:
return
input_queue.put('settxpower ' + format(power, 'X'))
current_mode = Mode.HOLD_MODE
buzzer.prog()
lcd.setflash()
def power_mode():
if not is_tx():
return
global current_mode, power
if current_mode == Mode.START_MODE:
return
elif current_mode == Mode.HOLD_MODE:
current_mode = Mode.IDLE_MODE
return
current_mode = Mode.POWER_MODE
power += 1
if power == 9:
power = -8
buzzer.set()
lcd.setflash()
def set_channels():
global current_mode, channel
if current_mode != Mode.CHANNEL_MODE:
return
input_queue.put('setchannel ' + format(channel, 'X'))
current_mode = Mode.HOLD_MODE
buzzer.prog()
lcd.setflash()
def channels():
global current_mode, channel
if current_mode == Mode.START_MODE:
return
elif current_mode == Mode.HOLD_MODE:
current_mode = Mode.IDLE_MODE
return
current_mode = Mode.CHANNEL_MODE
channel += 1
if channel == 27:
channel = 11
buzzer.set()
lcd.setflash()
def stop():
btn_start.when_released = None
global current_mode
if current_mode == Mode.START_MODE:
current_mode = Mode.STOP_MODE
input_queue.put('e')
buzzer.set()
lcd.setflash()
btn_start.when_released = start
def start():
btn_start.when_released = None
global current_mode
if current_mode == Mode.CHANNEL_MODE:
input_queue.put('setchannel ' + format(channel, 'X'))
if is_tx():
input_queue.put('settxpower ' + format(power, 'X'))
if current_mode == Mode.POWER_MODE:
input_queue.put('setchannel ' + format(channel, 'X'))
if is_tx():
input_queue.put('settxpower ' + format(power, 'X'))
if current_mode != Mode.START_MODE:
current_mode = Mode.START_MODE
if is_tx():
input_queue.put('tx 0')
else:
input_queue.put('rx')
buzzer.set()
lcd.setflash()
btn_start.when_released = stop
def io_jobs():
sp.flush_Input()
sp.flush_Output()
rssi = []
lqi = []
while sp.is_open():
if current_mode == Mode.STOP_MODE:
if is_tx():
lcd.redraw(channel, 'STOP', 'N/A', 'N/A', power)
else:
lcd.redraw(channel, 'STOP', 'N/A', 'N/A')
elif current_mode == Mode.POWER_MODE:
if is_tx():
lcd.redraw(channel, 'POWER', 'N/A', 'N/A', power)
else:
lcd.redraw(channel, 'POWER', 'N/A', 'N/A')
elif current_mode == Mode.CHANNEL_MODE:
if is_tx():
lcd.redraw(channel, 'CHANNEL', 'N/A', 'N/A', power)
else:
lcd.redraw(channel, 'CHANNEL', 'N/A', 'N/A')
elif current_mode == Mode.IDLE_MODE:
if is_tx():
lcd.redraw(channel, 'IDLE', 'N/A', 'N/A', power)
else:
lcd.redraw(channel, 'IDLE', 'N/A', 'N/A')
elif current_mode == Mode.START_MODE and output_queue.empty():
if is_tx():
lcd.redraw(channel, 'Transmit', 'N/A', 'N/A', power)
else:
lcd.redraw(channel, 'Receive', 'N/A', 'N/A')
elif not output_queue.empty():
if is_tx():
pass
else:
output_queue.get()
if y >= 250:
if int(x) >= -50:
lcd.redraw(channel, 'Excellent', str(y), str(x))
buzzer.buzz(.1, 2300, 1)
elif int(x) >= -70:
lcd.redraw(channel, 'Good', str(y), str(x))
buzzer.buzz(.1, 2500, 1)
else:
lcd.redraw(channel, 'Good', str(y), str(x))
buzzer.buzz(.1, 2700, 2)
else:
if int(x) <= -89:
lcd.redraw(channel, 'Poor', str(y), str(x))
buzzer.buzz(.1, 3000, 3)
else:
lcd.redraw(channel, 'Bad', str(y), str(x))
buzzer.buzz(.1, 3200, 4)
sleep(.1)
if not input_queue.empty():
data = input_queue.get()
# send it to the serial device
if data == 'e':
sp.flush_Input()
sp.flush_Output()
output_queue.queue.clear()
input_queue.queue.clear()
elif data == 'rx':
sp.flush_Input()
sp.flush_Output()
output_queue.queue.clear()
input_queue.queue.clear()
# lcd.reflash(channel)
sp.write(data)
lcd.setflash()
if sp.in_Waiting() > 1 and current_mode == Mode.START_MODE:
data = sp.read()
if "0x1B 0x61" in data and len(data.split('{')) > 11:
r = (data.split('{')[8][0:3])
l = (data.split('{')[7][0:4])
try:
int(r)
if 4000 != int(data.split('{')[11][2:6]):
continue
rssi.append(r)
lqi.append(int(l, 16))
except ValueError:
continue
if len(rssi) > 10:
sp.flush_Input()
try:
x = statistics.mode(rssi)
y = statistics.mode(lqi)
rssi[:] = []
lqi[:] = []
output_queue.put(data)
print('RSSI:{}, LQI: {}'.format(repr(x), repr(y)))
lcd.setflash()
except statistics.StatisticsError:
continue
if __name__ == '__main__':
# sudo service pigpiod start
# sudo service pigpiod stop
time()
jmp = Button(21)
btn_power = Button(26, hold_time=2)
btn_channel = Button(13, hold_time=2)
btn_start = Button(6)
channel = 11
power = 8
current_mode = ''
input_queue = queue.Queue()
output_queue = queue.Queue()
sp = SerialProcess()
lcd = Lcd()
buzzer = Buzzer()
buzzer.start()
if is_tx():
print("Tx Mode")
else:
print("Rx mode")
while True:
while not sp.is_open():
sp = SerialProcess()
print('port is open')
try:
t = threading.Thread(target=io_jobs)
t.start()
btn_start.when_released = start
btn_channel.when_released = channels
btn_channel.when_held = set_channels
btn_power.when_released = power_mode
btn_power.when_held = set_power
current_mode = Mode.IDLE_MODE
lcd.setflash()
pause()
except Exception:
sp.close()
raise
sp.close()