Skip to content

Commit a9d1601

Browse files
authored
Merge pull request #37 from jef41/feature/wifi_reconnect
improve wifi reconnect
2 parents 8657c89 + 4adaaf2 commit a9d1601

File tree

4 files changed

+132
-74
lines changed

4 files changed

+132
-74
lines changed

bridge/lib/display_driver.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def __init__(self, config: BridgeConfig):
6060
self.update_intvl = None
6161
self.brightness = None # getattr
6262
self.indicator = True
63-
self.startup_msg = ""
63+
self.startup_msg = []
6464
# lcd = PicoGraphics(display=DISPLAY_PICO_DISPLAY, pen_type=PEN_P4,rotate=0)
6565
# lcd.set_backlight(1.0)
6666
# update_frequency = 3 # seconds to cycle through each screen
@@ -338,18 +338,44 @@ def update_indicator(self):
338338
self.indicator = not self.indicator
339339
self.lcd.circle(10, 60, 5) # x, y, r
340340

341-
def show_msg(self, msg):
341+
def show_msg(self, msg, append=True):
342342
#self.lcd.set_font("serif")
343-
self.startup_msg = self.startup_msg + "\n" + msg
343+
if append:
344+
#self.startup_msg = self.startup_msg + "\n" + msg
345+
try:
346+
self.startup_msg.append(msg)
347+
except NameError:
348+
self.startup_msg = [msg]
349+
else:
350+
# overwrite last line
351+
#self.overwrite_msg(msg)
352+
try:
353+
self.startup_msg[-1] = msg
354+
except NameError:
355+
self.startup_msg = [msg]
344356
self.lcd.set_font("bitmap8")
345357
self.lcd.set_pen(self.colour_to_palette["BG"])
346358
self.lcd.clear()
347359
self.lcd.set_thickness(1)
348360
self.lcd.set_pen(self.colour_to_palette["WHITE"])
349361
#self.lcd.text(msg, 0, 65, scale=1)
350-
self.lcd.text(self.startup_msg, 0, 0)
362+
#self.lcd.text(self.startup_msg, 0, 0)
363+
self.lcd.text('\n'.join([item for item in self.startup_msg]), 0, 0)
351364
self.lcd.update()
352365
time.sleep(1)
366+
367+
'''def overwrite_msg(self, new_msg):
368+
# overwrite the last line of a messgae
369+
import re
370+
regex = re.compile("[\n]")
371+
msgs = regex.split(self.startup_msg)
372+
if len(msgs)>0:
373+
msgs[len(msgs)-1] = new_msg
374+
else:
375+
msgs[0] = new_msg
376+
self.startup_msg = '\n'.join([item for item in msgs])
377+
'''
378+
353379

354380
class RGB_Driver:
355381
def __new__(cls, config: BridgeConfig):
@@ -409,4 +435,4 @@ def r_align(lcd_obj, txt, sz, width):
409435
return int(width - lcd_obj.measure_text(txt, sz))
410436

411437

412-
__version__ = "1.1.1"
438+
__version__ = "1.1.2"

bridge/lib/wifi_client.py

Lines changed: 88 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from sys import platform
1313

1414
RP2 = platform == "rp2"
15-
15+
'''
1616
# cyw43_wifi_link_status
1717
error_codes_to_messages = {
1818
0: "CYW43_LINK_DOWN",
@@ -22,6 +22,16 @@
2222
-1: "CYW43_LINK_FAIL",
2323
-2: "CYW43_LINK_NONET",
2424
-3: "CYW43_LINK_BADAUTH",
25+
}'''
26+
# cyw43_wifi_link_status
27+
error_codes_to_messages = {
28+
0: "STAT_IDLE",
29+
1: "STAT_CONNECTING",
30+
2: "STAT_GOT_IP",
31+
3: "CYW43_LINK_UP",
32+
-1: "STAT_CONNECT_FAIL",
33+
-2: "STAT_NO_AP_FOUND",
34+
-3: "STAT_WRONG_PASSWORD",
2535
}
2636

2737
logger = logging.getLogger(__name__)
@@ -33,7 +43,7 @@ def __init__(self, config):
3343
# self._ping_interval = 20000
3444
# self._in_connect = False
3545
# self._has_connected = False # Define 'Clean Session' value to use.
36-
self._sta_if = network.WLAN(network.STA_IF)
46+
self.nic = network.WLAN(network.STA_IF)
3747
self._ssid = config.ssid
3848
self._wifi_pw = config.password
3949
try:
@@ -46,54 +56,92 @@ def __init__(self, config):
4656

