Skip to content

Commit bef6622

Browse files
committed
going for v0.3.0
1 parent b580c30 commit bef6622

8 files changed

Lines changed: 151 additions & 57 deletions

File tree

dumbdisplay/_ddimpl.py

Lines changed: 75 additions & 16 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,46 @@ 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):
60+
#print("validateConnection")
61+
need_reconnect = False
62+
if self.last_keep_alive_ms > 0:
63+
now = time.ticks_ms()
64+
diff_ms = now - self.last_keep_alive_ms
65+
if diff_ms > _RECONNECT_NO_KEEP_ALIVE_MS:
66+
need_reconnect = True
67+
if True:
68+
if need_reconnect:
69+
if self.reconnect_enabled:
70+
print("disconnected ... reconnecting ... ", self.reconnect_RC_id)
71+
else:
72+
print("disconnected")
73+
if need_reconnect:
74+
self.reconnecting = True
75+
if need_reconnect and self.reconnect_enabled:
76+
try:
77+
self._io.print("%%>RECON>")
78+
self._io.print(_DD_SID)
79+
self._io.print(":")
80+
self._io.print(self.reconnect_RC_id)
81+
self._io.print("\n")
82+
except:
83+
pass
84+
self.reconnect_keep_alive_ms = self.last_keep_alive_ms
85+
elif self.reconnect_keep_alive_ms > 0:
86+
self.reconnecting = False
87+
#_ConnectVersion = _ConnectVersion + 1;
88+
self.reconnect_keep_alive_ms = 0
89+
self.last_keep_alive_ms = time.ticks_ms()
90+
def isReconnecting(self) -> bool:
91+
return self.reconnecting;
4392

4493
_NextLayerNid: int = 0
4594
def _AllocLayerNid():
@@ -57,7 +106,8 @@ def __init__(self, io: DDInputOutput):
57106
self._connected_iop: IOProxy = None
58107
self._layers: dict[DDLayer] = {}
59108
self._tunnels: dict = {}
60-
109+
self.last_validate_ms = 0
110+
61111
def timeslice(self):
62112
self._checkForFeedback()
63113

@@ -100,7 +150,7 @@ def toggleDebugLed(self):
100150
pass
101151
def switchDebugLed(self, on):
102152
pass
103-
def onSendCommandException(self, os_error):
153+
def onSendCommandException(self, error):
104154
pass
105155

106156
def _allocLayerNid(self):
@@ -115,9 +165,8 @@ def _createLayer(self, layer_type: str, *params) -> str:
115165
layer_id = str(self._allocLayerNid())
116166
self._sendCommand(layer_id, "SU", layer_type, *params)
117167
return layer_id
118-
def _reorderLayer(self, layer_id: str, how: str): {
168+
def _reorderLayer(self, layer_id: str, how: str):
119169
self._sendCommand(layer_id, "REORD", how)
120-
}
121170
def _deleteLayer(self, layer_id: str):
122171
self._sendCommand(layer_id, "DEL")
123172
def _onCreatedLayer(self, layer: DDLayer):
@@ -208,11 +257,12 @@ def _sendCommand(self, layer_id: str, command: str, *params):
208257
else:
209258
self._io.print(',')
210259
self._io.print(params[i])
211-
except OSError as e:
212-
self.switchDebugLed(False)
260+
self._io.print('\n')
261+
except Exception as e:
262+
#self.switchDebugLed(False)
213263
self.onSendCommandException(e)
214-
self._io.print('\n')
215-
self.switchDebugLed(False)
264+
#self._io.print('\n')
265+
#self.switchDebugLed(False)
216266

217267

218268

