Skip to content

Commit 17ffff6

Browse files
authored
Merge pull request #2514 from kattni/canary-network-detection-handling
Refactor for better network handling.
2 parents c0a9493 + aa56f6f commit 17ffff6

File tree

1 file changed

+97
-68
lines changed

1 file changed

+97
-68
lines changed

Canary_Nightlight/code.py

Lines changed: 97 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -39,39 +39,6 @@
3939
SLEEP_COLOR = (255, 0, 0) # Red
4040
WAKE_COLOR = (0, 0, 255) # Blue
4141

42-
# The blink color.
43-
# This is the color that the canary will blink to notify you that the network is down.
44-
# Defaults to red.
45-
BLINK_COLOR = (255, 0, 0)
46-
47-
# Canary brightness customisation.
48-
# Both the options below must be a float between 0.0 and 1.0, where 0.0 is off, and 1.0 is max.
49-
# This is the brightness of the canary during sleep time. It defaults to 0.2, or "20%".
50-
# Increase or decrease this value to change the brightness.
51-
SLEEP_BRIGHTNESS = 0.2
52-
# This is the brightness of the canary during wake time. It defaults to 0.7, or "70%".
53-
# Increase or decrease this value to change the brightness.
54-
WAKE_BRIGHTNESS = 0.7
55-
56-
# Consecutive ping fail to blink.
57-
# This value is the number of times ping will consecutively fail before the canary begins blinking.
58-
# If the blinking is happening too often, or if the network is often flaky, this value can be
59-
# increased to extend the number of failures it takes to begin blinking.
60-
# Defaults to 10. Must be an integer greater than 1.
61-
CONSECUTIVE_PING_FAIL_TO_BLINK = 10
62-
63-
# Ping interval while ping is successful.
64-
# This is the interval at which the code will send a ping while the network is up and the pings
65-
# are successful. If for any reason you would prefer to slow down the ping interval, this value
66-
# can be updated. Defaults to 1 second. Must be a float greater than 1. Increase this value to
67-
# increase the ping interval time. Do not decrease this value!
68-
UP_PING_INTERVAL = 1
69-
70-
# Checks whether the successful ping interval is below the minimum value.
71-
if UP_PING_INTERVAL < 1:
72-
# If is below the minimum, raise this error and stop the code.
73-
raise ValueError("UP_PING_INTERVAL must be a float greater than 1!")
74-
7542
# Sleep time.
7643
# This is the hour in 24-hour time at which the light should change to the
7744
# desired color for the time you intend to sleep.
@@ -84,18 +51,58 @@
8451
# Must be an integer between 0 and 23. Defaults to 6 (6am).
8552
WAKE_TIME = 6
8653

54+
# Canary brightness customisation.
55+
# Brightness must be a float or integer between 0.0 and 1.0, where 0.0 is off, and 1.0 is max.
56+
# This is the brightness of the canary during sleep time. It defaults to 0.2, or "20%".
57+
# Increase or decrease this value to change the brightness.
58+
SLEEP_BRIGHTNESS = 0.2
59+
# This is the brightness of the canary during wake time. It defaults to 0.7, or "70%".
60+
# Increase or decrease this value to change the brightness.
61+
WAKE_BRIGHTNESS = 0.7
62+
8763
# Time check interval.
8864
# This sets the time interval at which the code checks Adafruit IO for the current time.
8965
# This is included because Adafruit IO has rate limiting. It ensures that you do not
9066
# hit the rate limit, and the time check does not get throttled.
91-
# Defaults to 300 seconds (5 minutes). Must be a float greater than 300. Increase
92-
# this value to increase the time check interval. Do not decrease this value!
67+
# Defaults to 300 seconds (5 minutes). Must be an integer equal to or greater than 300.
68+
# Increase this value to increase the time check interval. Do not decrease this value!
9369
TIME_CHECK_INTERVAL = 300
9470

