Ajout du support de la camera du Raspberry Pi

Séparation de la partie configuration du module "commun"
This commit is contained in:
Pierrick C 2017-09-18 22:37:04 +02:00
parent b1ca8a9190
commit e897b59d1f
5 changed files with 164 additions and 87 deletions

View File

@ -11,14 +11,26 @@ sql_verbose = 0
[MQTT] [MQTT]
mqtt_host = aro-yuno mqtt_host = aro-yuno
mqtt_port = 1883 mqtt_port = 1883
mqtt_client_id = mqtt2sql mqtt_client_id = cameteo
mqtt_user = arofarn mqtt_user = arofarn
mqtt_pass = WaKaW9XMGUZ3rRJD mqtt_pass = WaKaW9XMGUZ3rRJD
mqtt_qos = 1 mqtt_qos = 2
mqtt_topic = huzzah0/# mqtt_topic = huzzah0/#
[CAMERA] [CAMERA]
camera_mqtt_topic = raspi0/camera camera_mqtt_topic = raspi0/camera
camera_resolution_x=2592
camera_resolution_y=1944
camera_warmup_time=2
camera_iso=0
camera_rotation=0
camera_auto_white_balance=auto
camera_exposure_mode=auto
camera_contrast=0
photo_dir=/home/pi/Cameteo/photos/
photo_name=test_%%Y%%m%%d_%%H%%M%%S
photo_format=jpeg
[MISC] [MISC]
TimeZone = 0 TimeZone=2

View File

@ -11,48 +11,9 @@ Created on Fri Aug 18 21:35:59 2017
# IMPORTS # # IMPORTS #
########### ###########
from datetime import datetime, timedelta from cameteo_conf import *
from configparser import ConfigParser
from flask import Flask from flask import Flask
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
import os, sys
#################
# CONFIGURATION #
#################
script_path = os.path.dirname(sys.argv[0])
script_dir = os.path.abspath(script_path)
parser = ConfigParser()
parser.read(script_dir + '/cameteo.conf')
#Misc
TimeZone = parser['MISC'].get('TimeZone', fallback=0)
#SQL
sql_host = parser['SQL'].get('sql_host', fallback='localhost')
sql_port = parser['SQL'].get('sql_port', fallback=3306)
sql_base = parser['SQL'].get('sql_base', fallback='cameteo')
sql_user = parser['SQL'].get('sql_user', fallback='cameteo')
sql_pass = parser['SQL'].get('sql_pass', fallback='oetemac')
sql_sys = parser['SQL'].get('sql_sys', fallback='mysql')
sql_api = parser['SQL'].get('sql_api', fallback='pymysql')
sql_verbose = bool(int(parser['SQL'].get('sql_verbose', fallback=0)))
sql_uri = sql_sys + '+' + sql_api + '://' + sql_user + ':' + sql_pass + '@' + sql_host + ':' + sql_port + '/' + sql_base
#MQTT
mqtt_host = parser['MQTT'].get('mqtt_host', fallback='localhost')
mqtt_port = int(parser['MQTT'].get('mqtt_port', fallback=1883))
mqtt_client_id = parser['MQTT'].get('mqtt_client_id', fallback='mqtt2sql')
mqtt_user = parser['MQTT'].get('mqtt_user', fallback='cameteo')
mqtt_pass = parser['MQTT'].get('mqtt_pass', fallback='oetemac')
mqtt_qos = parser['MQTT'].get('mqtt_qos', fallback=0)
mqtt_topic = parser['MQTT'].get('mqtt_topic', fallback='sensors/#')
#Camera
camera_mqtt_topic = parser['CAMERA'].get('camera_mqtt_topic', fallback='raspi0/camera')
##################### #####################
# Flask & SQLAchemy # # Flask & SQLAchemy #

