Mini Pi Dash Screen

Quelques années après le Raspberry Pi Home Dash Screen j’ai eu envie d’explorer d’autres manières de réaliser un affichage simple sur de petits écrans. Dans cette article, j’explique pas à pas comment réaliser très simplement un écran d’affichage en utilisant un Raspberry Pi et la lib Python PyGame.

L’écran que vous voyez en photo est géré par un simple script en Python qui peut être adapté selon vos besoins.

Matériel utilisé

Cette fois ci, je n’ai utilisé que des éléments officiellement distribué par la fondation Raspberry Pi.

Pygame

Proposée à l’origine pour créer des jeux vidéos, la lib PyGame vous permet d’afficher très simplement texte, images et autres contenus, sans toutefois nécessiter un gestionnaire de fenêtre. Contrairement au Pi Home Dash screen qui repose sur un ensemble relativement lourd de middleware, l’utilisation de PyGame se suffit à lui même et peut fonctionner directement sur une Raspbian Lite.

Il vous faudra toutefois installer quelques paquets pour Python et Xplanet :

apt-get update
apt-get install python-pygame python-urllib3 xplanet imagemagick

Sur la screenshot ci-dessous, vous voyez plusieurs informations :

  • La date et l’heure
  • La température
  • La terre et la lune

La date et l’heure sont simplement affichée en se basant sur l’heure du système. Inutile ici de chercher quelque chose de compliqué, Python dispose de base de tout ce qu’il faut.

Température

La température est fournis par le site OpenWeatherMap.

Pour utiliser ce service, vous devez créer un compte gratuit ici :

Rendez vous ensuite dans la section API pour récupérer votre clé API.

OpenWeatherMap fournis un paquet d’informations météorologiques disponibles via une API JSON. Pour récupérer ces informations, rien de plus simple en Python :

Vous pouvez choisir la localité qui vous convient, bien entendu. Ce lien vous permettra de trouver la ville la plus proche de chez vous : https://openweathermap.org/find?q=

Xplanet

L’image de la terre et de la lune sont elles générées par Xplanet, vous savez combien j’affectionne ce soft dont je parle en détails ici : Pi Home Dash Screen – Xplanet

Pour simplifier, j’ai créé deux services, un pour la terre et un pour la lune, qui vont chacun générer une nouvelle image à intervalles réguliers. Le script Python se contera ensuite de rafraîchir les images.

Si dessous, les scripts idoines ainsi que les script systemd permettant de lancer ces sous programmes au démarrage du Pi.

xplanet.conf : Le fichier de configuration de Xplanet

[default]

arc_color=white
arc_thickness=1
bump_scale=3
cloud_gamma=1
cloud_ssec=false 
cloud_threshold=90
color={255,255,255}
draw_orbit=false                
grid=false
grid1=6
grid2=15
magnify=1                      
marker_color=red
max_radius_for_label=3 
min_radius_for_label=.01
min_radius_for_markers=40
orbit={-.5,.5,2}
orbit_color={255,255,255}       # color for the orbit
random_origin=true           
random_target=true
shade=30                        # 0 = black, 100 = same as dayside
text_color={255,0,0}            # color for text (markers & body label)
twilight=6                      # blend the day and night images for
                                # pixels within this many degrees of
                                # the terminator 

[sun]
"Sun"
color={255,255,166}
map=/root/img/sunmap.jpg
max_radius_for_label=0
shade=100

[earth]
"Earth"
color={28, 82, 110}
map=/root/img/land_ocean_ice_2048.jpg
night_map=/root/img/night-dark.jpg
cloud_map=/root/xplanet_clouds.jpg
min_radius_for_label=0

[moon]
"Moon"
color={100, 100, 100}
map=/root/img/moonmap2k.jpg

xplanet_earth.sh : pour la planète terre

#!/bin/bash

xplanet -conf /root/xplanet.conf -wait 600 -transpng /root/xplanet_earth.png -body earth -latitude 20 -longitude 10 -geometry 400x400

/etc/systemd/system/xplanetEarth.service

[Unit]
Description=xPlanet
After=network.target
After=syslog.target

[Install]
WantedBy=default.target

[Service]
ExecStart=/root/xplanet_earth.sh
StandardOutput=journal+console
User=root
Group=root
Restart=always

xplanet_moon.sh : pour la lune

#!/bin/bash

xplanet -conf /root/xplanet.conf -transpng /root/xplanet_moon.png -wait 3600 -body moon -geometry 160x160

/etc/systemd/system/xplanetMoon.service

[Unit]
Description=xPlanet
After=network.target
After=syslog.target

[Install]
WantedBy=default.target

[Service]
ExecStart=/root/xplanet_moon.sh
StandardOutput=journal+console
User=root
Group=root
Restart=always

Il vous suffira ensuite d’exécuter ces deux commandes pour lancer ces scripts au démarrage du système.

systemctl enable xplanetEarth.service
systemctl enable xplanetMoon.service

Script Python

Voyons maintenant le contenu du script principal : pi_mini_screen.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import json
import urllib3
import sys
import threading
import datetime
import time
import pygame
import signal
import random
from pygame.locals import *

