Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update weather app #75

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ To enable the weather display, set the environment variable `MODE` to `weather`.

Next, use either `LATLONG` (e.g. 39.9199,32.8543) or `WEATHER_LOCATION` (e.g. Ankara, Turkey) environment variables to define the location for weather information. Entering only an empty `WEATHER_LOCATION` is also sufficient and in this case Inkyshot will lookup the latitude and longitude information from device's IP address.

Set `SCALE` environment variable to `F` to display the temperature values in Fahrenheit scale. The default is Celcius scale.
Set `SCALE` environment variable to `F` to display the temperature values in Fahrenheit scale. The default is Celsius scale.

Set `TEMP_THRESHOLD` environment variable to a desired temperature. All readings above this value will be displayed in colour on colour eInk screens. The default value is 25 Celsius (77 Fahrenheit).

You can use the `WEATHER_DARK_MODE` environment variable if you want to eanble dark mode on the inkyshot.

Use the `WEATHER_FONT` variable to customize the font used in weather display mode.

Expand Down
84 changes: 70 additions & 14 deletions inkyshot/update-display.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,52 +78,75 @@ def create_mask(source):
mask_image.putpixel((x, y), 255)
return mask_image

def swap_two_colours(img, dark_mode=False):
"""Swap two colours.
"""
black = BLACK
if dark_mode:
target = BLACK - 1
else:
target = BLACK + 1
logging.info(f"Swapping colours {black} and {target}")
w, h = img.size
for x in range(w):
for y in range(h):
if img.getpixel((x, y)) == black:
img.putpixel((x, y), target)
elif img.getpixel((x, y)) == target:
img.putpixel((x, y), black)
return img

# Declare non pip fonts here ** Note: ttf files need to be in the /fonts dir of application repo
Grand9KPixel = "/usr/app/fonts/Grand9KPixel.ttf"

def draw_weather(weather, img, scale):
def draw_weather(weather, img, scale, fill):
"""Draw the weather info on screen"""
logging.info("Prepare the weather data for drawing")
# Draw today's date on left side below today's name
today = arrow.utcnow().format(fmt="DD MMMM", locale=LOCALE)
date_font = ImageFont.truetype(WEATHER_FONT, 18)
draw.text((3, 3), today, BLACK, font=date_font)
date_font = ImageFont.truetype(WEATHER_FONT, 18 + WEATHER_FONT_INCREASE)
draw.text((3 + X_OFFSET/3, 3 + Y_OFFSET), today, BLACK, font=date_font)
# Draw current temperature to right of today
temp_font = ImageFont.truetype(WEATHER_FONT, 24)
draw.text((3, 30), f"{temp_to_str(weather['temperature'], scale)}°", BLACK, font=temp_font)
temp_font = ImageFont.truetype(WEATHER_FONT, 24 + WEATHER_FONT_INCREASE)
draw.text((3 + X_OFFSET/3, 30 + Y_OFFSET), f"{temp_to_str(weather['temperature'], scale)}°", fill, font=temp_font)
# Draw today's high and low temps on left side below date
small_font = ImageFont.truetype(WEATHER_FONT, 14)
small_font = ImageFont.truetype(WEATHER_FONT, 14 + WEATHER_FONT_INCREASE)
draw.text(
(3, 72),
(3 + X_OFFSET/3, 72 + Y_OFFSET),
f"{temp_to_str(weather['min_temp'], scale)}° - {temp_to_str(weather['max_temp'], scale)}°",
BLACK,
font=small_font,
)
# Draw today's max humidity on left side below temperatures
draw.text((3, 87), f"{weather['max_humidity']}%", BLACK, font=small_font)
draw.text((3 + X_OFFSET/3, 87 + Y_OFFSET), f"{weather['max_humidity']}%", BLACK, font=small_font)
# Load weather icon
icon_name = weather['symbol'].split('_')[0]
time_of_day = ''
swap_colours = False
# Couple of symbols have different icons for day and night. Check if this symbol is one of them.
if len(weather['symbol'].split('_')) > 1:
symbol_cycle = weather['symbol'].split('_')[1]
if symbol_cycle == 'day':
time_of_day = 'd'
elif symbol_cycle == 'night':
time_of_day = 'n'
swap_colours = True
icon_filename = f"{icon_map[icon_name]:02}{time_of_day}.png"
filepath = Path(__file__).parent / 'weather-icons' / icon_filename
icon_image = Image.open(filepath)
icon_mask = create_mask(icon_image)
if swap_colours:
logging.info("Swapping night weather icon black and colour pixels")
icon_image = swap_two_colours(icon_image)
# Draw the weather icon
if WEATHER_INVERT and WAVESHARE:
icon_mask = create_mask(icon_image)
logging.info("Inverting Weather Icon")
icon = Image.new('1', (100, 100), 255)
icon.paste(icon_image, (0,0), icon_mask)
icon_inverted = ImageOps.invert(icon.convert('RGB'))
img.paste(icon_inverted, (120, 3))
img.paste(icon_inverted, (119 + X_OFFSET, 3 + Y_OFFSET))
else:
img.paste(icon_image, (120, 3), icon_mask)
img.paste(icon_image, (119 + X_OFFSET, 3 + Y_OFFSET))
return img

def get_current_display():
Expand Down Expand Up @@ -225,11 +248,15 @@ def set_current_display(val):
logging.error(f"Failed to set current display to {val}. Error is: {err}")

def temp_to_str(temp, scale):
"""Prepare the temperature to draw based on the defined scale: Celcius or Fahrenheit"""
"""Prepare the temperature to draw based on the defined scale: Celsius or Fahrenheit"""
if scale == 'F':
temp = temp * 9/5 + 32
temp = celsius_to_fahrenheit(temp)
return f"{temp:.1f}"