View File

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
"""
Configuration du projet Camétéo
Created on Fri Aug 18 21:35:59 2017
@author: arofarn
"""
###########
# IMPORTS #
###########
from datetime import datetime, timedelta, timezone
from configparser import SafeConfigParser
import os, sys
#################
# CONFIGURATION #
#################
script_path = os.path.dirname(sys.argv[0])
script_dir = os.path.abspath(script_path)
parser = SafeConfigParser(allow_no_value=True)
parser.read(script_dir + '/cameteo.conf')
#Misc
TimeZone = timezone(timedelta(hours=int(parser['MISC'].get('TimeZone', fallback=0))))
#SQL
sql_host = parser['SQL'].get('sql_host', fallback='localhost')
sql_port = parser['SQL'].get('sql_port', fallback=3306)
sql_base = parser['SQL'].get('sql_base', fallback='cameteo')
sql_user = parser['SQL'].get('sql_user', fallback='cameteo')
sql_pass = parser['SQL'].get('sql_pass', fallback='oetemac')
sql_sys = parser['SQL'].get('sql_sys', fallback='mysql')
sql_api = parser['SQL'].get('sql_api', fallback='pymysql')
sql_verbose = bool(int(parser['SQL'].get('sql_verbose', fallback=0)))
sql_uri = sql_sys + '+' + sql_api + '://' + sql_user + ':' + sql_pass + '@' + sql_host + ':' + sql_port + '/' + sql_base
#MQTT
mqtt_host = parser['MQTT'].get('mqtt_host', fallback='localhost')
mqtt_port = int(parser['MQTT'].get('mqtt_port', fallback=1883))
mqtt_client_id = parser['MQTT'].get('mqtt_client_id', fallback='mqtt2sql')
mqtt_user = parser['MQTT'].get('mqtt_user', fallback='cameteo')
mqtt_pass = parser['MQTT'].get('mqtt_pass', fallback='oetemac')
mqtt_auth = {'username' : mqtt_user, 'password' : mqtt_pass}
mqtt_qos = parser['MQTT'].get('mqtt_qos', fallback=0)
mqtt_topic = parser['MQTT'].get('mqtt_topic', fallback='sensors/#')
#Camera
camera_mqtt_topic = parser['CAMERA'].get('camera_mqtt_topic', fallback='raspi0/camera')
camera_resolution_x = int(parser['CAMERA'].get('camera_resolution_x', fallback='800'))
camera_resolution_y = int(parser['CAMERA'].get('camera_resolution_y', fallback='600'))
camera_resolution = (camera_resolution_x, camera_resolution_y)
camera_warmup_time = int(parser['CAMERA'].get('camera_warmup_time', fallback=2))
camera_iso = int(parser['CAMERA'].get('camera_iso', fallback=0))
camera_awb = parser['CAMERA'].get('camera_auto_white_balance', fallback='auto')
camera_expo_mode = parser['CAMERA'].get('camera_exposure_mode', fallback='auto')
camera_rotation = int(parser['CAMERA'].get('camera_rotation', fallback=0))
camera_contrast = int(parser['CAMERA'].get('camera_contrast', fallback=0))
photo_dir = parser['CAMERA'].get('photo_dir', fallback='/home/pi/photos/')
photo_name = parser['CAMERA'].get('photo_name', fallback='%%Y%%m%%d_%%H%%M%%S')
photo_format = parser['CAMERA'].get('photo_format', fallback='jpg')

View File