95-
# Checks whether the time check interval is below the minimum value.
96-
if TIME_CHECK_INTERVAL < 300:
97-
# If is below the minimum, raise this error and stop the code.
98-
raise ValueError("TIME_CHECK_INTERVAL must be a float greater than 300!")
71+
# Checks whether the time check interval is below the minimum value and an integer.
72+
if TIME_CHECK_INTERVAL < 300 or isinstance(TIME_CHECK_INTERVAL, float):
73+
# If is below the minimum or a float, raise this error and stop the code.
74+
raise ValueError("TIME_CHECK_INTERVAL must be a integer, and greater than 300!")
75+
76+
# Ping interval while ping is successful.
77+
# This is the interval at which the code will send a ping while the network is up and the pings
78+
# are successful. If for any reason you would prefer to slow down the ping interval, this value
79+
# can be updated. Defaults to 1 second. Must be an integer equal to or greater than 1. Increase
80+
# this value to increase the ping interval time. Do not decrease this value!
81+
UP_PING_INTERVAL = 1
82+
83+
# Checks whether the successful ping interval is below the minimum value and an integer.
84+
if UP_PING_INTERVAL < 1 or isinstance(UP_PING_INTERVAL, float):
85+
# If is below the minimum or a float, raise this error and stop the code.
86+
raise ValueError("UP_PING_INTERVAL must be a integer, and greater than 1!")
87+
88+
# The blink color.
89+
# This is the color that the canary will blink to notify you that the network is down.
90+
# Defaults to red.
91+
BLINK_COLOR = (255, 0, 0)
92+
93+
# Consecutive ping fail to blink.
94+
# This value is the number of times ping will consecutively fail before the canary begins blinking.
95+
# If the blinking is happening too often, or if the network is often flaky, this value can be
96+
# increased to extend the number of failures it takes to begin blinking.
97+
# Defaults to 10. Must be an integer greater than 1.
98+
CONSECUTIVE_PING_FAIL_TO_BLINK = 10
99+
100+
# The amount of time in seconds that needs to pass while the network is down AND
101+
# NETWORK_DOWN_DETECTION is DISABLED before the board resets to try again.
102+
# Defaults to 900 seconds, or 20 minutes. Must be an integer. Increase or decrease
103+
# this value to alter how long the network should be down in this specific case
104+
# before the board resets.
105+
NETWORK_DOWN_RELOAD_TIME = 900
99106

100107
# IP address.
101108
# This is the IP address used to ping to verify that network connectivity is still present.
@@ -189,11 +196,13 @@ def blink(color):
189196
wifi_ping = wifi.radio.ping(ip=ip_address)
190197
# If the initial ping is unsuccessful, print the message.
191198
if wifi_ping is None:
192-
print("Setup test-ping failed.")
199+
print("Set up test-ping failed.")
193200
# Set `initial_ping` to False to indicate the failure.
194201
initial_ping = False
195202
else:
196-
# Otherwise, set `initial_ping` to True to indicate success.
203+
# Otherwise, print this message.
204+
print("Set up test-ping successful.")
205+
# Set `initial_ping` to True to indicate success.
197206
initial_ping = True
198207

199208
# Set up Adafruit IO. This will provide the current time through `io.receive_time()`.
@@ -211,10 +220,14 @@ def blink(color):
211220
reload_on_error(5, error)
212221

213222
# Initialise various time tracking variables.
214-
ping_time = 0
215223
check_time = 0
224+
network_down_time = time.time()
225+
ping_time = 0
216226
ping_fail_time = time.time()
217227

228+
# Initialise network check variable.
229+
network_check = 1
230+
218231
# Initialise ping fail count tracking.
219232
ping_fail_count = 0
220233