@@ -221,8 +271,10 @@ def _checkForFeedback(self):
221271
if feedback != None:
222272
if len(feedback) > 0:
223273
if feedback[0:1] == '<':
274+
self._onFeedbackKeepAlive()
224275
if len(feedback) == 1:
225-
self._onFeedbackKeepAlive()
276+
pass
277+
#self._onFeedbackKeepAlive()
226278
else:
227279
#print(feedback)####
228280
if feedback.startswith('<lt.'):
@@ -271,19 +323,26 @@ def _checkForFeedback(self):
271323
except:
272324
pass
273325
def _readFeedback(self) -> str:
326+
self._validateConnection()
274327
if not self._connected_iop.available():
275328
return None
276329
feedback = self._connected_iop.read()
277330
#self._connected_iop.clear()
278331
return feedback
279332
def _onFeedbackKeepAlive(self):
280-
pass
281-
# def _onFeedback(self, lid, type, x, y):
282-
# layer = self.layers.get(lid)
283-
# if layer != None:
284-
# layer._handleFeedback(type, x, y)
285-
# #print("FB: " + layer.layer_id + '.' + type + ':' + str(x) + ',' + str(y))
286-
333+
if self._connected_iop:
334+
self._connected_iop.keepAlive()
335+
def _validateConnection(self):
336+
if self._connected_iop:
337+
validate_gap = _RECONNECTING_VALIDATE_GAP if self._connected_iop.isReconnecting() else _VALIDATE_GAP
338+
now = time.ticks_ms()
339+
diff_ms = now - self.last_validate_ms
340+
if diff_ms >= validate_gap:
341+
self._connected_iop.validateConnection()
342+
self.last_validate_ms = now
343+
def _setReconnectRCId(self, rc_id: str):
344+
if self._connected_iop:
345+
self._connected_iop.setReconnectRCId(rc_id)
287346
def _createTunnel(self, end_point):
288347
tunnel_id = str(self._allocTunnelNid())
289348
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/_dumbdisplay.py

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
import sys
77

8-
try:
9-
from machine import Pin
10-
_DD_HAS_LED = True
11-
except:
12-
_DD_HAS_LED = False
8+
# try:
9+
# from machine import Pin
10+
# _DD_HAS_LED = True
11+
# except:
12+
# _DD_HAS_LED = False
1313

1414

1515
class DDAutoPin:
@@ -46,15 +46,15 @@ class DumbDisplay(DumbDisplayImpl):
4646
@staticmethod
4747
def runningWithMicropython():
4848
return hasattr(sys, 'implementation') and sys.implementation.name == 'micropython'
49-
def __init__(self, io: DDInputOutput):
49+
def __init__(self, io: DDInputOutput, reset_machine_on_connection_error: bool = True):
5050
super().__init__(io)
51-
self.debug_led = None
52-
self.reset_machine_on_connection_error = False # _DD_HAS_LED and len(sys.argv) != 0
51+
#self.debug_led = None
52+
self.reset_machine_on_connection_error = reset_machine_on_connection_error # _DD_HAS_LED and len(sys.argv) != 0
5353

54-
def debugSetup(self, debug_led_pin):
55-
'''setup debug use flashing LED pin number'''
56-
if _DD_HAS_LED:
57-
self.debug_led = Pin(debug_led_pin, Pin.OUT)
54+
# def debugSetup(self, debug_led_pin):
55+
# '''setup debug use flashing LED pin number'''
56+
# if _DD_HAS_LED:
57+
# self.debug_led = Pin(debug_led_pin, Pin.OUT)
5858
def connect(self):
5959
'''explicit connect'''
6060
self._connect()
@@ -88,6 +88,7 @@ def recordLayerSetupCommands(self):
8888
def playbackLayerSetupCommands(self, layerSetupPersistId: str):
8989
self._sendCommand(None, "SAVEC", layerSetupPersistId, _DD_BOOL_ARG(True))
9090
self._sendCommand(None, "PLAYC")
91+
self._setReconnectRCId(layerSetupPersistId)
9192
def backgroundColor(self, color: str):
9293
'''set DD background color with common "color name"'''
9394
self._connect()
@@ -117,24 +118,34 @@ def notone(self):
117118

118119

119120

