2013-09-19 22:44:29 +02:00
|
|
|
#! /usr/bin/env python3.3
|
|
|
|
|
|
|
|
# Auteur : Phyks (phyks@phyks.me)
|
|
|
|
# Site web : http://phyks.me
|
|
|
|
# Licence : BEERWARE
|
|
|
|
|
|
|
|
# Description :
|
|
|
|
# =============
|
|
|
|
# Récupérer et afficher la météo et le nombre de vélibs aux stations
|
|
|
|
# prédéfinies sur un écran LCD nokia 3310 (connecté via les pins GPIO)
|
|
|
|
# Plus d'informations sur le montage :
|
|
|
|
# http://blog.idleman.fr/raspberry-pi-11-relier-a-un-ecran-et-afficher-du-texte
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import urllib3
|
|
|
|
import xml.etree.ElementTree as ET
|
|
|
|
import datetime
|
2013-09-19 23:15:32 +02:00
|
|
|
import wiringpi2
|
|
|
|
|
|
|
|
# ===========
|
|
|
|
# Pins du LCD
|
|
|
|
# ===========
|
|
|
|
|
|
|
|
PIN_SCE = 3
|
|
|
|
PIN_RESET = 4
|
|
|
|
PIN_DC = 5
|
|
|
|
PIN_SDIN = 6
|
|
|
|
PIN_SCLK = 7
|
|
|
|
|
|
|
|
LCD_C = HIGH
|
|
|
|
LCD_D = LOW
|
|
|
|
LCD_X = 84
|
|
|
|
LCD_Y = 48
|
|
|
|
|
|
|
|
|
|
|
|
ASCII = [
|
|
|
|
[0x00, 0x00, 0x00, 0x00, 0x00], # 20 " "
|
|
|
|
[0x00, 0x00, 0x5f, 0x00, 0x00], # 21 !
|
|
|
|
[0x00, 0x07, 0x00, 0x07, 0x00], # 22 "
|
|
|
|
[0x14, 0x7f, 0x14, 0x7f, 0x14], # 23 #
|
|
|
|
[0x24, 0x2a, 0x7f, 0x2a, 0x12], # 24 $
|
|
|
|
[0x23, 0x13, 0x08, 0x64, 0x62], # 25 %
|
|
|
|
[0x36, 0x49, 0x55, 0x22, 0x50], # 26 &
|
|
|
|
[0x00, 0x05, 0x03, 0x00, 0x00], # 27 '
|
|
|
|
[0x00, 0x1c, 0x22, 0x41, 0x00], # 28 (
|
|
|
|
[0x00, 0x41, 0x22, 0x1c, 0x00], # 29 )
|
|
|
|
[0x14, 0x08, 0x3e, 0x08, 0x14], # 2a *
|
|
|
|
[0x08, 0x08, 0x3e, 0x08, 0x08], # 2b +
|
|
|
|
[0x00, 0x50, 0x30, 0x00, 0x00], # 2c ,
|
|
|
|
[0x08, 0x08, 0x08, 0x08, 0x08], # 2d -
|
|
|
|
[0x00, 0x60, 0x60, 0x00, 0x00], # 2e .
|
|
|
|
[0x20, 0x10, 0x08, 0x04, 0x02], # 2f /
|
|
|
|
[0x3e, 0x51, 0x49, 0x45, 0x3e], # 30 0
|
|
|
|
[0x00, 0x42, 0x7f, 0x40, 0x00], # 31 1
|
|
|
|
[0x42, 0x61, 0x51, 0x49, 0x46], # 32 2
|
|
|
|
[0x21, 0x41, 0x45, 0x4b, 0x31], # 33 3
|
|
|
|
[0x18, 0x14, 0x12, 0x7f, 0x10], # 34 4
|
|
|
|
[0x27, 0x45, 0x45, 0x45, 0x39], # 35 5
|
|
|
|
[0x3c, 0x4a, 0x49, 0x49, 0x30], # 36 6
|
|
|
|
[0x01, 0x71, 0x09, 0x05, 0x03], # 37 7
|
|
|
|
[0x36, 0x49, 0x49, 0x49, 0x36], # 38 8
|
|
|
|
[0x06, 0x49, 0x49, 0x29, 0x1e], # 39 9
|
|
|
|
[0x00, 0x36, 0x36, 0x00, 0x00], # 3a :
|
|
|
|
[0x00, 0x56, 0x36, 0x00, 0x00], # 3b ;
|
|
|
|
[0x08, 0x14, 0x22, 0x41, 0x00], # 3c <
|
|
|
|
[0x14, 0x14, 0x14, 0x14, 0x14], # 3d =
|
|
|
|
[0x00, 0x41, 0x22, 0x14, 0x08], # 3e >
|
|
|
|
[0x02, 0x01, 0x51, 0x09, 0x06], # 3f ?
|
|
|
|
[0x32, 0x49, 0x79, 0x41, 0x3e], # 40 @
|
|
|
|
[0x7e, 0x11, 0x11, 0x11, 0x7e], # 41 A
|
|
|
|
[0x7f, 0x49, 0x49, 0x49, 0x36], # 42 B
|
|
|
|
[0x3e, 0x41, 0x41, 0x41, 0x22], # 43 C
|
|
|
|
[0x7f, 0x41, 0x41, 0x22, 0x1c], # 44 D
|
|
|
|
[0x7f, 0x49, 0x49, 0x49, 0x41], # 45 E
|
|
|
|
[0x7f, 0x09, 0x09, 0x09, 0x01], # 46 F
|
|
|
|
[0x3e, 0x41, 0x49, 0x49, 0x7a], # 47 G
|
|
|
|
[0x7f, 0x08, 0x08, 0x08, 0x7f], # 48 H
|
|
|
|
[0x00, 0x41, 0x7f, 0x41, 0x00], # 49 I
|
|
|
|
[0x20, 0x40, 0x41, 0x3f, 0x01], # 4a J
|
|
|
|
[0x7f, 0x08, 0x14, 0x22, 0x41], # 4b K
|
|
|
|
[0x7f, 0x40, 0x40, 0x40, 0x40], # 4c L
|
|
|
|
[0x7f, 0x02, 0x0c, 0x02, 0x7f], # 4d M
|
|
|
|
[0x7f, 0x04, 0x08, 0x10, 0x7f], # 4e N
|
|
|
|
[0x3e, 0x41, 0x41, 0x41, 0x3e], # 4f O
|
|
|
|
[0x7f, 0x09, 0x09, 0x09, 0x06], # 50 P
|
|
|
|
[0x3e, 0x41, 0x51, 0x21, 0x5e], # 51 Q
|
|
|
|
[0x7f, 0x09, 0x19, 0x29, 0x46], # 52 R
|
|
|
|
[0x46, 0x49, 0x49, 0x49, 0x31], # 53 S
|
|
|
|
[0x01, 0x01, 0x7f, 0x01, 0x01], # 54 T
|
|
|
|
[0x3f, 0x40, 0x40, 0x40, 0x3f], # 55 U
|
|
|
|
[0x1f, 0x20, 0x40, 0x20, 0x1f], # 56 V
|
|
|
|
[0x3f, 0x40, 0x38, 0x40, 0x3f], # 57 W
|
|
|
|
[0x63, 0x14, 0x08, 0x14, 0x63], # 58 X
|
|
|
|
[0x07, 0x08, 0x70, 0x08, 0x07], # 59 Y
|
|
|
|
[0x61, 0x51, 0x49, 0x45, 0x43], # 5a Z
|
|
|
|
[0x00, 0x7f, 0x41, 0x41, 0x00], # 5b [
|
|
|
|
[0x02, 0x04, 0x08, 0x10, 0x20], # 5c ¥
|
|
|
|
[0x00, 0x41, 0x41, 0x7f, 0x00], # 5d ]
|
|
|
|
[0x04, 0x02, 0x01, 0x02, 0x04], # 5e ^
|
|
|
|
[0x40, 0x40, 0x40, 0x40, 0x40], # 5f _
|
|
|
|
[0x00, 0x01, 0x02, 0x04, 0x00], # 60 `
|
|
|
|
[0x20, 0x54, 0x54, 0x54, 0x78], # 61 a
|
|
|
|
[0x7f, 0x48, 0x44, 0x44, 0x38], # 62 b
|
|
|
|
[0x38, 0x44, 0x44, 0x44, 0x20], # 63 c
|
|
|
|
[0x38, 0x44, 0x44, 0x48, 0x7f], # 64 d
|
|
|
|
[0x38, 0x54, 0x54, 0x54, 0x18], # 65 e
|
|
|
|
[0x08, 0x7e, 0x09, 0x01, 0x02], # 66 f
|
|
|
|
[0x0c, 0x52, 0x52, 0x52, 0x3e], # 67 g
|
|
|
|
[0x7f, 0x08, 0x04, 0x04, 0x78], # 68 h
|
|
|
|
[0x00, 0x44, 0x7d, 0x40, 0x00], # 69 i
|
|
|
|
[0x20, 0x40, 0x44, 0x3d, 0x00], # 6a j
|
|
|
|
[0x7f, 0x10, 0x28, 0x44, 0x00], # 6b k
|
|
|
|
[0x00, 0x41, 0x7f, 0x40, 0x00], # 6c l
|
|
|
|
[0x7c, 0x04, 0x18, 0x04, 0x78], # 6d m
|
|
|
|
[0x7c, 0x08, 0x04, 0x04, 0x78], # 6e n
|
|
|
|
[0x38, 0x44, 0x44, 0x44, 0x38], # 6f o
|
|
|
|
[0x7c, 0x14, 0x14, 0x14, 0x08], # 70 p
|
|
|
|
[0x08, 0x14, 0x14, 0x18, 0x7c], # 71 q
|
|
|
|
[0x7c, 0x08, 0x04, 0x04, 0x08], # 72 r
|
|
|
|
[0x48, 0x54, 0x54, 0x54, 0x20], # 73 s
|
|
|
|
[0x04, 0x3f, 0x44, 0x40, 0x20], # 74 t
|
|
|
|
[0x3c, 0x40, 0x40, 0x20, 0x7c], # 75 u
|
|
|
|
[0x1c, 0x20, 0x40, 0x20, 0x1c], # 76 v
|
|
|
|
[0x3c, 0x40, 0x30, 0x40, 0x3c], # 77 w
|
|
|
|
[0x44, 0x28, 0x10, 0x28, 0x44], # 78 x
|
|
|
|
[0x0c, 0x50, 0x50, 0x50, 0x3c], # 79 y
|
|
|
|
[0x44, 0x64, 0x54, 0x4c, 0x44], # 7a z
|
|
|
|
[0x00, 0x08, 0x36, 0x41, 0x00], # 7b {
|
|
|
|
[0x00, 0x00, 0x7f, 0x00, 0x00], # 7c |
|
|
|
|
[0x00, 0x41, 0x36, 0x08, 0x00], # 7d ]
|
|
|
|
[0x10, 0x08, 0x08, 0x10, 0x08], # 7e ?
|
|
|
|
[0x78, 0x46, 0x41, 0x46, 0x78], # 7f ?
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def writeLCD(dc, data):
|
|
|
|
wiringpi2.digitalWrite(PIN_DC, dc)
|
|
|
|
wiringpi2.digitalWrite(PIN_SCE, LOW)
|
|
|
|
wiringpi2.shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data)
|
|
|
|
wiringpi2.digitalWrite(PIN_SCE, HIGH)
|
|
|
|
|
|
|
|
|
|
|
|
def characterLCD(character):
|
|
|
|
writeLCD(LCD_D, 0x00)
|
|
|
|
for i in range(0, 5):
|
|
|
|
writeLCD(ASCII[character - 0x20][i])
|
|
|
|
writeLCD(LCD_D, 0x00)
|
|
|
|
|
|
|
|
|
|
|
|
def stringLCD(string):
|
|
|
|
for character in string:
|
|
|
|
characterLCD(character)
|
|
|
|
|
|
|
|
|
|
|
|
def initLCD():
|
|
|
|
wiringpi2.pinMode(PIN_SCE, OUTPUT)
|
|
|
|
wiringpi2.pinMode(PIN_RESET, OUTPUT)
|
|
|
|
wiringpi2.pinMode(PIN_DC, OUTPUT)
|
|
|
|
wiringpi2.pinMode(PIN_SDIN, OUTPUT)
|
|
|
|
wiringpi2.pinMode(PIN_SCLK, OUTPUT)
|
|
|
|
wiringpi2.digitalWrite(PIN_RESET, LOW)
|
|
|
|
wiringpi2.digitalWrite(PIN_RESET, HIGH)
|
|
|
|
|
|
|
|
wiringpi2.writeLCD(LCD_C, 0x21) # LCD Extended commands
|
|
|
|
wiringpi2.writeLCD(LCD_C, 0x98) # Set LCD Vop (contrast)
|
|
|
|
wiringpi2.writeLCD(LCD_C, 0x04) # Set Temp coefficient
|
|
|
|
wiringpi2.writeLCD(LCD_C, 0x13) # LCD bias mode (1:48)
|
|
|
|
wiringpi2.writeLCD(LCD_C, 0x0C) # LCD in normal mode
|
|
|
|
wiringpi2.writeLCD(LCD_C, 0x20)
|
|
|
|
wiringpi2.writeLCD(LCD_C, 0x0C)
|
|
|
|
|
|
|
|
|
|
|
|
def clearLCD():
|
|
|
|
for i in range(0, LCD_X*LCD_Y/8):
|
|
|
|
writeLCD(LCD_D, 0x00)
|
|
|
|
characterLCD(' ')
|
2013-09-19 22:44:29 +02:00
|
|
|
|
|
|
|
# ==========
|
|
|
|
# Paramètres
|
|
|
|
# ==========
|
|
|
|
|
|
|
|
if(len(sys.argv) == 1):
|
|
|
|
exit('Vous devez fournir au moins un numéro de station en argument.')
|
|
|
|
|
|
|
|
stations = []
|
|
|
|
for station in sys.argv[1:]:
|
|
|
|
stations.append(int(station))
|
|
|
|
|
|
|
|
base_url = ('http://www.velib.paris.fr/service/stationdetails/paris/')
|
|
|
|
|
|
|
|
# =============================
|
|
|
|
# Initialisation des librairies
|
|
|
|
# =============================
|
|
|
|
http = urllib3.PoolManager()
|
|
|
|
|
|
|
|
# ====
|
|
|
|
# Date
|
|
|
|
# ====
|
|
|
|
now = datetime.datetime.now()
|
|
|
|
date = now.strftime('%d/%m/%Y')
|
|
|
|
time = now.strftime('%H:%M')
|
|
|
|
|
|
|
|
# =======================
|
|
|
|
# Requête sur l'API Vélib
|
|
|
|
# =======================
|
|
|
|
available = {}
|
|
|
|
free = {}
|
|
|
|
for station in stations:
|
|
|
|
r = http.request('GET', base_url+str(station))
|
|
|
|
|
|
|
|
if r.status == 200:
|
|
|
|
station_xml = ET.fromstring(r.data)
|
|
|
|
|
|
|
|
for child in station_xml.iter('available'):
|
|
|
|
available[station] = child.text
|
|
|
|
for child in station_xml.iter('free'):
|
|
|
|
free[station] = child.text
|
|
|
|
|
|
|
|
else:
|
|
|
|
available[station] = -1
|
|
|
|
free[station] = -1
|
|
|
|
|
|
|
|
# ==================================
|
|
|
|
# Requête pour les prédictions météo
|
|
|
|
# ==================================
|
2013-10-01 14:51:33 +02:00
|
|
|
url_weather = ('http://api.openweathermap.org/data/2.5/forecast' +
|
|
|
|
'?q=Paris,fr&mode=xml&lang=fr&units=metric')
|
2013-09-19 22:44:29 +02:00
|
|
|
r = http.request('GET', url_weather)
|
|
|
|
|
|
|
|
weather_now = ''
|
|
|
|
temp_now = -1
|
2013-10-01 14:51:33 +02:00
|
|
|
weather_3h = ''
|
|
|
|
temp_3h = -1
|
|
|
|
weather_6h = ''
|
|
|
|
temp_6h = -1
|
|
|
|
weather_9h = ''
|
|
|
|
temp_9h = -1
|
2013-09-19 22:44:29 +02:00
|
|
|
|
|
|
|
if r.status == 200:
|
|
|
|
weather_xml = ET.fromstring(r.data)
|
|
|
|
|
|
|
|
for child in weather_xml.iter('forecast'):
|
2013-10-01 14:51:33 +02:00
|
|
|
for time in child.iter('time'):
|
|
|
|
time_from = datetime.datetime.strptime(time.attrib['from'],
|
|
|
|
"%Y-%m-%dT%H:%M:%S")
|
|
|
|
time_to = datetime.datetime.strptime(time.attrib['to'],
|
|
|
|
"%Y-%m-%dT%H:%M:%S")
|
|
|
|
|
|
|
|
if time_to > now and time_from < now:
|
|
|
|
weather_now = time.find('clouds').attrib['value']
|
|
|
|
temp_now = time.find('temperature').attrib['value']
|
|
|
|
|
|
|
|
if (time_to > now + datetime.timedelta(hours=3) and
|
|
|
|
time_from < now+datetime.timedelta(hours=3)):
|
|
|
|
weather_3h = time.find('clouds').attrib['value']
|
|
|
|
temp_3h = time.find('temperature').attrib['value']
|
|
|
|
|
|
|
|
if (time_to > now+datetime.timedelta(hours=6) and
|
|
|
|
time_from < now+datetime.timedelta(hours=6)):
|
|
|
|
weather_6h = time.find('clouds').attrib['value']
|
|
|
|
temp_6h = time.find('temperature').attrib['value']
|
|
|
|
|
|
|
|
if (time_to > now+datetime.timedelta(hours=9) and
|
|
|
|
time_from < now+datetime.timedelta(hours=9)):
|
|
|
|
weather_9h = time.find('clouds').attrib['value']
|
|
|
|
temp_9h = time.find('temperature').attrib['value']
|
|
|
|
|
2013-09-19 22:44:29 +02:00
|
|
|
|
|
|
|
# ============================
|
|
|
|
# Afficher les infos à l'écran
|
|
|
|
# ============================
|
2013-09-19 23:15:32 +02:00
|
|
|
|
|
|
|
wiringpi2.wiringPiSetup
|
|
|
|
|
|
|
|
initLCD()
|
|
|
|
clearLCD()
|