4757
async def wifi_connect(self, onboard_led, quick=False):
4858
await onboard_led.set_status(onboard_led.WIFI_CONNECTING)
49-
s = self._sta_if
50-
s.active(True)
51-
if RP2: # Disable auto-sleep.
59+
#nic = self._sta_if
60+
#nic.disconnect()
61+
#nic.active(False)
62+
'''if RP2: # Disable auto-sleep.
5263
# https://datasheets.raspberrypi.com/picow/connecting-to-the-internet-with-pico-w.pdf
5364
# para 3.6.3
54-
s.config(pm=0xA11140)
65+
nic.config(pm=0xA11140)
5566
import rp2
5667
5768
if self._country:
58-
rp2.country(self._country)
69+
rp2.country(self._country)'''
70+
self.nic.deinit()
71+
self.nic = network.WLAN(network.STA_IF)
72+
network.hostname("tilt_micro_bridge")
73+
self.nic.config(pm = network.WLAN.PM_PERFORMANCE)
74+
if self._country:
75+
network.country(self._country)
5976
logger.info("Attempting to connect to wifi")
60-
s.connect(self._ssid, self._wifi_pw)
61-
for _ in range(60): # Break out on fail or success. Check once per sec.
62-
await asyncio.sleep(1)
77+
self.nic.active(True)
78+
self.nic.connect(self._ssid, self._wifi_pw)
79+
catch = 0
80+
for _ in range(30): # Break out on fail or success. Check once per sec.
81+
catch = self.nic.status() # can be a fleeting status, so capture it
82+
# print(catch)
6383
# Loop while connecting or no IP
64-
if s.isconnected():
84+
if self.nic.isconnected():
6585
logger.info("wifi connected")
6686
await onboard_led.set_status(onboard_led.WIFI_CONNECTED)
6787
break
68-
if RP2: # 1 is joining. 2 is No IP, ie in process of connecting
69-
if not 1 <= s.status() <= 3:
70-
logger.debug(f"wifi reports {error_codes_to_messages[s.status()]}")
71-
break
88+
#if RP2: # 1 is joining. 2 is No IP, ie in process of connecting
89+
# if not 1 <= nic.status() <= 3:
90+
if catch < 1:
91+
logger.warning(f"wifi reports {error_codes_to_messages[catch]}")
92+
break
93+
await asyncio.sleep(1)
7294
else: # Timeout: still in connecting state
73-
s.disconnect()
7495
await onboard_led.set_status(onboard_led.WIFI_DISCONNECTED)
7596
await asyncio.sleep(1)
76-
77-
if not s.isconnected(): # Timed out
78-
logger.warning("wifi connect timed out")
79-
raise OSError("Wi-Fi connect timed out")
80-
if not quick: # Skip on first connection only if power saving
81-
# Ensure connection stays up for a few secs.
82-
logger.info("Checking wifi integrity")
83-
for _ in range(5):
84-
if not s.isconnected():
85-
logger.warning("Connection Unstable")
86-
raise OSError("Connection Unstable") # in 1st 5 secs
87-
await asyncio.sleep(1)
88-
logger.info("Got reliable connection")
97+
#if not nic.isconnected(): # Timed out
98+
logger.warning(f"wifi connect timed out {error_codes_to_messages[catch]}")
99+
#raise OSError("Wi-Fi connect timed out")
100+
#else:
101+
if self.nic.isconnected():
102+
if not quick: # Skip on first connection only if power saving
103+
# Ensure connection stays up for a few secs.
104+
logger.info("Checking wifi integrity")
105+
for _ in range(5):
106+
if not self.nic.isconnected():
107+
logger.warning("Connection Unstable")
108+
#raise OSError("Connection Unstable") # in 1st 5 secs
109+
await asyncio.sleep(1)
110+
logger.info("Got reliable connection")
111+
else: # reset nic
112+
self.nic.disconnect()
113+
self.nic.active(False)
114+
self.nic.deinit()
115+
return catch #nic.status()
89116

