2023-10-23 15:43:36 -04:00
|
|
|
import time
|
|
|
|
|
|
|
|
from machine import Pin
|
|
|
|
from machine import ADC
|
|
|
|
from net import logging
|
|
|
|
from net import ntp
|
|
|
|
from net import Server
|
|
|
|
from net import templates
|
|
|
|
from net import util
|
|
|
|
from net.config import config
|
|
|
|
|
|
|
|
|
|
|
|
class Marshaller(Server):
|
|
|
|
|
|
|
|
def __init__(self):
|
2023-10-27 17:39:58 -04:00
|
|
|
self.activation_switch = Pin(8, Pin.IN, Pin.PULL_UP)
|
2023-10-23 15:43:36 -04:00
|
|
|
self.red_led = Pin(11, Pin.OUT)
|
|
|
|
self.blue_led = Pin(13, Pin.OUT)
|
|
|
|
self.green_led = Pin(20, Pin.OUT)
|
|
|
|
self.yellow_led = Pin(18, Pin.OUT)
|
2023-10-27 17:39:58 -04:00
|
|
|
self.distance_sensor_power = Pin(27, Pin.OUT)
|
|
|
|
self.distance_reading = ADC(2)
|
2023-10-23 15:43:36 -04:00
|
|
|
self.last_value = -1
|
|
|
|
self.last_http_activation_ticks = time.ticks_ms()
|
|
|
|
self.http_activation_interval_in_seconds = 2 * 60
|
|
|
|
self.is_http_activation = False
|
|
|
|
self.ntp_interval_in_seconds = 3 * 60 * 60
|
|
|
|
self.ntp_ticks = time.ticks_ms()
|
|
|
|
|
2023-10-27 17:39:58 -04:00
|
|
|
super().__init__()
|
2023-10-23 15:43:36 -04:00
|
|
|
ntp.sync()
|
|
|
|
|
|
|
|
def work(self):
|
|
|
|
ticks = time.ticks_ms()
|
|
|
|
|
2023-10-27 17:39:58 -04:00
|
|
|
if self.is_active():
|
|
|
|
self.distance_sensor_power.on()
|
|
|
|
self.show_color()
|
2023-10-23 15:43:36 -04:00
|
|
|
|
2023-10-27 17:39:58 -04:00
|
|
|
if self.is_activation_expired(ticks):
|
|
|
|
logging.info('deactivating')
|
2023-10-23 15:43:36 -04:00
|
|
|
self.is_http_activation = False
|
|
|
|
else:
|
2023-10-27 17:39:58 -04:00
|
|
|
self.distance_sensor_power.off()
|
2023-10-23 15:43:36 -04:00
|
|
|
self.leds_off()
|
|
|
|
super().work()
|
|
|
|
|
2023-10-27 17:48:42 -04:00
|
|
|
if util.seconds_elapsed(ticks, self.ntp_ticks) > self.ntp_interval_in_seconds:
|
2023-10-23 15:43:36 -04:00
|
|
|
self.ntp_ticks = ticks
|
|
|
|
ntp.sync()
|
|
|
|
|
2023-10-27 17:39:58 -04:00
|
|
|
def is_active(self):
|
|
|
|
return self.activation_switch.value() == 0 or self.is_http_activation
|
|
|
|
|
|
|
|
def is_activation_expired(self, ticks):
|
2023-10-27 17:48:42 -04:00
|
|
|
return self.is_http_activation and util.seconds_elapsed(ticks, self.last_http_activation_ticks) > self.http_activation_interval_in_seconds
|
2023-10-27 17:39:58 -04:00
|
|
|
|
|
|
|
def show_color(self):
|
|
|
|
distance_in_inches = self.get_buffered_distance_in_inches()
|
|
|
|
self.leds_off()
|
|
|
|
|
|
|
|
if distance_in_inches < 15:
|
|
|
|
self.red_led.on()
|
|
|
|
elif distance_in_inches < 20:
|
|
|
|
self.green_led.on()
|
|
|
|
self.yellow_led.on()
|
|
|
|
elif distance_in_inches < 25:
|
|
|
|
self.green_led.on()
|
|
|
|
elif distance_in_inches < 30:
|
|
|
|
self.yellow_led.on()
|
|
|
|
else:
|
|
|
|
self.blue_led.on()
|
|
|
|
|
|
|
|
def leds_off(self):
|
|
|
|
self.red_led.off()
|
|
|
|
self.blue_led.off()
|
|
|
|
self.green_led.off()
|
|
|
|
self.yellow_led.off()
|
2023-10-23 15:43:36 -04:00
|
|
|
|
|
|
|
def get_buffered_distance_in_inches(self):
|
|
|
|
distance = self.get_distance_in_inches()
|
|
|
|
|
|
|
|
if abs(distance - self.last_value) > 0.25:
|
|
|
|
self.last_value = distance
|
|
|
|
|
|
|
|
return self.last_value
|
|
|
|
|
|
|
|
def get_distance_in_inches(self):
|
2023-10-27 17:39:58 -04:00
|
|
|
return self.distance_reading.read_u16() / 65535 * 1024 * 5 * 0.03937008
|
2023-10-23 15:43:36 -04:00
|
|
|
|
2023-10-27 17:48:42 -04:00
|
|
|
def handle_path(self, path):
|
2023-10-23 15:43:36 -04:00
|
|
|
if (path == 'on'):
|
2023-10-27 17:39:58 -04:00
|
|
|
logging.info('activated via http')
|
2023-10-23 15:43:36 -04:00
|
|
|
return self.http_activation()
|
|
|
|
|
2023-10-27 17:39:58 -04:00
|
|
|
return self.get_path_data(path)
|
2023-10-23 15:43:36 -04:00
|
|
|
|
2023-10-27 17:39:58 -04:00
|
|
|
def get_path_data(self, path):
|
2023-10-23 15:43:36 -04:00
|
|
|
if path.endswith('.txt') or path.endswith('.ico'):
|
|
|
|
with open(f'www/{path}', 'rb') as f:
|
|
|
|
return f.read()
|
|
|
|
|
|
|
|
return templates.render(
|
|
|
|
f'www/{path or self.default_path}',
|
|
|
|
hostname=config['hostname'],
|
|
|
|
datetime=util.datetime(),
|
2023-10-27 17:39:58 -04:00
|
|
|
is_active=self.is_active()
|
2023-10-23 15:43:36 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
def http_activation(self):
|
|
|
|
self.is_http_activation = True
|
|
|
|
self.last_http_activation_ticks = time.ticks_ms()
|
|
|
|
|
2023-10-27 17:39:58 -04:00
|
|
|
return ''
|
2023-10-23 15:43:36 -04:00
|
|
|
|
|
|
|
def cleanup(self):
|
2023-10-27 17:39:58 -04:00
|
|
|
self.distance_sensor_power.off()
|
2023-10-23 15:43:36 -04:00
|
|
|
self.leds_off()
|
|
|
|
super().cleanup()
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
logging.log_file = 'www/log.txt'
|
|
|
|
Marshaller().run()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|