/ EInk_Bonnet_Weather_Station / weather_graphics.py
weather_graphics.py
  1  # SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  from datetime import datetime
  6  import json
  7  from PIL import Image, ImageDraw, ImageFont
  8  from adafruit_epd.epd import Adafruit_EPD
  9  
 10  small_font = ImageFont.truetype(
 11      "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 16
 12  )
 13  medium_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 20)
 14  large_font = ImageFont.truetype(
 15      "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 24
 16  )
 17  icon_font = ImageFont.truetype("./meteocons.ttf", 48)
 18  
 19  # Map the OpenWeatherMap icon code to the appropriate font character
 20  # See http://www.alessioatzeni.com/meteocons/ for icons
 21  ICON_MAP = {
 22      "01d": "B",
 23      "01n": "C",
 24      "02d": "H",
 25      "02n": "I",
 26      "03d": "N",
 27      "03n": "N",
 28      "04d": "Y",
 29      "04n": "Y",
 30      "09d": "Q",
 31      "09n": "Q",
 32      "10d": "R",
 33      "10n": "R",
 34      "11d": "Z",
 35      "11n": "Z",
 36      "13d": "W",
 37      "13n": "W",
 38      "50d": "J",
 39      "50n": "K",
 40  }
 41  
 42  # RGB Colors
 43  WHITE = (255, 255, 255)
 44  BLACK = (0, 0, 0)
 45  
 46  
 47  class Weather_Graphics:
 48      def __init__(self, display, *, am_pm=True, celsius=True):
 49          self.am_pm = am_pm
 50          self.celsius = celsius
 51  
 52          self.small_font = small_font
 53          self.medium_font = medium_font
 54          self.large_font = large_font
 55  
 56          self.display = display
 57  
 58          self._weather_icon = None
 59          self._city_name = None
 60          self._main_text = None
 61          self._temperature = None
 62          self._description = None
 63          self._time_text = None
 64  
 65      def display_weather(self, weather):
 66          weather = json.loads(weather.decode("utf-8"))
 67  
 68          # set the icon/background
 69          self._weather_icon = ICON_MAP[weather["weather"][0]["icon"]]
 70  
 71          city_name = weather["name"] + ", " + weather["sys"]["country"]
 72          print(city_name)
 73          self._city_name = city_name
 74  
 75          main = weather["weather"][0]["main"]
 76          print(main)
 77          self._main_text = main
 78  
 79          temperature = weather["main"]["temp"] - 273.15  # its...in kelvin
 80          print(temperature)
 81          if self.celsius:
 82              self._temperature = "%d °C" % temperature
 83          else:
 84              self._temperature = "%d °F" % ((temperature * 9 / 5) + 32)
 85  
 86          description = weather["weather"][0]["description"]
 87          description = description[0].upper() + description[1:]
 88          print(description)
 89          self._description = description
 90          # "thunderstorm with heavy drizzle"
 91  
 92          self.update_time()
 93  
 94      def update_time(self):
 95          now = datetime.now()
 96          self._time_text = now.strftime("%I:%M %p").lstrip("0").replace(" 0", " ")
 97          self.update_display()
 98  
 99      def update_display(self):
100          self.display.fill(Adafruit_EPD.WHITE)
101          image = Image.new("RGB", (self.display.width, self.display.height), color=WHITE)
102          draw = ImageDraw.Draw(image)
103  
104          # Draw the Icon
105          (font_width, font_height) = icon_font.getsize(self._weather_icon)
106          draw.text(
107              (
108                  self.display.width // 2 - font_width // 2,
109                  self.display.height // 2 - font_height // 2 - 5,
110              ),
111              self._weather_icon,
112              font=icon_font,
113              fill=BLACK,
114          )
115  
116          # Draw the city
117          draw.text(
118              (5, 5), self._city_name, font=self.medium_font, fill=BLACK,
119          )
120  
121          # Draw the time
122          (font_width, font_height) = medium_font.getsize(self._time_text)
123          draw.text(
124              (5, font_height * 2 - 5),
125              self._time_text,
126              font=self.medium_font,
127              fill=BLACK,
128          )
129  
130          # Draw the main text
131          (font_width, font_height) = large_font.getsize(self._main_text)
132          draw.text(
133              (5, self.display.height - font_height * 2),
134              self._main_text,
135              font=self.large_font,
136              fill=BLACK,
137          )
138  
139          # Draw the description
140          (font_width, font_height) = small_font.getsize(self._description)
141          draw.text(
142              (5, self.display.height - font_height - 5),
143              self._description,
144              font=self.small_font,
145              fill=BLACK,
146          )
147  
148          # Draw the temperature
149          (font_width, font_height) = large_font.getsize(self._temperature)
150          draw.text(
151              (
152                  self.display.width - font_width - 5,
153                  self.display.height - font_height * 2,
154              ),
155              self._temperature,
156              font=self.large_font,
157              fill=BLACK,
158          )
159  
160          self.display.image(image)
161          self.display.display()