def page(web): try: yield web.heading( 2, trn['Edit connection']) config = connection[int(web.args['idx'])] yield web.form_head('set') yield web.form_label('SSID', 'ssid', config.ssid) yield web.form_label('BSSID', 'bssid', bytes2bssid(config.bssid)) yield web.form_input(trn['Password'], 'psw', config.passwd, 'password') yield web.form_spacer() yield web.select_head(trn['Location'], 'location') for i in range(len(location)): yield web.select_option(i, location[i].name, i == config.location) yield web.select_tail() yield web.form_tail() except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: vbat.low_voltage = max(2.8, min(4.0, float(web.args['v']))) vbat.flush() except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: hotspot.ssid = web.args['id'] hotspot.flush() except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: location.append(Location(web.args['name'], web.args['lat'], web.args['lon'])) Location.flush() except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: ui.language = web.args['l'] ui.flush() except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: ui.apikey = web.args['key'] ui.flush() except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: l = int(web.args['t']), (int(web.args['b']), int(web.args['e'])) ui.refresh, ui.dbl = l ui.flush() except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: i = int(web.args['idx']) args = web.args['name'], float(web.args['lat']), float(web.args['lon']) location[i].name, location[i].lat, location[i].lon = args location[i].flush() except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: p = web.args['p'] hotspot.passwd = p hotspot.flush() except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: l = float(web.args['ihi']), float(web.args['ohi']), float( web.args['olo']) temp.indoor_high, temp.outdoor_high, temp.outdoor_low = l temp.flush() except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: yield web.heading(2, trn['DELETE LOCATION'] + ' ??!') loc = location[int(web.args['idx'])] yield web.form_head('lrm') yield web.form_label(trn['Name'], 'name', loc.name) yield web.form_label(trn['Latitude'], 'lat', loc.lat) yield web.form_label(trn['Longitude'], 'lon', loc.lon) yield web.form_tail() except Exception as e: dump_exception('WEB error:', e) yield web.index
def run(sha): try: # Init all peripheries temp, led, volt, canvas, net, wdt = _perif() # Beep when we are rebooted (only when this is not wake up # from deep sleep) if not DEEPSLEEP == reset_cause(): play((2093, 30)) # It can happen that we want only to move meteostation somewhere # and don't want to let it wake up during transport. In this case # we can put it to greetings mode, where only picture is displayed # and station kept sleeping till reset button is pressed if DISPLAY_GREETINGS == display.DISPLAY_STATE or jumpers.sleep: # Read all initializes all peripheries play((800, 30), 500, (400, 30)) _greetings(canvas, net, led) # It may happen that user wants to attach with HTTP for update of firmware # or configuration. In this case we can not rely on existing WiFi connection # and we rather go to hot-spot mode. elif jumpers.hotspot: _hotspot(canvas, net, led, volt, wdt) # And finally - meteostation display - basic functionality ;-) else: # Network is running and connected ... we can checks for updates _update(net, sha) # Once we are connected to network, we can download forecast. # Just note that once forecast is download, WiFi is disconnected # to save as much battery capacity as possible. forecast = _forecast(net, temp) # Most time consuming part when we have all data is to draw them # on user interface - screen. _repaint(canvas, forecast, net, led, volt) # Forecast is painted. Now we shall checks for alerts if there are some # activated _allerts(forecast) # When all is displayed, then go to deep sleep. Sleep time is obtained # according to current weather forecast and UI needs and is in minutes. _sleep(net, forecast) except Exception as e: dump_exception('FATAL - RECOVERY REQUIRED !!!', e) _sleep(net, forecast, 5)
def page(web): try: name = web.args['name'] for i in range(len(location)): if location[i].name == name: location.remove(location[i]) Location.flush() break except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: bssid = bssid2bytes(web.args['bssid']) for i in range(len(connection)): if connection[i].bssid == bssid: connection.remove(connection[i]) Connection.flush() break except Exception as e: dump_exception('WEB error:', e) yield web.index
def page(web): try: yield web.heading(2, trn['DELETE CONNECTION'] + ' ??!') config = connection[int(web.args['idx'])] yield web.form_head('rm') yield web.form_label('SSID', 'ssid', config.ssid) yield web.form_label('BSSID', 'bssid', bytes2bssid(config.bssid)) yield web.form_spacer() yield web.form_label( trn['Location'], 'loc', location[config.location].name if config.location < len(location) else '...') yield web.form_tail() except Exception as e: dump_exception('WEB error:', e) yield web.index
def run(self): # Open TCP socket for listening self.wdt.feed() addr = socket.getaddrinfo('0.0.0.0', 5555)[0][-1] sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.wdt.feed() sck.bind(addr) self.wdt.feed() sck.setblocking(False) self.wdt.feed() sck.listen(1) self.wdt.feed() log('Web server listening on', addr) # Wait for incoming connection while True: self.wdt.feed() while True: try: self.client, addr = sck.accept() self.wdt.feed() break except OSError as e: if e.errno == EAGAIN: sleep_ms(100) elif e.errno == 23: # Out of memory - restart server self._restart('Low memory - restart !!!') else: dump_exception('Socket accept failed ?!', e) pass self.client.settimeout(8.0) log('Accepted client from', addr) try: # Parse HTTP request self.wdt.feed() request = self.client.makefile('rwb', 0) self.args = {} while True: self.wdt.feed() try: line = request.readline() self.wdt.feed() except OSError as e: if e.errno == ETIMEDOUT: log('Timeout - interrupt') break raise e if not line or line == b'\r\n': break line = line.decode() log('LINE', line.rstrip()) self.wdt.feed() # Check for GET file and args if line.startswith('GET '): line = line.split() # Parse GET request like '/page?arg1=n1&arg2=n2&...' if len(line) < 3: continue log('REQ', line[1]) if not line[1].startswith('/'): continue line = line[1][1:].split('?', 1) log('SPLIT', line) self.page = line[0] log('PAGE', self.page) if len(line) < 2: continue line = line[1].split('&') if len(line[0]) < 1: continue if line[0] == '': continue for key in line: log(key) key = key.split('=', 1) p = key[1].replace('+', ' ').split('%') t = bytearray(p[0].encode()) for k in p[1:]: t.append(int(k[0:2], 16)) t.extend(k[2:].encode()) self.args[key[0]] = t.decode() log('ARGS', self.args) except Exception as e: dump_exception('WEB page failed ?!', e) self.page = 'index' try: self._ack() self._send_page() self.client = None except OSError as e: if e.errno == ENOTCONN: log('Connection dropped')
from log import dump_exception try: print('Starting the application ...') from app import run run(b'fdd04ce7a42b3005e4d722574315b654399707a7') except KeyboardInterrupt as e: dump_exception('Interrupted by keyboard ...', e) except BaseException as e: dump_exception('!!! APPLICATION ERROR - REBOOTING !!!', e) import machine machine.reset()
def _perif(): # First of all we have to initialize watchdog if requested log('Initializing watchdog ...') from machine import WDT wdt = WDT(timeout=120000) # Reads internal temperature just after wake-up to reduce # influence of chip warm-up and use some kind of ambient # reduction to get more close to indoor temperature. This # value will be used when DTH22 or DHT11 sensor is # not found on selected pin. # # Just note that better is to connect DHT22/DTH11 for # more precise temperature measurement and also for information # about humidity. temp = ((raw_temperature() - 32) / 1.8) - 26.0 # There is LED driver for debugging purposes. LED control # is running on background and can be disabled to save # piece of battery capacity. However then there is no # other way how to signalizes in which state meteostation # is then UART. led = Led() # Disable LED when battery voltage is too low volt = battery.voltage if (volt < vbat.low_voltage): led.disable() # We shall checks if there is requested to toggle temperature alarm if jumpers.alert: alert.temp_balanced = not alert.temp_balanced if alert.temp_balanced: play((100, 50), (200, 50), (400, 50), (800, 50), (1600, 50), (3200, 50)) write('alert', (False, )) else: play((3200, 50), (1600, 50), (800, 50), (400, 50), (200, 50), (100, 50)) alert.flush() deepsleep(1) # As we uses E-Ink display, the most comfortable way # how to work with it is to define canvas object for # drawing objects and flushing them later on screen. led.mode(Led.WARM_UP) canvas = Canvas() # When battery voltage is too low, just draw low battery # error on screen and go to deep sleep. if (volt < vbat.low_voltage): led.mode(Led.ALERT) ui = MeteoUi(canvas, None, None) ui.repaint_lowbat(volt) log('Low battery !!!') _sleep(15) # Once we have canvas established (large object needs # to be created first to prevent from memory fragmentation), # we can establish WiFi connection and connect to network. led.mode(Led.DOWNLOAD) net = None try: net = Connection() log('Connected to network') except Exception as e: dump_exception('Network connection error', e) return temp, led, volt, canvas, net, wdt