From 9ded8e28a69df48fe02e82caed7cd48e4be02b8d Mon Sep 17 00:00:00 2001 From: Tait Berlette <54515877+taitberlette@users.noreply.github.com> Date: Tue, 30 Mar 2021 19:10:24 -0400 Subject: [PATCH] Added weather application. Signed-off-by: Tait Berlette <54515877+taitberlette@users.noreply.github.com> --- README.rst | 4 + docs/apps.rst | 2 + res/WeatherApp.png | Bin 0 -> 10888 bytes res/weather_icon.png | Bin 0 -> 688 bytes wasp/apps/software.py | 1 + wasp/apps/weather.py | 164 ++++++++++++++++++++++++++++++++ wasp/boards/manifest_240x240.py | 1 + wasp/boards/simulator/main.py | 8 ++ wasp/gadgetbridge.py | 2 + wasp/wasp.py | 4 + 10 files changed, 186 insertions(+) create mode 100644 res/WeatherApp.png create mode 100644 res/weather_icon.png create mode 100644 wasp/apps/weather.py diff --git a/README.rst b/README.rst index b6dbc0e..90343e8 100644 --- a/README.rst +++ b/README.rst @@ -224,6 +224,10 @@ application (and the "blank" white screen is a torch application): :alt: Countdown timer application running in the wasp-os simulator :width: 179 +.. image:: res/WeatherApp.png + :alt: Weather application running in the wasp-os simulator + :width: 179 + .. image:: res/WordClkApp.png :alt: Shows a time as words in the wasp-os simulator :width: 179 diff --git a/docs/apps.rst b/docs/apps.rst index 01e1e16..350c5d5 100644 --- a/docs/apps.rst +++ b/docs/apps.rst @@ -53,6 +53,8 @@ Applications .. automodule:: apps.timer +.. automodule:: apps.weather + Games ----- diff --git a/res/WeatherApp.png b/res/WeatherApp.png new file mode 100644 index 0000000000000000000000000000000000000000..a143775c5e88df123a7a6f8f1ef8f82d2b7376be GIT binary patch literal 10888 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 literal 0 HcmV?d00001 diff --git a/res/weather_icon.png b/res/weather_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..44b86ec648f9cbabfe4473e3f5c08e3b7b255a74 GIT binary patch literal 688 zcmeAS@N?(olHy`uVBq!ia0vp^2|(1!UAf~R$LVWcza#7A&1b}(tn=6QzVY~=M6r>i z-S5A4&g=i_@wYoqdn~E(;Lu#AO+EXgm&bByc+Zgk;CKUE)U_PvcdAXG73#mi+nlgfjOO1p$7Fx5|4 z7|9#Ud7)vw?m}tCSszSQ0~#vs7I|No(X~sULE>*zr~@OXXhLxC>IG4Z@7{Xcmo|^qh{CoX>@0{g3G#xCOf)7VB zu4EDZtf?TFkY&ZXM9AmFb1ex&DIZ3PP>2ng3~0u=;aB|i)R1T_t+#n zkBPrkL@9|k&ts#>etwR|4I;u?I@{#AI#icWacA^WNS?j0A)?5uQe**((KbmW;Y>FN zorX!DR#iuL?UvN$T=pd*;KSR(751}U%!_%epXYSwzRLlPC1!#dAC$!_SUpbf-Tp&| z$*ZPtwdnlEZ+Awr+?cHE>%{kCb{zAam90#AE)k6Xm6gL;|1d5M{w^?CN@4~uB{F!r L`njxgN@xNAg;gFK literal 0 HcmV?d00001 diff --git a/wasp/apps/software.py b/wasp/apps/software.py index bc345b5..dcc412e 100644 --- a/wasp/apps/software.py +++ b/wasp/apps/software.py @@ -49,6 +49,7 @@ class SoftwareApp(): db.append(('flashlight', factory('Torch'))) db.append(('testapp', factory('Test'))) db.append(('timer', factory('Timer'))) + db.append(('weather', factory('Weather'))) db.append(('word_clock', factory('Word Clock'))) # Get the initial state for the checkboxes diff --git a/wasp/apps/weather.py b/wasp/apps/weather.py new file mode 100644 index 0000000..2e44da4 --- /dev/null +++ b/wasp/apps/weather.py @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2020 Daniel Thompson +# Copyright (C) 2020 Carlos Gil + +"""Weather for GadgetBridge and wasp-os companion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + .. figure:: res/WeatherApp.png + :width: 179 + + Screenshot of the Weather application + +""" + +import wasp + +import icons +import time +import fonts.sans36 + +# 2-bit RLE, generated from res/weather_icon.png, 309 bytes +icon = ( + b'\x02' + b'`@' + b'\x1e\xa4<\xa4<\xa4;\xa5?Y\xec2\xf0/\xf2-' + b'\xf4,\xc3@;n\xc3,\xc3n\xc3,\xc3n\xc3,' + b'\xc3n\xc3,\xc3n\xc3,\xc3n\xc3,\xc3n\xc3,' + b'\xc3n\xc3,\xc3n\xc3,\xc3O\x80\xd3\x87X\xc3,' + b'\xc3M\x8bV\xc3,\xc3K\x8fT\xc3,\xc3J\x91S' + b'\xc3,\xc3I\x93R\xc3,\xc3H\x95Q\xc3,\xc3H' + b'\x95Q\xc3,\xc3G\x97P\xc3,\xc3G\x97P\xc3+' + b'\xc4F\x99O\xc3*\xc5F\x99O\xc3*\xc5F\x99O' + b'\xc3*\xc5F\x99O\xc3*\xc5F\x99O\xc3*\xc5F' + b'\x99\xc4K\xc3*\xc5F\x8e\xc5\x84\xc1\x81\xc5J\xc3*' + b'\xc5G\x8c\xc8\x81\xcaH\xc3+\xc4G\x83\xc5\x83\xd6F' + b'\xc3,\xc3H\x81\xe0E\xc3,\xc3G\xe2E\xc3,\xc3' + b'G\xe3D\xc3,\xc3F\xe4D\xc3,\xc3F\xe4D\xc3' + b',\xc3F\xe4D\xc3,\xc3F\xe4D\xc3,\xc3F\xe3' + b'E\xc3,\xc3G\xe2E\xc3,\xc3G\xe1F\xc3,\xc3' + b'H\xc9A\xccC\xc5H\xc3,\xc3J\xc5E\xc9Q\xc3' + b',\xc3V\xc5S\xc3,\xc3n\xc3,\xc3n\xc3,\xc3' + b'n\xc3,\xc3n\xc3,\xc3n\xc3,\xc3n\xc3,\xf4' + b'-\xf2/\xf02\xec?X\xc0\xdb\xe6;\xe4<\xe4<' + b'\xe4\x1e' +) + +class WeatherApp(object): + """ Weather application.""" + NAME = 'Weather' + ICON = icon + + def __init__(self): + self._temp = '' + self._hum = '' + self._txt = '' + self._wind = '' + self._loc = '' + self._temp_changed = True + self._hum_changed = True + self._txt_changed = True + self._wind_changed = True + self._loc_changed = True + + def foreground(self): + """Activate the application.""" + temp = wasp.system.weatherinfo.get('temp') + hum = wasp.system.weatherinfo.get('hum') + txt = wasp.system.weatherinfo.get('txt') + wind = wasp.system.weatherinfo.get('wind') + loc = wasp.system.weatherinfo.get('loc') + if temp: + self._temp = temp + if hum: + self._hum = hum + if txt: + self._txt = txt + if wind: + self._wind = wind + if loc: + self._loc = loc + wasp.watch.drawable.fill() + self.draw() + wasp.system.request_tick(1000) + + def background(self): + """De-activate the application (without losing state).""" + self._temp_changed = True + self._hum_changed = True + self._txt_changed = True + self._wind_changed = True + self._loc_changed = True + + def tick(self, ticks): + wasp.system.keep_awake() + temp_now = wasp.system.weatherinfo.get('temp') + hum_now = wasp.system.weatherinfo.get('hum') + txt_now = wasp.system.weatherinfo.get('txt') + wind_now = wasp.system.weatherinfo.get('wind') + loc_now = wasp.system.weatherinfo.get('loc') + if temp_now: + if temp_now != self._temp: + self._temp = temp_now + self._temp_changed = True + else: + self._temp_changed = False + if hum_now: + if hum_now != self._hum: + self._hum = hum_now + self._hum_changed = True + else: + self._hum_changed = False + if txt_now: + if txt_now != self._txt: + self._txt = txt_now + self._txt_changed = True + else: + self._txt_changed = False + if wind_now: + if wind_now != self._wind: + self._wind = wind_now + self._wind_changed = True + else: + self._wind_changed = False + if loc_now: + if loc_now != self._loc: + self._loc = loc_now + self._loc_changed = True + else: + self._loc_changed = False + wasp.system.weatherinfo = {} + self._update() + + def draw(self): + """Redraw the display from scratch.""" + self._draw() + + def _draw(self): + """Redraw the updated zones.""" + if self._temp_changed: + self._draw_label(self._temp, 54, 36) + if self._hum_changed: + self._draw_label("Humidity: "+self._hum, 160) + if self._txt_changed: + self._draw_label(self._txt, 12) + if self._wind_changed: + self._draw_label("Wind: "+self._wind, 120) + if self._loc_changed: + self._draw_label(self._loc, 200) + + def _draw_label(self, label, pos, size = 24): + """Redraw label info""" + if label: + draw = wasp.watch.drawable + draw.reset() + if size == 36: + draw.set_font(fonts.sans36) + + draw.string(label, 0, pos, 240) + + def _update(self): + self._draw() + + def update(self): + pass diff --git a/wasp/boards/manifest_240x240.py b/wasp/boards/manifest_240x240.py index ccd4f64..2f59436 100644 --- a/wasp/boards/manifest_240x240.py +++ b/wasp/boards/manifest_240x240.py @@ -24,6 +24,7 @@ manifest = ( 'apps/snake.py', 'apps/testapp.py', 'apps/timer.py', + 'apps/weather.py', 'apps/word_clock.py', 'fonts/__init__.py', 'fonts/clock.py', diff --git a/wasp/boards/simulator/main.py b/wasp/boards/simulator/main.py index 78a1168..618fae5 100644 --- a/wasp/boards/simulator/main.py +++ b/wasp/boards/simulator/main.py @@ -13,6 +13,14 @@ wasp.system.set_music_info({ 'artist': 'Dreams of Bamboo', }) +wasp.system.set_weather_info({ + 'temp': '22', + 'hum': '100%', + 'txt': 'Cloudy', + 'wind': '25km/h', + 'loc': 'Toronto' +}) + # Increase the display blanking time to avoid spamming the console # with backlight activations. diff --git a/wasp/gadgetbridge.py b/wasp/gadgetbridge.py index 18285ab..dc5479a 100644 --- a/wasp/gadgetbridge.py +++ b/wasp/gadgetbridge.py @@ -56,6 +56,8 @@ def GB(cmd): wasp.system.toggle_music(cmd) elif task == 'musicinfo': wasp.system.set_music_info(cmd) + elif task == 'weather': + wasp.system.set_weather_info(cmd) else: pass #_info('Command "{}" is not implemented'.format(cmd)) diff --git a/wasp/wasp.py b/wasp/wasp.py index abcb974..5b1a8b8 100644 --- a/wasp/wasp.py +++ b/wasp/wasp.py @@ -117,6 +117,7 @@ class Manager(): self.notifications = {} self.musicstate = {} self.musicinfo = {} + self.weatherinfo = {} self._theme = ( b'\x7b\xef' # ble @@ -320,6 +321,9 @@ class Manager(): def set_music_info(self, info): self.musicinfo = info + def set_weather_info(self, info): + self.weatherinfo = info + def set_alarm(self, time, action): """Queue an alarm.