120-
def toggleDebugLed(self):
121-
if self.debug_led != None:
122-
self.debug_led.value(not self.debug_led.value())
123-
def switchDebugLed(self, on):
124-
if self.debug_led != None:
125-
if on:
126-
self.debug_led.on()
127-
else:
128-
self.debug_led.off()
129-
def onSendCommandException(self, os_error):
130-
print("xxxxxxxxx")
131-
print("xxx OsError -- " + str(os_error) )
132-
print("xxxxxxxxx")
133-
if _DD_HAS_LED and self.reset_machine_on_connection_error:
134-
import machine
135-
machine.reset()
136-
else:
137-
sys.exit()
121+
# def toggleDebugLed(self):
122+
# if self.debug_led != None:
123+
# self.debug_led.value(not self.debug_led.value())
124+
# def switchDebugLed(self, on):
125+
# if self.debug_led != None:
126+
# if on:
127+
# self.debug_led.on()
128+
# else:
129+
# self.debug_led.off()
130+
def onSendCommandException(self, error):
131+
if False:
132+
print("xxxxxxxxx")
133+
print("xxx Error (send command) -- " + str(error) )
134+
print("xxxxxxxxx")
135+
if self.reset_machine_on_connection_error:
136+
print("xxxxxxxxx")
137+
print("xxx Error (send command) -- {}".format(error))
138+
print("xxxxxxxxx")
139+
try:
140+
import machine
141+
machine.reset()
142+
except:
143+
sys.exit()
144+
# if _DD_HAS_LED and self.reset_machine_on_connection_error:
145+
# import machine
146+
# machine.reset()
147+
# else:
148+
# sys.exit()
138149

139150

140151

samples/graphical/main.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
from dumbdisplay.io_inet import *
1717
dd = DumbDisplay(io4Inet())
1818

19-
import time
19+
import time
20+
21+
22+
dd.recordLayerSetupCommands()
2023

2124
# create 4 graphical [LCD] layers
2225
l1 = LayerGraphical(dd, 150, 101)
@@ -27,6 +30,8 @@
2730
# "auto pin" the 4 layers -- 2 by 2
2831
AutoPin('H', AutoPin('V', l1, l2), AutoPin('V', l3, l4)).pin(dd)
2932

33+
dd.playbackLayerSetupCommands("ugraphical")
34+
3035

3136
while True:
3237
dd.writeComment("start ...")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
WIFI_SSID="your wifi router ssid"
3+
WIFI_PWD="your wifi router password"

samples/ledgrid_onoff/main.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11

22
from dumbdisplay.core import *
3-
from dumbdisplay.io_inet import *
43
from dumbdisplay.layer_ledgrid import *
54

6-
dd = DumbDisplay(io4Inet())
5+
6+
# create DumbDisplay
7+
if DumbDisplay.runningWithMicropython():
8+
# connect using WIFI:
9+
# assume a _my_secret.py Python script containing
10+
# WIFI_SSID="SSID"
11+
# WIFI_PWD="PASSWORD"
12+
from _my_secret import *
13+
from dumbdisplay.io_wifi import *
14+
dd = DumbDisplay(io4Wifi(WIFI_SSID, WIFI_PWD))
15+
else:
16+
# connect using Inet (Python Internet connection)
17+
from dumbdisplay.io_inet import *
18+
dd = DumbDisplay(io4Inet())
19+
20+
721
l = LayerLedGrid(dd, 20, 20)
822
l.enableFeedback("fa")
923
l.offColor(RGB_COLOR(0xcc, 0xcc, 0xcc))

samples/melody/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def __init__(self):
153153

154154
dd.pinAutoPinLayers(AutoPin("H", self.playLayer, self.restartLayer, self.targetLayer).build(), 0, 0, 9 * WIDTH, TOP_HEIGHT)
155155

156-
dd.playbackLayerSetupCommands("ddmelody")
156+
dd.playbackLayerSetupCommands("uddmelody")
157157

158158
def run(self):
159159
while True:

samples/run_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22

33
if __name__ == "__main__":
4-
import melody.main
5-
#import graphical.main
4+
#import melody.main
5+
import graphical.main
66
#import doodle.main

0 commit comments

Comments
 (0)