Skip to content

Commit 9d8bdd1

Browse files
authored
Merge pull request #1 from trevorwslee/develop
Develop
2 parents 2454028 + 1511bd8 commit 9d8bdd1

31 files changed

+633
-124
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ dumbdisplay_experimental
1111
/_test.py
1212
/_dd.py
1313
/_test.ipynb
14+
/.micropico

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# DumbDisplay MicroPython Library (v0.2.2) #
1+
# DumbDisplay MicroPython Library (v0.3.0)
22

33
DumbDisplay MicroPython Library is a port of the Arduino DumbDisplay Library (https://github.com/trevorwslee/Arduino-DumbDisplay)
44
for the DumbDisplay Android app -- https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay
@@ -105,7 +105,7 @@ l_b.enableFeedback("f", feedback_handler)
105105
l.enableFeedback("fs:rpt50", feedback_handler)
106106
AutoPin('V', AutoPin('H', l_r, l_g, l_b), l).pin(dd)
107107
while True:
108-
dd.delay(1)
108+
dd.sleep(1)
109109
```
110110

111111

@@ -120,15 +120,15 @@ Notes:
120120
121121
122122
123-
## Enjoy! May God bless you! Peace be with you! Jesus loves you! ##
123+
## Enjoy! Peace be with you! May God bless you! Jesus loves you!
124124
125125
126126
127127
# Change History
128128
129129
v0.3.0
130130
- checked Raspberry Pi Pico W WIFI support
131-
- port more options from Arduino DumbDisplay library
131+
- ported more options from Arduino DumbDisplay library
132132
- bug fixes
133133
134134
v0.2.1

dumbdisplay/_ddimpl.py

Lines changed: 101 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,20 @@
1515

1616
_HS_GAP: int = 1000
1717

18+
_RECONNECT_NO_KEEP_ALIVE_MS: int = 5000
19+
_VALIDATE_GAP: int = 1000
20+
_RECONNECTING_VALIDATE_GAP: int = 500
21+
1822

1923
class IOProxy:
2024
def __init__(self, io):
2125
self._io = io
2226
self.data: str = ''
27+
self.last_keep_alive_ms = 0
28+
self.reconnect_keep_alive_ms = 0
29+
self.reconnecting = False
30+
self.reconnect_enabled = False
31+
self.reconnect_RC_id = None
2332
def available(self):
2433
done = '\n' in self.data
2534
while (not done) and self._io.available():
@@ -40,6 +49,48 @@ def read(self) -> str:
4049
# self.data = ''
4150
def print(self, s):
4251
self._io.print(s)
52+
def keepAlive(self):
53+
self.last_keep_alive_ms = time.ticks_ms()
54+
def setReconnectRCId(self, rc_id: str):
55+
### reconnect not working yet
56+
self.reconnect_RC_id = rc_id
57+
self.reconnect_enabled = True
58+
self.reconnect_keep_alive_ms = 0
59+
def validateConnection(self) -> bool:
60+
#print("validateConnection")
61+
diff_ms = -1
62+
need_reconnect = False
63+
if self.last_keep_alive_ms > 0:
64+
now = time.ticks_ms()
65+
diff_ms = now - self.last_keep_alive_ms
66+
if diff_ms > _RECONNECT_NO_KEEP_ALIVE_MS:
67+
need_reconnect = True
68+
if True:
69+
if need_reconnect:
70+
if self.reconnect_enabled:
71+
print("disconnected ... reconnecting ... ", self.reconnect_RC_id, diff_ms)
72+
else:
73+
print("disconnected")
74+
if need_reconnect:
75+
self.reconnecting = True
76+
if need_reconnect and self.reconnect_enabled:
77+
try:
78+
self._io.print("%%>RECON>")
79+
self._io.print(_DD_SID)
80+
self._io.print(":")
81+
self._io.print(self.reconnect_RC_id)
82+
self._io.print("\n")
83+
except:
84+
pass
85+
self.reconnect_keep_alive_ms = self.last_keep_alive_ms
86+
elif self.reconnect_keep_alive_ms > 0:
87+
self.reconnecting = False
88+
#_ConnectVersion = _ConnectVersion + 1;
89+
self.reconnect_keep_alive_ms = 0
90+
self.last_keep_alive_ms = time.ticks_ms()
91+
return not need_reconnect
92+
def isReconnecting(self) -> bool:
93+
return self.reconnecting;
4394

4495
_NextLayerNid: int = 0
4596
def _AllocLayerNid():
@@ -57,14 +108,21 @@ def __init__(self, io: DDInputOutput):
57108
self._connected_iop: IOProxy = None
58109
self._layers: dict[DDLayer] = {}
59110
self._tunnels: dict = {}
60-
111+
self.last_validate_ms = 0
112+
61113
def timeslice(self):
62114
self._checkForFeedback()
63115

64116
def delay(self, seconds: float = 0):
65-
self.delay_ms(seconds * 1000)
117+
'''
118+
use sleep() instead
119+
'''
120+
self.sleep_ms(seconds * 1000)
121+
122+
def sleep(self, seconds: float = 0):
123+
self.sleep_ms(seconds * 1000)
66124

67-
def delay_ms(self, ms: int = 0):
125+
def sleep_ms(self, ms: int = 0):
68126
self._checkForFeedback()
69127
until_ms = int(time.ticks_ms() + ms)
70128
while True:
@@ -90,11 +148,13 @@ def release(self):
90148
self._connected = False
91149
self._connected_iop = None
92150

93-
def toggleDebugLed(self):
151+
# def toggleDebugLed(self):
152+
# pass
153+
# def switchDebugLed(self, on):
154+
# pass
155+
def onDetectedDisconnect(self):
94156
pass
95-
def switchDebugLed(self, on):
96-
pass
97-
def onSendCommandException(self, os_error):
157+
def onSendCommandException(self, error):
98158
pass
99159

100160
def _allocLayerNid(self):
@@ -109,9 +169,8 @@ def _createLayer(self, layer_type: str, *params) -> str:
109169
layer_id = str(self._allocLayerNid())
110170
self._sendCommand(layer_id, "SU", layer_type, *params)
111171
return layer_id
112-
def _reorderLayer(self, layer_id: str, how: str): {
172+
def _reorderLayer(self, layer_id: str, how: str):
113173
self._sendCommand(layer_id, "REORD", how)
114-
}
115174
def _deleteLayer(self, layer_id: str):
116175
self._sendCommand(layer_id, "DEL")
117176
def _onCreatedLayer(self, layer: DDLayer):
@@ -129,7 +188,7 @@ def _connect(self):
129188
if self._connected:
130189
return
131190

132-
self.switchDebugLed(True)
191+
#self.switchDebugLed(True)
133192
self._io.preconnect()
134193

135194
# > ddhello and < ddhello
@@ -139,7 +198,7 @@ def _connect(self):
139198
now = time.ticks_ms()
140199
if now > next_time:
141200
iop.print('ddhello\n')
142-
self.toggleDebugLed()
201+
#self.toggleDebugLed()
143202
next_time = now + _HS_GAP
144203
if iop.available():
145204
data = iop.read()
@@ -156,7 +215,7 @@ def _connect(self):
156215
now = time.ticks_ms()
157216
if now > next_time:
158217
iop.print('>init>:' + _DD_SID + '\n')
159-
self.toggleDebugLed()
218+
#self.toggleDebugLed()
160219
next_time = now + _HS_GAP
161220
if iop.available():
162221
data = iop.read()
@@ -170,12 +229,12 @@ def _connect(self):
170229

171230
self._connected = True
172231
self._compatibility = compatibility
173-
self.switchDebugLed(False)
232+
#self.switchDebugLed(False)
174233
#print('connected:' + str(compatibility))
175234

176235
def _sendSpecial(self, special_type: str, special_id: str, special_command: str, special_data: str):
177236
##print("lt:" + str(special_command) + ":" + str(special_data))#####
178-
self.switchDebugLed(True)
237+
#self.switchDebugLed(True)
179238
self._io.print('%%>')
180239
self._io.print(special_type)
181240
self._io.print('.')
@@ -187,10 +246,10 @@ def _sendSpecial(self, special_type: str, special_id: str, special_command: str,
187246
if special_data != None:
188247
self._io.print(special_data)
189248
self._io.print('\n')
190-
self.switchDebugLed(False)
249+
#self.switchDebugLed(False)
191250
def _sendCommand(self, layer_id: str, command: str, *params):
192251
self._checkForFeedback()
193-
self.switchDebugLed(True)
252+
#self.switchDebugLed(True)
194253
try:
195254
if layer_id != None:
196255
self._io.print(layer_id)
@@ -202,11 +261,12 @@ def _sendCommand(self, layer_id: str, command: str, *params):
202261
else:
203262
self._io.print(',')
204263
self._io.print(params[i])
205-
except OSError as e:
206-
self.switchDebugLed(False)
264+
self._io.print('\n')
265+
except Exception as e:
266+
#self.switchDebugLed(False)
207267
self.onSendCommandException(e)
208-
self._io.print('\n')
209-
self.switchDebugLed(False)
268+
#self._io.print('\n')
269+
#self.switchDebugLed(False)
210270

211271

212272

@@ -215,8 +275,10 @@ def _checkForFeedback(self):
215275
if feedback != None:
216276
if len(feedback) > 0:
217277
if feedback[0:1] == '<':
278+
self._onFeedbackKeepAlive()
218279
if len(feedback) == 1:
219-
self._onFeedbackKeepAlive()
280+
pass
281+
#self._onFeedbackKeepAlive()
220282
else:
221283
#print(feedback)####
222284
if feedback.startswith('<lt.'):
@@ -265,19 +327,30 @@ def _checkForFeedback(self):
265327
except:
266328
pass
267329
def _readFeedback(self) -> str:
330+
if not self._validateConnection():
331+
self.onDetectedDisconnect()
268332
if not self._connected_iop.available():
269333
return None
270334
feedback = self._connected_iop.read()
271335
#self._connected_iop.clear()
272336
return feedback
273337
def _onFeedbackKeepAlive(self):
274-
pass
275-
# def _onFeedback(self, lid, type, x, y):
276-
# layer = self.layers.get(lid)
277-
# if layer != None:
278-
# layer._handleFeedback(type, x, y)
279-
# #print("FB: " + layer.layer_id + '.' + type + ':' + str(x) + ',' + str(y))
280-
338+
if self._connected_iop:
339+
self._connected_iop.keepAlive()
340+
def _validateConnection(self):
341+
if self._connected_iop:
342+
validate_gap = _RECONNECTING_VALIDATE_GAP if self._connected_iop.isReconnecting() else _VALIDATE_GAP
343+
now = time.ticks_ms()
344+
diff_ms = now - self.last_validate_ms
345+
if diff_ms >= validate_gap:
346+
res = self._connected_iop.validateConnection()
347+
self.last_validate_ms = now
348+
else:
349+
res = True
350+
return res
351+
def _setReconnectRCId(self, rc_id: str):
352+
if self._connected_iop:
353+
self._connected_iop.setReconnectRCId(rc_id)
281354
def _createTunnel(self, end_point):
282355
tunnel_id = str(self._allocTunnelNid())
283356
self._sendSpecial("lt", tunnel_id, "connect", end_point)

dumbdisplay/_ddio_socket.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,13 @@ def print(self, s):
4444
while all > count:
4545
try:
4646
count = self.conn.send(data[count:])
47-
except OSError as e:
48-
if e.args[0] == 11:
49-
pass
50-
else:
51-
raise e
47+
except Exception as e:
48+
raise e
49+
# except OSError as e:
50+
# if e.args[0] == 11:
51+
# pass
52+
# else:
53+
# raise e
5254
#self.conn.sendall(data)
5355
def close(self):
5456
if self.conn != None:

dumbdisplay/_ddlayer.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ def __init__(self, dd, layer_id):
3636
def visibility(self, visible):
3737
'''set layer visibility'''
3838
self.dd._sendCommand(self.layer_id, "visible", _DD_BOOL_ARG(visible))
39+
def disabled(self, disabled: bool = True):
40+
'''set layer disabled'''
41+
self.dd._sendCommand(self.layer_id, "disabled", _DD_BOOL_ARG(disabled))
3942
def transparent(self, transparent: bool):
4043
self.dd._sendCommand(self.layer_id, "transparent", _DD_BOOL_ARG(transparent))
4144
def opacity(self, opacity: int):
@@ -73,9 +76,18 @@ def padding(self, left, top = None, right = None, bottom = None):
7376
self.dd._sendCommand(self.layer_id, "padding", str(left), str(top), str(right), str(bottom))
7477
def noPadding(self):
7578
self.dd._sendCommand(self.layer_id, "padding")
76-
def margin(self, left, top, right, bottom):
79+
def margin(self, left, top = None, right = None, bottom = None):
7780
'''see border() for size unit'''
78-
self.dd._sendCommand(self.layer_id, "margin", str(left), str(top), str(right), str(bottom))
81+
if top == None and right == None and bottom == None:
82+
self.dd._sendCommand(self.layer_id, "margin", str(left))
83+
else:
84+
if top == None:
85+
top = left
86+
if right == None:
87+
right = left
88+
if bottom == None:
89+
bottom = top
90+
self.dd._sendCommand(self.layer_id, "margin", str(left), str(top), str(right), str(bottom))
7991
def noMargin(self):
8092
self.dd._sendCommand(self.layer_id, "margin")
8193
def backgroundColor(self, color):

dumbdisplay/_ddlayer_graphical.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def drawChar(self, x, y, char, color, bg_color = "", size = 0):
4646
def drawStr(self, x, y, string, color, bg_color = "", size = 0):
4747
'''
4848
:param bg_color: "" means default
49-
:param size: 0 means defajult
49+
:param size: 0 means default
5050
'''
5151
self.dd._sendCommand(self.layer_id, "drawstr", str(x), str(y), _DD_COLOR_ARG(color), _DD_COLOR_ARG(bg_color), str(size), string)
5252
def drawPixel(self, x, y, color):

0 commit comments

Comments
 (0)