def celsius_to_fahrenheit(temp):
"""Convert Celsius to Fahrenheit"""
return temp * 9/5 + 32

# Read the preset environment variables and overwrite the default ones
if "DEBUG" in os.environ:
logging.basicConfig(level=logging.DEBUG)
Expand Down Expand Up @@ -268,6 +295,11 @@ def temp_to_str(temp, scale):
# Temperature scale
SCALE = 'F' if "SCALE" in os.environ and os.environ["SCALE"] == 'F' else 'C'

# Temperature threshold above which T is displayed in colour
TEMP_THRESHOLD = 25 if SCALE == 'C' else celsius_to_fahrenheit(25)
if "TEMP_THRESHOLD" in os.environ:
TEMP_THRESHOLD = os.environ['TEMP_THRESHOLD']

# Locale formatting of date
LOCALE = os.environ["LOCALE"] if "LOCALE" in os.environ else 'en'

Expand Down Expand Up @@ -306,6 +338,22 @@ def temp_to_str(temp, scale):
HEIGHT = display.HEIGHT
BLACK = display.BLACK
WHITE = display.WHITE
COLOUR = BLACK if display.colour == "black" else display.RED
if HEIGHT == 104:
# Display size: W 212 x H 104
X_OFFSET = 0
Y_OFFSET = 0
WEATHER_FONT_INCREASE = 0
else:
# Display size: W 250 x H 122
# text margin is 3 + 1/3*X_OFFSET = 10 pixels from left border
# weather icon is 250 - (120 + 21 + 100) = 9 pixels from right border
X_OFFSET = 21
# centering weather icons along y-axis:
# default padding is 3 => 3+8 + 100 (weather icon height) + 3+8 = 122 pixels
# thus, an addition offset of 8 pixels places the weather icon in the middle
Y_OFFSET = 8
WEATHER_FONT_INCREASE = 2
img = Image.new("P", (WIDTH, HEIGHT))

draw = ImageDraw.Draw(img)
Expand Down Expand Up @@ -340,7 +388,9 @@ def temp_to_str(temp, scale):
os.environ['LATLONG'] = f"{LAT},{LONG}"
# If weather is empty dictionary, fall back to drawing quote
if len(weather) > 0:
img = draw_weather(weather, img, SCALE)
temperature = weather['temperature'] if SCALE == 'C' else celsius_to_fahrenheit(weather['temperature'])
fill = COLOUR if temperature >= TEMP_THRESHOLD else BLACK
img = draw_weather(weather, img, SCALE, fill)
else:
target_display = 'quote'
elif target_display == 'quote':
Expand Down Expand Up @@ -415,6 +465,12 @@ def temp_to_str(temp, scale):
if "ROTATE" in os.environ:
img = img.rotate(180)

# Enable dark mode
# #(it swaps the colour of the first two pixels in the palette)
if "WEATHER_DARK_MODE" in os.environ and target_display == 'weather':
logging.info("Switching to dark mode")
img = swap_two_colours(img, dark_mode=True)

if WAVESHARE:
# epd does not have a set_image method.
display.display(display.getbuffer(img))
Expand Down
Binary file modified inkyshot/weather-icons/01d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/01n.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/02d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/02n.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/03d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/03n.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/05d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/05n.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/06d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/06n.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/07d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/07n.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/08d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/08n.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/09.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/13.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/14.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/20d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/20n.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/21d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified inkyshot/weather-icons/21n.png
Binary file modified inkyshot/weather-icons/22.png
Binary file modified inkyshot/weather-icons/23.png
Binary file modified inkyshot/weather-icons/24d.png
Binary file modified inkyshot/weather-icons/24n.png
Binary file modified inkyshot/weather-icons/25d.png
Binary file modified inkyshot/weather-icons/25n.png
Binary file modified inkyshot/weather-icons/26d.png
Binary file modified inkyshot/weather-icons/26n.png
Binary file modified inkyshot/weather-icons/27d.png
Binary file modified inkyshot/weather-icons/27n.png
Binary file modified inkyshot/weather-icons/28d.png
Binary file modified inkyshot/weather-icons/28n.png
Binary file modified inkyshot/weather-icons/29d.png
Binary file modified inkyshot/weather-icons/29n.png
Binary file modified inkyshot/weather-icons/30.png
Binary file modified inkyshot/weather-icons/31.png
Binary file modified inkyshot/weather-icons/32.png
Binary file modified inkyshot/weather-icons/33.png
Binary file modified inkyshot/weather-icons/34.png
Binary file modified inkyshot/weather-icons/40d.png
Binary file modified inkyshot/weather-icons/40n.png
Binary file modified inkyshot/weather-icons/41d.png
Binary file modified inkyshot/weather-icons/41n.png
Binary file modified inkyshot/weather-icons/42d.png
Binary file modified inkyshot/weather-icons/42n.png
Binary file modified inkyshot/weather-icons/43d.png
Binary file modified inkyshot/weather-icons/43n.png
Binary file modified inkyshot/weather-icons/44d.png
Binary file modified inkyshot/weather-icons/44n.png
Binary file modified inkyshot/weather-icons/45d.png
Binary file modified inkyshot/weather-icons/45n.png
Binary file modified inkyshot/weather-icons/46.png
Binary file modified inkyshot/weather-icons/47.png
Binary file modified inkyshot/weather-icons/48.png
Binary file modified inkyshot/weather-icons/49.png
Binary file modified inkyshot/weather-icons/50.png
1 change: 1 addition & 0 deletions repo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type: generic