Ajout du support de la camera du Raspberry Pi
Séparation de la partie configuration du module "commun"
This commit is contained in:
parent
b1ca8a9190
commit
e897b59d1f
@ -11,14 +11,26 @@ sql_verbose = 0
|
||||
[MQTT]
|
||||
mqtt_host = aro-yuno
|
||||
mqtt_port = 1883
|
||||
mqtt_client_id = mqtt2sql
|
||||
mqtt_client_id = cameteo
|
||||
mqtt_user = arofarn
|
||||
mqtt_pass = WaKaW9XMGUZ3rRJD
|
||||
mqtt_qos = 1
|
||||
mqtt_qos = 2
|
||||
mqtt_topic = huzzah0/#
|
||||
|
||||
[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]
|
||||
TimeZone = 0
|
||||
TimeZone=2
|
||||
|
@ -11,48 +11,9 @@ Created on Fri Aug 18 21:35:59 2017
|
||||
# IMPORTS #
|
||||
###########
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from configparser import ConfigParser
|
||||
from cameteo_conf import *
|
||||
from flask import Flask
|
||||
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 #
|
||||
|
67
cameteo-interface/cameteo_conf.py
Normal file
67
cameteo-interface/cameteo_conf.py
Normal 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')
|
@ -1,19 +1,15 @@
|
||||
# Affichage de données arrivant sur un MQTT
|
||||
# sur un écran ePaper
|
||||
# Auteur : Arofarn
|
||||
# v0.1
|
||||
|
||||
#################
|
||||
# Configuration #
|
||||
#################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Display data from MQTT broker on ePaper screen
|
||||
|
||||
@author: arofarn
|
||||
"""
|
||||
|
||||
###########
|
||||
# IMPORTS #
|
||||
###########
|
||||
|
||||
from cameteo import *
|
||||
from cameteo_conf import *
|
||||
import paho.mqtt.client as mqtt
|
||||
from spidev import SpiDev
|
||||
import EPD_driver
|
||||
@ -31,8 +27,9 @@ def on_connect(client, userdata, flags, rc):
|
||||
print(mqtt.connack_string(rc))
|
||||
if rc == 0:
|
||||
print("Subscribing to %s ..." % mqtt_topic)
|
||||
client.subscribe(mqtt_topic)
|
||||
client.subscribe(camera_mqtt_topic + "/#")
|
||||
client.subscribe([(mqtt_topic, 0),
|
||||
(camera_mqtt_topic + "/#", 0)]
|
||||
)
|
||||
print("OK")
|
||||
|
||||
#Callback de gestion des messages arrivant au MQTT :
|
||||
@ -70,13 +67,20 @@ def on_message_date(client, userdata, msg):
|
||||
print("Date : " + payload)
|
||||
try:
|
||||
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:
|
||||
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):
|
||||
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
|
||||
def on_disconnect(client, userdata, msg):
|
||||
if msg != 0:
|
||||
|
@ -1,59 +1,92 @@
|
||||
#!/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
|
||||
# and name of the file on a MQTT broker
|
||||
@author: arofarn
|
||||
"""
|
||||
|
||||
import picamera
|
||||
import paho.mqtt.publish as mqtt
|
||||
from time import sleep
|
||||
import datetime
|
||||
from cameteo_conf import *
|
||||
|
||||
|
||||
# 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/'
|
||||
mqtt_client_id = "picamera"
|
||||
|
||||
########
|
||||
# Main #
|
||||
########
|
||||
|
||||
file_date = datetime.datetime.now().replace(microsecond=0).isoformat()
|
||||
file_name = file_date + "." + photo_format
|
||||
photo_extensions = {'jpeg': 'jpg',
|
||||
'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
|
||||
#################
|
||||
|
||||
# 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.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
|
||||
cam.start_preview()
|
||||
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_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},
|
||||
{'topic':photo_mqtt_topic+"last_photo_date", 'payload':file_date, 'qos':mqtt_qos, 'retain':False}]
|
||||
|
||||
mqtt_data = [{'topic': camera_mqtt_topic + "/shooting",
|
||||
'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,
|
||||
hostname= mqtt_server ,
|
||||
hostname= mqtt_host ,
|
||||
port= mqtt_port ,
|
||||
client_id= mqtt_client_id ,
|
||||
auth= mqtt_auth )
|
||||
|
Loading…
Reference in New Issue
Block a user