Thonthon : mon PI compagnon – Part two

Thonthon : mon PI compagnon – Part two

Petit bricolage d’une station météo. L’idée est d’affichier sur le pHat une alternance heure / météo. Pour se faire je me suis basé sur l’exemple “clock.py” auquel j’ai rajouté une connexion à l’API pyowm. Voici le principe :

Le code est assez simple. En gros :
1. On check s’il existe une connexion internet
2. Si oui, on met à jour la ville courrante basée sur l’adresse IP publique (si indisponible, prendre la ville par défaut)
3. On lance de façon alternée l’heure (5 secondes) et la météo (~11 secondes)
4. La météo lancée affiche la température, la vitesse du vent et le pourcentage d’humidité dans l’air.

#!/usr/bin/env python

import time
import json
import pyowm
import requests
import scrollphathd

from datetime import datetime
from scrollphathd.fonts import font5x5, font5x7

print("""
Scroll pHAT HD: Clock

Displays weather, hours and minutes in text,
plus a seconds progress bar.

Press Ctrl+C to exit!

""")

# Display a progress bar for seconds
# Displays a dot if False
DISPLAY_BAR = True

# Brightness of the seconds bar and text
BRIGHTNESS = 0.2

# API Key for Weather forecast and minutes allowed between requests
API_KEY = "XXX"
WEATHER_INTERVAL = 65*60
# Weather location
weather_loc = "Paris,fr"

# Uncomment the below if your display is upside down
#   (e.g. if you're using it in a Pimoroni Scroll Bot)
scrollphathd.rotate(degrees=180)
scrollphathd.set_brightness(BRIGHTNESS)


def check_net():
    try:
        response = requests.get("http://www.google.com")
        print("Internet OK")
    except requests.ConnectionError:
        print("Could not connect to Internet")
        return False
    return True


def show_clock(duration: int=5) -> None:
    print("Running show_clock for", duration, "seconds")

    scrollphathd.set_font(font5x5)
    sec = abs(datetime.timestamp(datetime.now()))
    while abs(datetime.timestamp(datetime.now())) - sec < duration:
        scrollphathd.clear()
        # Grab the "seconds" component of the current time
        # and convert it to a range from 0.0 to 1.0
        float_sec = (time.time() % 60) / 59.0

        # Multiply our range by 15 to spread the current
        # number of seconds over 15 pixels.
        #
        # 60 is evenly divisible by 15, so that
        # each fully lit pixel represents 4 seconds.
        #
        # For example this is 28 seconds:
        # [x][x][x][x][x][x][x][ ][ ][ ][ ][ ][ ][ ][ ]
        #  ^ - 0 seconds                59 seconds - ^
        seconds_progress = float_sec * 15

        if DISPLAY_BAR:
            # Step through 15 pixels to draw the seconds bar
            for y in range(15):
                # For each pixel, we figure out its brightness by
                # seeing how much of "seconds_progress" is left to draw
                # If it's greater than 1 (full brightness) then we just display 1.
                current_pixel = min(seconds_progress, 1)

                # Multiply the pixel brightness (0.0 to 1.0) by our global brightness value
                scrollphathd.set_pixel(y + 1, 6, current_pixel)

                # Subtract 1 now we've drawn that pixel
                seconds_progress -= 1

                # If we reach or pass 0, there are no more pixels left to draw
                if seconds_progress <= 0:
                    break

        else:
            # Just display a simple dot
            scrollphathd.set_pixel(int(seconds_progress), 6, 1)

        # Display the time (HH:MM) in a 5x5 pixel font
        scrollphathd.write_string(time.strftime("%H:%M"), 0, 0)

        # int(time.time()) % 2 will tick between 0 and 1 every second.
        # We can use this fact to clear the ":" and cause it to blink on/off
        # every other second, like a digital clock.
        # To do this we clear a rectangle 8 pixels along, 0 down,
        # that's 1 pixel wide and 5 pixels tall.
        if int(time.time()) % 2 == 0:
            scrollphathd.clear_rect(8, 0, 1, 5)

        # Display our time and sleep a bit. Using 1 second in time.sleep
        # is not recommended, since you might get quite far out of phase
        # with the passing of real wall-time seconds and it'll look weird!
        #
        # 1/10th of a second is accurate enough for a simple clock though :D
        scrollphathd.show()
        time.sleep(0.1)


def show_weather(weather, duration: int=5) -> None:
    print("Running show_weather for", duration, "seconds")
    print("Location: " + weather_loc)
    scrollphathd.clear()
    scrollphathd.set_font(font5x7)
    # Set scrolling speed
    speed=0.05

    # Get weather data
    t_metric = "°C"
    w_metric = "km/h"
    h_metric = "%"
    temp = "0"
    humidity = "0"
    wind = "0"

    if weather:
        temp = str(weather.get_temperature('celsius')['temp'])
        wind = str(round(weather.get_wind(unit='meters_sec')['speed']*3.6))
        humidity = str(weather.get_humidity())

    weather_info = (
        "  "
        + temp + t_metric + " "
        + wind + w_metric + " "
        + humidity + h_metric
    )
    # Display the weather in a 5x5 pixel font
    scrollphathd.write_string(weather_info)

    timer = 0
    while timer < (duration / (2*speed)):
        scrollphathd.show()
        scrollphathd.scroll(1)
        time.sleep(speed)
        timer += 1


def update_location() -> None:
    # Update geo location
    data_content = requests.get("http://ipinfo.io/json")
    loc_data = json.loads(data_content.content.decode())
    country = loc_data['country'].lower()
    city = loc_data['city']
    weather_loc = city + "," + country


while True:
    try:
        print("Rolling Barrel")
        # Fetch time to check for weather every 65 minutes
        weather = None
        if check_net():
            update_location()
            owm = pyowm.OWM(API_KEY)
            observation = owm.weather_at_place(weather_loc)
            weather = observation.get_weather()
        sec_timer = abs(datetime.timestamp(datetime.now()))
        while abs(datetime.timestamp(datetime.now())) - sec_timer < WEATHER_INTERVAL:
            # Alternate betweek clock and weather
            show_clock(5)
            show_weather(weather, 11)
            time.sleep(0.1)
    except (KeyboardInterrupt, SystemExit):
        print("Exiting...")
        exit()

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.