129 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
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 < 22:
 | 
						|
            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()
 |