@ -1,19 +1,15 @@
# Affichage de données arrivant sur un MQTT # -*- coding: utf-8 -*-
# sur un écran ePaper """
# Auteur : Arofarn Display data from MQTT broker on ePaper screen
# v0.1
#################
# Configuration #
#################
@author: arofarn
"""
########### ###########
# IMPORTS # # IMPORTS #
########### ###########
from cameteo import * from cameteo_conf import *
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
from spidev import SpiDev from spidev import SpiDev
import EPD_driver import EPD_driver
@ -31,8 +27,9 @@ def on_connect(client, userdata, flags, rc):
print(mqtt.connack_string(rc)) print(mqtt.connack_string(rc))
if rc == 0: if rc == 0:
print("Subscribing to %s ..." % mqtt_topic) print("Subscribing to %s ..." % mqtt_topic)
client.subscribe(mqtt_topic) client.subscribe([(mqtt_topic, 0),
client.subscribe(camera_mqtt_topic + "/#") (camera_mqtt_topic + "/#", 0)]
)
print("OK") print("OK")
#Callback de gestion des messages arrivant au MQTT : #Callback de gestion des messages arrivant au MQTT :
@ -70,13 +67,20 @@ def on_message_date(client, userdata, msg):
print("Date : " + payload) print("Date : " + payload)
try: try:
d = datetime.strptime(payload, "%H:%M:%S %d/%m/%Y") d = datetime.strptime(payload, "%H:%M:%S %d/%m/%Y")
disp.Dis_String(0, 17, d.strftime("%d/%m/%Y %H:%M:%S"), 16) disp.Dis_String(0, 17, datetime.strftime(d + TimeZone.utcoffset(None), "%d/%m/%Y %H:%M:%S"), 16)
except: except:
disp.Dis_String(0, 17, payload, 16) disp.Dis_String(0, 17, payload, 16)
#Update display with info from camera (camera shooting new photo or name of the
# last photo)
def on_message_camera(client, userdata, msg): def on_message_camera(client, userdata, msg):
print(msg) pl = msg.payload.decode()
print("{} : {} ({})".format(msg.topic, pl, type(pl)))
if pl == "1" and msg.topic == camera_mqtt_topic + "/shooting" :
disp.Dis_String(0, 105, "Shooting photo... ", 16)
if msg.topic == camera_mqtt_topic + "/last_photo":
disp.Dis_String(0, 105, "Last: " + pl, 16)
#Callback de déconnexion au broker MQTT #Callback de déconnexion au broker MQTT
def on_disconnect(client, userdata, msg): def on_disconnect(client, userdata, msg):
if msg != 0: if msg != 0:

View File

@ -1,59 +1,92 @@
#!/usr/bin/python3 #!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Take a picture with the Pi Camera module and publish the path
and name of the file on a MQTT broker
# Take a picture with the Pi Camera module and publish the path @author: arofarn
# and name of the file on a MQTT broker """
import picamera import picamera
import paho.mqtt.publish as mqtt import paho.mqtt.publish as mqtt
from time import sleep from time import sleep
import datetime from cameteo_conf import *
mqtt_client_id = "picamera"
# Camera settings
camera_resolution=(2592, 1944)
camera_warmup_time=2 #in seconds
#camera_iso=800
# MQTT settings
mqtt_server = 'localhost'
mqtt_port= 1883
mqtt_auth= {'username':'cameteo',
'password':'CaMeteo'}
mqtt_client_id= 'picamera2mqtt'
mqtt_qos=2
# Photo parameters
photo_path = '/home/pi/photos/'
photo_format = 'jpg'
photo_mqtt_topic = 'pi/picamera/'
######## ########
# Main # # Main #
######## ########
file_date = datetime.datetime.now().replace(microsecond=0).isoformat() photo_extensions = {'jpeg': 'jpg',
file_name = file_date + "." + photo_format 'png' : 'png',
'gif': 'gif',
'bmp': 'bmp',
'yuv': 'yuv',
'rgb': 'rgb',
'rgba': 'rgba'}
if not(os.path.exists(photo_dir)):
print("Create photos directory : " + photo_dir)
os.mkdir(photo_dir)
file_name = datetime.strftime(datetime.now(), photo_name) + os.path.extsep + photo_extensions[photo_format]
file_path = os.path.join(photo_dir, file_name)
print("Shooting " + file_path)
# Taking a photo # Taking a photo
################# #################
# Tell the MQTT that we start shooting
mqtt.single(camera_mqtt_topic + "/shooting" ,
payload= 1 ,
qos= 1 ,
retain= True ,
hostname= mqtt_host ,
port= mqtt_port ,
client_id= mqtt_client_id ,
auth= mqtt_auth )
# Camera settings
cam = picamera.PiCamera(resolution = camera_resolution) cam = picamera.PiCamera(resolution = camera_resolution)
cam.iso = camera_iso
cam.awb_mode = camera_awb
cam.rotation = camera_rotation
cam.contrast = camera_contrast
cam.exposure_mode = camera_expo_mode
cam.image_effect = 'none'
#Add some EXIF tags
cam.exif_tags['EXIF.UserComment'] = 'Cameteo !'
# Warm-up # Warm-up
cam.start_preview() cam.start_preview()
sleep(camera_warmup_time) sleep(camera_warmup_time)
print(photo_path+file_name) cam.capture(file_path, format=photo_format, quality=95, thumbnail=None)
cam.capture(photo_path+file_name) cam.close()
# MQTT publication # MQTT publication
################### ###################
mqtt_data = [{'topic':photo_mqtt_topic+"path", 'payload':photo_path, 'qos':mqtt_qos, 'retain':False},
{'topic':photo_mqtt_topic+"last_photo_name", 'payload':file_name, 'qos':mqtt_qos, 'retain':False}, mqtt_data = [{'topic': camera_mqtt_topic + "/shooting",
{'topic':photo_mqtt_topic+"last_photo_date", 'payload':file_date, 'qos':mqtt_qos, 'retain':False}] 'payload': 0,
'qos': 2,
'retain': True},
{'topic': camera_mqtt_topic + "/last_photo",
'payload': file_name,
'qos': 2,
'retain': True},
{'topic': camera_mqtt_topic + "/photos_path",
'payload': photo_dir,
'qos': 2,
'retain': True},
]
mqtt.multiple(mqtt_data, mqtt.multiple(mqtt_data,
hostname= mqtt_server , hostname= mqtt_host ,
port= mqtt_port , port= mqtt_port ,
client_id= mqtt_client_id , client_id= mqtt_client_id ,
auth= mqtt_auth ) auth= mqtt_auth )