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): self.activation_switch = Pin(8, Pin.IN, Pin.PULL_UP) 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) self.distance_sensor_power = Pin(27, Pin.OUT) self.distance_reading = ADC(2) 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() super().__init__() ntp.sync() def work(self): ticks = time.ticks_ms() if self.is_active(): self.distance_sensor_power.on() self.show_color() if self.is_activation_expired(ticks): logging.info('deactivating') self.is_http_activation = False else: self.distance_sensor_power.off() self.leds_off() super().work() if util.seconds_elapsed(ticks, self.ntp_ticks) > self.ntp_interval_in_seconds: self.ntp_ticks = ticks ntp.sync() def is_active(self): return self.activation_switch.value() == 0 or self.is_http_activation def is_activation_expired(self, ticks): return self.is_http_activation and util.seconds_elapsed(ticks, self.last_http_activation_ticks) > self.http_activation_interval_in_seconds 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 < 23: self.green_led.on() self.yellow_led.on() elif distance_in_inches < 25: self.green_led.on() elif distance_in_inches < 33: 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() 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): return self.distance_reading.read_u16() / 65535 * 1024 * 5 * 0.03937008 def handle_path(self, path): if (path == 'on'): logging.info('activated via http') return self.http_activation() return self.get_path_data(path) def get_path_data(self, path): 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(), is_active=self.is_active() ) def http_activation(self): self.is_http_activation = True self.last_http_activation_ticks = time.ticks_ms() return '' def cleanup(self): self.distance_sensor_power.off() self.leds_off() super().cleanup() def main(): logging.log_file = 'www/log.txt' Marshaller().run() if __name__ == '__main__': main()