90117
async def connect(
91-
self, onboard_led, quick=False
118+
self, onboard_led, display=False, quick=False
92119
): # Quick initial connect option for battery apps
93-
s = self._sta_if
94-
if not s.isconnected():
95-
await self.wifi_connect(onboard_led, quick)
96-
if s.isconnected():
120+
#nic = self._sta_if
121+
attempt = 0
122+
while not self.nic.isconnected():
123+
if attempt > 0 and display:
124+
display.show_msg("trying connection again")
125+
del display.startup_msg[-1]
126+
attempt += 1
127+
result = await self.wifi_connect(onboard_led, quick)
128+
if result < 2:
129+
# wifi not connected
130+
if display:
131+
display.show_msg(f"{error_codes_to_messages[result]} ({attempt})", append = (False if attempt>1 else True))
132+
if result == -3:
133+
if display:
134+
display.show_msg("bad wifi password,\nstopping here.")
135+
logger.error("bad wifi password, stopping here.")
136+
raise OSError("Bad Password")
137+
else:
138+
logger.debug("sleep 120 secs and try wifi again")
139+
if display:
140+
display.show_msg("trying again in 2 minutes.")
141+
del display.startup_msg[-1] #remove that last message from list - it's hacky
142+
await asyncio.sleep(120)
143+
144+
if self.nic.isconnected():
97145
if self.check_interval > 0:
98146
asyncio.create_task(self._keep_connected())
99147
# Runs forever unless user issues .disconnect()
@@ -103,10 +151,10 @@ async def connect(
103151
# Scheduled on 1st successful connection. Runs forever maintaining wifi and
104152
# broker connection. Must handle conditions at edge of wifi range.
105153
async def _keep_connected(self):
106-
s = self._sta_if
107-
while True: # s.active():
154+
#nic = self._sta_if
155+
while True: # nic.active():
108156
logger.debug("running in _keep_connected")
109-
if s.isconnected(): # Pause for 1 second
157+
if self.nic.isconnected(): # Pause for 1 second
110158
# await asyncio.sleep(1) # debug
111159
await asyncio.sleep(
112160
randrange(
@@ -116,7 +164,7 @@ async def _keep_connected(self):
116164
gc.collect()
117165
else: # Link is down
118166
try:
119-
s.disconnect()
167+
self.nic.disconnect()
120168
except OSError:
121169
logger.error("Wi-Fi not started, unable to disconnect interface")
122170
await asyncio.sleep(1)
@@ -131,7 +179,7 @@ async def _keep_connected(self):
131179
except OSError as e:
132180
logger.error(f"Error in reconnect. {e}")
133181
# Can get ECONNABORTED or -1. The latter signifies no or bad CONNACK received.
134-
s.disconnect()
182+
self.nic.disconnect()
135183
logger.warning("Disconnected, exited _keep_connected")
136184

137185

@@ -160,4 +208,4 @@ async def wan_ok(
160208
return False
161209

162210

163-
__version__ = "1.0.0"
211+
__version__ = "1.0.2"

bridge/tilt_micro_bridge.py

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,3 @@
1-
"""latest change:
2-
allow for a display rst pin
3-
remove clock, introduce blinky dot
4-
report some startup progress on LCD, if present
5-
working on:
6-
1.1.1
7-
TODO:
8-
todo refactor main & bridge lib to make more logical
9-
todo remove unnecessary libs & comments
10-
11-
ideas:
12-
button to set into calibration mode, use different cal_config.json ?
13-
display
14-
15-
16-
"""
17-
181
import time # micropython-lib/python-stdlib/time extends std time module, required for strftime in debug logging
192
import logging
203
from logging import TimedRotatingLogFileHandler
@@ -99,12 +82,12 @@ async def hold_up():
9982
if wifi.has_config:
10083
if bridge.display:
10184
bridge.display.show_msg("connecting to wifi...")
102-
asyncio.run(wifi.connect(onboard_led))
85+
asyncio.run(wifi.connect(onboard_led, bridge.display))
10386

104-
if bridge.display:
105-
bridge.display.show_msg("wifi connected \nget NTP time")
106-
# set system time - could have a UTC offset in config, but time is only used internally at the moment
107-
bridge.get_time()
87+
if bridge.display:
88+
bridge.display.show_msg("wifi connected \nget NTP time")
89+
# set system time - could have a UTC offset in config, but time is only used internally at the moment
90+
bridge.get_time()
10891
# provision the providers referenced in config.json, called here so the wifi referrnce doesn't have to be passed around
10992
bridge.set_providers(wifi.has_config)
11093

@@ -143,4 +126,5 @@ async def hold_up():
143126
# hold here, cannot proceed, error with config.json
144127
onboard_led.on()
145128

146-
__version__ = "1.1.1"
129+
__version__ = "1.1.2"
130+

build/boot.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ async def hold_up():
9393
if wifi.has_config:
9494
if bridge.display:
9595
bridge.display.show_msg("connecting to wifi...")
96-
asyncio.run(wifi.connect(onboard_led))
96+
asyncio.run(wifi.connect(onboard_led, bridge.display))
9797
98-
if bridge.display:
99-
bridge.display.show_msg("wifi connected \\nget NTP time")
100-
# set system time - could have a UTC offset in config, but time is only used internally at the moment
101-
bridge.get_time()
98+
if bridge.display:
99+
bridge.display.show_msg("wifi connected \\nget NTP time")
100+
# set system time - could have a UTC offset in config, but time is only used internally at the moment
101+
bridge.get_time()
102102
# provision the providers referenced in config.json, called here so the wifi referrnce doesn't have to be passed around
103103
bridge.set_providers(wifi.has_config)
104104
@@ -137,7 +137,7 @@ async def hold_up():
137137
# hold here, cannot proceed, error with config.json
138138
onboard_led.on()
139139
140-
__version__ = "1.1.1"
140+
__version__ = "1.1.2"
141141
142142
""")
143143

0 commit comments

Comments
 (0)