/ PyPortal_OpenWeather / openweather_graphics.py
openweather_graphics.py
  1  # SPDX-FileCopyrightText: 2019 Limor Fried for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  import time
  6  import json
  7  import displayio
  8  from adafruit_display_text.label import Label
  9  from adafruit_bitmap_font import bitmap_font
 10  
 11  cwd = ("/"+__file__).rsplit('/', 1)[0] # the current working directory (where this file is)
 12  
 13  small_font = cwd+"/fonts/Arial-12.bdf"
 14  medium_font = cwd+"/fonts/Arial-16.bdf"
 15  large_font = cwd+"/fonts/Arial-Bold-24.bdf"
 16  
 17  class OpenWeather_Graphics(displayio.Group):
 18      def __init__(self, root_group, *, am_pm=True, celsius=True):
 19          super().__init__()
 20          self.am_pm = am_pm
 21          self.celsius = celsius
 22  
 23          root_group.append(self)
 24          self._icon_group = displayio.Group()
 25          self.append(self._icon_group)
 26          self._text_group = displayio.Group()
 27          self.append(self._text_group)
 28  
 29          self._icon_sprite = None
 30          self._icon_file = None
 31          self.set_icon(cwd+"/weather_background.bmp")
 32  
 33          self.small_font = bitmap_font.load_font(small_font)
 34          self.medium_font = bitmap_font.load_font(medium_font)
 35          self.large_font = bitmap_font.load_font(large_font)
 36          glyphs = b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,.: '
 37          self.small_font.load_glyphs(glyphs)
 38          self.medium_font.load_glyphs(glyphs)
 39          self.large_font.load_glyphs(glyphs)
 40          self.large_font.load_glyphs(('°',))  # a non-ascii character we need for sure
 41          self.city_text = None
 42  
 43          self.time_text = Label(self.medium_font)
 44          self.time_text.x = 200
 45          self.time_text.y = 12
 46          self.time_text.color = 0xFFFFFF
 47          self._text_group.append(self.time_text)
 48  
 49          self.temp_text = Label(self.large_font)
 50          self.temp_text.x = 200
 51          self.temp_text.y = 195
 52          self.temp_text.color = 0xFFFFFF
 53          self._text_group.append(self.temp_text)
 54  
 55          self.main_text = Label(self.large_font)
 56          self.main_text.x = 10
 57          self.main_text.y = 195
 58          self.main_text.color = 0xFFFFFF
 59          self._text_group.append(self.main_text)
 60  
 61          self.description_text = Label(self.small_font)
 62          self.description_text.x = 10
 63          self.description_text.y = 225
 64          self.description_text.color = 0xFFFFFF
 65          self._text_group.append(self.description_text)
 66  
 67      def display_weather(self, weather):
 68          weather = json.loads(weather)
 69  
 70          # set the icon/background
 71          weather_icon = weather['weather'][0]['icon']
 72          self.set_icon(cwd+"/icons/"+weather_icon+".bmp")
 73  
 74          city_name =  weather['name'] + ", " + weather['sys']['country']
 75          print(city_name)
 76          if not self.city_text:
 77              self.city_text = Label(self.medium_font, text=city_name)
 78              self.city_text.x = 10
 79              self.city_text.y = 12
 80              self.city_text.color = 0xFFFFFF
 81              self._text_group.append(self.city_text)
 82  
 83          self.update_time()
 84  
 85          main_text = weather['weather'][0]['main']
 86          print(main_text)
 87          self.main_text.text = main_text
 88  
 89          temperature = weather['main']['temp'] - 273.15 # its...in kelvin
 90          print(temperature)
 91          if self.celsius:
 92              self.temp_text.text = "%d °C" % temperature
 93          else:
 94              self.temp_text.text = "%d °F" % ((temperature * 9 / 5) + 32)
 95  
 96          description = weather['weather'][0]['description']
 97          description = description[0].upper() + description[1:]
 98          print(description)
 99          self.description_text.text = description
100          # "thunderstorm with heavy drizzle"
101  
102      def update_time(self):
103          """Fetch the time.localtime(), parse it out and update the display text"""
104          now = time.localtime()
105          hour = now[3]
106          minute = now[4]
107          format_str = "%d:%02d"
108          if self.am_pm:
109              if hour >= 12:
110                  hour -= 12
111                  format_str = format_str+" PM"
112              else:
113                  format_str = format_str+" AM"
114              if hour == 0:
115                  hour = 12
116          time_str = format_str % (hour, minute)
117          print(time_str)
118          self.time_text.text = time_str
119  
120      def set_icon(self, filename):
121          """The background image to a bitmap file.
122  
123          :param filename: The filename of the chosen icon
124  
125          """
126          print("Set icon to ", filename)
127          if self._icon_group:
128              self._icon_group.pop()
129  
130          if not filename:
131              return  # we're done, no icon desired
132  
133          # CircuitPython 6 & 7 compatible
134          if self._icon_file:
135              self._icon_file.close()
136          self._icon_file = open(filename, "rb")
137          icon = displayio.OnDiskBitmap(self._icon_file)
138          self._icon_sprite = displayio.TileGrid(
139              icon, pixel_shader=getattr(icon, 'pixel_shader', displayio.ColorConverter()))
140  
141          # # CircuitPython 7+ compatible
142          # icon = displayio.OnDiskBitmap(filename)
143          # self._icon_sprite = displayio.TileGrid(icon, pixel_shader=background.pixel_shader)
144  
145          self._icon_group.append(self._icon_sprite)