def process(self): log('*** PAGE ***', self.page) if (self.page == '') or (self.last == self.page): self.page = 'index' try: page = __import__('web.{}'.format(self.page), None, None, ('page', ), 0).page except ImportError: log('!!! Page {} not found !!!'.format(self.page)) page = __import__('web.index', None, None, ('page', ), 0).page if not self.last == self.page: self.last = self.page play((1047, 30), 120, (1568, 30)) s = BytesIO() for p in page(self): if isinstance(p, WebServer.IndexDrawer): for q in __import__('web.index', None, None, ('page', ), 0).page(self): self.wdt.feed() self.writer.write(q) self.wdt.feed() else: self.wdt.feed() self.writer.write(p) self.wdt.feed() self.wdt.feed() self.writer.flush() self.wdt.feed()
async def main(): majorC=RTTTL('10:d=4,o=5,b=180:c,d,e,f,g,a,b,c6') #C major scale anthem=RTTTL('10:d=16,o=5,b=90:2g,e,4c,4e,4g,2c6,8e6,d6,4c6,4e,4f#,2g') #nat'l anthem buzzer.play(majorC) #buzzer.play(anthem)
def _read1(self, connection, ui): # Download hourly weather forecast for today url = 'http://api.openweathermap.org/data/2.5/onecall?lat={}&lon={}&APPID={}&mode=json&units={}&lang={}&exclude={}' fcast = connection.http_get_json( url.format(location[connection.config.location].lat, location[connection.config.location].lon, ui.apikey, ui.units, ui.language, 'minutely,hourly,daily')) # Parse todays forecast try: if not fcast['cod'] == 0: log('Server commu8nication error - can not load forecast!') try: log('Server reported:') log(' ', fcast['message']) log('') log('Go into configuration mode to set server correctly') except: pass play((400, 1000), (200, 1000), (400, 1000), (200, 1000), (400, 1000), (200, 1000)) deepsleep() except: pass current = fcast['current'] try: rain = current['rain']['1h'] except KeyError: rain = 0.0 try: snow = current['snow']['1h'] except KeyError: snow = 0.0 self.time_zone = fcast['timezone_offset'] weather = current['weather'][0] dsc = weather['description'] self.descr = dsc[0].upper() + dsc[1:] # Fix rain icon according to amount of rain def _mk_id(id, rain): return id if id != 500 or rain < 0.5 else 520 self.weather = Forecast.Weather( '{}{}'.format(id2icon[self._mk_id(weather['id'], rain)], weather['icon'][-1]), current['dt'], current['temp'], current['feels_like'], current['humidity'], rain, snow, current['wind_speed'], current['wind_deg']) self.time = Time(self.time_zone) # Set RTC clock according to forecast time rtc = RTC() dt = self.time.get_date_time(self.weather.dt) rtc.init((dt[0], dt[1], dt[2], 0, dt[3], dt[4], dt[5], 0))
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 _hotspot(canvas, net, led, volt, wdt): play((2093, 30), 120, (2093, 30)) led.mode(Led.DOWNLOAD) ui = MeteoUi(canvas, None, net) ui.repaint_config(led, volt) led.mode(Led.DOWNLOAD) server = WebServer(net, wdt) play((1047, 30), 120, (1319, 30), 120, (1568, 30), 120, (2093, 30)) server.run() reset()
def dump_exception(msg, e): print(msg) print_exception(e) if EXCEPTION_DUMP > 0: pos = _log.tell() if pos < EXCEPTION_DUMP : dt = RTC().datetime() _log.write(f'\n{dt[2]}.{dt[1]}.{dt[0]} {dt[4]}:{dt[5]:02} :: ') _log.write(msg) _log.write('\n') print_exception(e, _log) _log.flush() if alert.error_beep: play((200, 500), (100, 500))
def _allerts(forecast): if not alert.temp_balanced: return if temp.indoor_high > forecast.home.temp: return h = forecast.time.get_date_time(forecast.weather.dt)[3] if h == 13: write('alert', (False, )) return if not alert_var.ALREADY_TRIGGERED and forecast.home.temp > forecast.weather.temp: for i in range(3): play((4000, 30), (6000, 30), (4000, 30), (6000, 30), (4000, 30), (6000, 30), (4000, 30), (6000, 30), 500) write('alert', (True, ))
def process(self): print('*** PAGE ***', self.page) if (self.page == '') or (self.last == self.page): self.page = 'index' try: page = __import__('web.{}'.format(self.page), None, None, ('page', ), 0).page except ImportError: print('!!! Page {} not found !!!'.format(self.page)) return if not self.last == self.page: self.last = self.page play(((1047, 30), (0, 120), (1568, 30))) if page(self): page = __import__('web.index', None, None, ('page', ), 0).page page(self)
def _restart(msg): self.wdt.feed() log(msg) play((2093, 30), 120, (1568, 30), 120, (1319, 30), 120, (1047, 30)) write('mode', (1, ), force=True) deepsleep(1)
global animation_type if pressed: animation_type = 1 elif animation_type == 1: animation_type = 0 def btnB(pressed): global animation_type if pressed: animation_type = 2 elif animation_type == 2: animation_type = 0 def btnC(pressed): global animation_type if pressed: animation_type = 3 elif animation_type == 3: animation_type = 0 buttons.attach(buttons.BTN_0, btnB) buttons.attach(buttons.BTN_1, btnA) buttons.attach(buttons.BTN_BOOT, btnC) song = "20thCenFox:d=16,o=5,b=140:b,8p,b,b,2b,p,c6,32p,b,32p,c6,32p,b,32p,c6,32p,b,8p,b,b,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,g#,32p,a,32p,b,8p,b,b,2b,4p,8e,8g#,8b,1c#6,8f#,8a,8c#6,1e6,8a,8c#6,8e6,1e6,8b,8g#,8a,2b" buzzer.play(song)
def page(web): play((2093, 30), 120, (1568, 30), 120, (1319, 30), 120, (1047, 30)) write('display', (DISPLAY_GREETINGS,)) 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
def page(web): play((2093, 30), 120, (1568, 30), 120, (1319, 30), 120, (1047, 30)) reset()
def playSong(): song = "20thCenFox:d=16,o=5,b=140:b,8p,b,b,2b,p,c6,32p,b,32p,c6,32p,b,32p,c6,32p,b,8p,b,b,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,g#,32p,a,32p,b,8p,b,b,2b,4p,8e,8g#,8b,1c#6,8f#,8a,8c#6,1e6,8a,8c#6,8e6,1e6,8b,8g#,8a,2b" buzzer.play(song)