###########################

screen_w = 800 # largeur en pixel de l'écran
screen_h = 480 # hauteur en pixel de l'écran

# XXX à remplacer par vos ids
openweathermap_localid = "XXXXX"
openweathermap_appid = "XXXXXXXXXXXXX"

###########################

temp = ''

def getWeather():
  global temp
  while True:
    http = urllib3.PoolManager()
    weather = http.request('GET', 'https://api.openweathermap.org/data/2.5/weather?id='+openweathermap_localid+'&units=metric&appid='+openweathermap_appid)
    weather_json = json.loads(weather.data.decode('UTF-8'))
    temp = str("%.1f" % float(weather_json['main']['temp']))
    time.sleep(60)

thread = threading.Thread(target=getWeather)
thread.daemon = True
thread.start()

def dont_quit(signal, frame):
  print 'Catch signal: {}'.format(signal)

signal.signal(signal.SIGHUP, dont_quit)

pygame.init()

pygame.mouse.set_visible(False)
pygame.display.set_caption('Liberty')
size = [screen_w, screen_h]
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
screen.fill((0, 0, 0))
pygame.display.update()

screen_width = screen.get_width()
screen_height = screen.get_height()
screen_centerx = screen.get_rect().centerx
screen_centery = screen.get_rect().centery

start_time = 0
frame_count = 1000
frame_rate = 20

bg_color = (0, 0, 0)

hour_font = pygame.font.SysFont(None, 150)
hour_color = (190, 190, 190)
date_font = pygame.font.SysFont(None, 80)
date_color = (190, 190, 190)

temp_font = pygame.font.SysFont(None, 100)
temp_color = (190, 190, 190)
degre_font = pygame.font.SysFont(None, 50)

while True:
  for event in pygame.event.get():
    if event.type == pygame.QUIT: 
      pygame.quit()
      sys.exit()

  screen.fill((0, 0, 0))

  # EARTH
  try:
    xplanet_earth = pygame.image.load(('/root/xplanet_earth.png'))
  except pygame.error, message:
    print 'Cannot load image xplanet_earth.png'
    time.sleep(1)
    continue

  xp_earth_rect = xplanet_earth.get_rect()
  xp_earth_rect.centerx = screen_centerx
  xp_earth_rect.centery = screen_centery
  screen.blit(xplanet_earth, xp_earth_rect)

  # MOON

  xplanet_moon = pygame.image.load(('/root/xplanet_moon.png'))
  xp_moon_rect = xplanet_moon.get_rect()
  xp_moon_rect.centerx = screen_width-80
  xp_moon_rect.centery = screen_height-80
  screen.blit(xplanet_moon, xp_moon_rect)

  # DATE

  now = str(time.strftime("%a %d %b"))
  dt = date_font.render(now, 1, date_color, None)
  dt_rect = dt.get_rect()
  dt_rect.x = 0
  dt_rect.y = screen_height-dt.get_height()
  screen.blit(dt, dt_rect)

  # HOUR

  now = str(time.strftime("%H:%M"))
  hour = hour_font.render(now, 1, hour_color, None)
  hour_rect = hour.get_rect()
  hour_rect.x = 0
  hour_rect.y = 0
  screen.blit(hour, hour_rect)

  # TEMP

  d = degre_font.render('°C'.decode('utf-8'), 1, temp_color, None)
  drect = d.get_rect()
  drect.x = screen_width-d.get_width()
  drect.y = 0
  screen.blit(d, drect)

  t = temp_font.render(temp.decode('utf-8'), 1, temp_color, None)
  trect = t.get_rect()
  trect.x = screen_width-t.get_width()-d.get_width()
  trect.y = 0
  screen.blit(t, trect)

  # END

  frame_count += 1 
  clock.tick(frame_rate)
  pygame.display.flip()

pygame.quit()
quit()

Lancer le script au démarrage du système

La manière la plus propre de lancer ce petit script est de laisser le système d’exploitation le gérer comme un service. Sous Raspbian, nous utilisons donc systemd et la commande systemctl comme vu précédemment pour les scripts Xplanet.

/etc/systemd/system/piMiniScreen.service

[Unit]
Description=Liberty Display
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
ExecStart=/usr/bin/python -u /root/pi_mini_screen.py
StandardOutput=journal+console
User=root
Group=root
Restart=always

Sans oublier ensuite d’activer le service au démarrage du système :

systemctl enable piMiniScreen.service

Il ne vous reste plus qu’à rebooter votre Pi 🙂

Dans le prochain article je vous montrerai comment faire tomber de la neige sur cet écran en rajoutant quelques lignes de code, à très vite !

7 réflexions au sujet de « Mini Pi Dash Screen »

  1. Ping : De la neige en Python sur votre Pi Mini Screen - MagdiBlog

  2. therm

    Bonjour, est ce que c’est comme un mode plein écran ? si jamais on veut quitter pour aller dans un fichier ou quoique ce soit, on fait comment ?

    Répondre

Laisser un commentaire

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