@@ -226,38 +239,54 @@ def blink(color):
226239
# try/except block to ensure the project will continue to run unattended if any
227240
# failures do occur.
228241
try:
229-
# If this is the first run of the code or `UP_PING_INTERVAL` time has passed, continue.
230-
if not ping_time or current_time - ping_time > UP_PING_INTERVAL:
231-
ping_time = time.time()
232-
# Ping to verify network connection.
233-
wifi_ping = wifi.radio.ping(ip=ip_address)
234-
if wifi_ping is not None:
235-
# If the ping is successful, print IP address and ping time.
236-
print(f"Pinging {ip_address}: {wifi_ping} ms")
237-
238-
# If the ping is successful, continue with this code.
239-
if wifi_ping is not None:
240-
ping_fail_count = 0
241-
# If this is the first run of the code or `TIME_CHECK_INTERVAL` has passed, continue.
242-
if not check_time or current_time - check_time > TIME_CHECK_INTERVAL:
242+
# If this is the first run of the code or the time check interval has passed, continue.
243+
if not check_time or current_time - check_time >= TIME_CHECK_INTERVAL:
244+
# Send a single ping to test for network connectivity.
245+
network_check = wifi.radio.ping(ip=ip_address)
246+
# If there is network connectivity, run the time check code.
247+
if network_check is not None:
248+
# Reset `check_time` to continue tracking.
243249
check_time = time.time()
244-
# Retrieve the time and save it to sundial.
250+
# Retrieve the time and save it to `sundial`.
245251
sundial = io.receive_time()
246252
# Print the current date and time to the serial console.
247253
print(f"LED color time-check. Date and time: {sundial.tm_year}-{sundial.tm_mon}-" +
248254
f"{sundial.tm_mday} {sundial.tm_hour}:{sundial.tm_min:02}")
249-
# Provides the current hour to the color_time function. This verifies the
250-
# current color based on time and returns that color, which is provided
251-
# to `fill()` to set the LED color.
255+
# Provide the current hour to the `color_time` function. The returned color is
256+
# provided to `pixels.fill()` to set the LED color.
252257
pixels.fill(color_time(sundial.tm_hour))
253-
254-
# If the ping has failed, and it's been one second, continue with this code.
255-
if wifi_ping is None and current_time - ping_fail_time > 1:
256-
ping_fail_time = time.time() # Reset the ping fail time to continue tracking.
257-
ping_fail_count += 1 # Add one to the fail count tracking.
258-
print(f"Ping failed {ping_fail_count} times")
259-
# If network down detection is enabled, run the following code.
260-
if NETWORK_DOWN_DETECTION:
258+
else:
259+
print("Network check ping failed.")
260+
261+
# If network down detection is disabled AND the network check ping failed
262+
# AND the specified network down reload time passed: print the message,
263+
# wait 3 seconds, and hard reset the board.
264+
if not NETWORK_DOWN_DETECTION and network_check is None and \
265+
current_time - network_down_time > NETWORK_DOWN_RELOAD_TIME:
266+
print(f"Network check ping has failed for over {NETWORK_DOWN_RELOAD_TIME} seconds.")
267+
reload_on_error(3, reload_type="reset")
268+
269+
# If network down detection is enabled, run the rest of the code.
270+
if NETWORK_DOWN_DETECTION:
271+
# If this is the first run of the code or up ping interval` time has passed, continue.
272+
if not ping_time or current_time - ping_time >= UP_PING_INTERVAL:
273+
# Reset `ping_time` to continue tracking.
274+
ping_time = time.time()
275+
# Ping to verify network connection.
276+
wifi_ping = wifi.radio.ping(ip=ip_address)
277+
# If the ping is successful, set the fail count to 0, and print IP and ping time.
278+
if wifi_ping is not None:
279+
ping_fail_count = 0
280+
print(f"Pinging {ip_address}: {wifi_ping} ms")
281+
282+
# If the ping has failed, and it's been one second, continue with this code.
283+
if wifi_ping is None and current_time - ping_fail_time >= 1:
284+
# Reset `ping_fail_time` to continue tracking.
285+
ping_fail_time = time.time()
286+
# Add one to the failure count tracking.
287+
ping_fail_count += 1
288+
# Print the ping failure count.
289+
print(f"Ping failed {ping_fail_count} times")
261290
# If the ping fail count exceeds the value defined above, begin blinking the LED
262291
# to indicate that the network is down.
263292
if ping_fail_count > CONSECUTIVE_PING_FAIL_TO_BLINK:

0 commit comments

Comments
 (0)