This commit is contained in:
Your Name
2025-07-22 15:36:36 +02:00
parent 4d512685a0
commit 25c5a7a65a
4 changed files with 132 additions and 39 deletions

View File

@@ -1,3 +1,20 @@
"""
_____ _ ___ _______ _
| ____| \ | \ \ / / ____| / \
| _| | \| |\ \ / /| _| / _ \
| |___| |\ | \ V / | |___ / ___ \
|_____|_| \_| \_/ |_____/_/ \_\
Gather data from envea Sensors and store them to the SQlite table
Use the RTC time for the timestamp
This script is run by a service nebuleair-envea-data.service
/usr/bin/python3 /var/www/nebuleair_pro_4g/envea/read_ref_v2.py ttyAMA4
ATTENTION --> read_ref.py fonctionne mieux
"""
import serial
import time
import sys

View File

@@ -44,9 +44,9 @@ def read_cairsens(port, baudrate=9600, parity=serial.PARITY_NONE, stopbits=seria
# Lire les données reçues
#data = ser.read_until(b'\n') # Lire jusqu'à la fin de ligne ou un autre délimiteur
data = ser.read_until(b'\n') # Lire jusqu'à la fin de ligne ou un autre délimiteur
data = ser.readline()
#print(f"Données reçues brutes : {data}")
print(f"Données reçues brutes : {data}")
#print(f"Données reçues (utf-8) : {data.decode('utf-8').strip()}")
# Extraire le 20ème octet

View File

@@ -10,7 +10,7 @@ Use the RTC time for the timestamp
This script is run by a service nebuleair-envea-data.service
/usr/bin/python3 /var/www/nebuleair_pro_4g/envea/read_value_v2.py
/usr/bin/python3 /var/www/nebuleair_pro_4g/envea/read_value_v2.py -d
"""
@@ -20,23 +20,58 @@ import time
import traceback
import sqlite3
from datetime import datetime
import sys
# Set DEBUG to True to enable debug prints, False to disable
DEBUG = False # Change this to False to disable debug output
# You can also control debug via command line argument
if len(sys.argv) > 1 and sys.argv[1] in ['--debug', '-d']:
DEBUG = True
elif len(sys.argv) > 1 and sys.argv[1] in ['--quiet', '-q']:
DEBUG = False
def debug_print(message):
"""Print debug messages only if DEBUG is True"""
if DEBUG:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] {message}")
debug_print("=== ENVEA Sensor Reader Started ===")
# Connect to the SQLite database
try:
conn = sqlite3.connect("/var/www/nebuleair_pro_4g/sqlite/sensors.db")
cursor = conn.cursor()
except Exception as e:
debug_print(f"✗ Failed to connect to database: {e}")
sys.exit(1)
# GET RTC TIME from SQlite
try:
cursor.execute("SELECT * FROM timestamp_table LIMIT 1")
row = cursor.fetchone() # Get the first (and only) row
rtc_time_str = row[1] # '2025-02-07 12:30:45'
except Exception as e:
debug_print(f"✗ Failed to get RTC time: {e}")
rtc_time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
debug_print(f" Using system time instead: {rtc_time_str}")
# Fetch connected ENVEA sondes from SQLite config table
try:
cursor.execute("SELECT port, name, coefficient FROM envea_sondes_table WHERE connected = 1")
connected_envea_sondes = cursor.fetchall() # List of tuples (port, name, coefficient)
#print(connected_envea_sondes)
debug_print(f"✓ Found {len(connected_envea_sondes)} connected ENVEA sensors")
for port, name, coefficient in connected_envea_sondes:
debug_print(f" - {name}: port={port}, coefficient={coefficient}")
except Exception as e:
debug_print(f"✗ Failed to fetch connected sensors: {e}")
connected_envea_sondes = []
serial_connections = {}
if connected_envea_sondes:
debug_print("\n--- Opening Serial Connections ---")
for port, name, coefficient in connected_envea_sondes:
try:
serial_connections[name] = serial.Serial(
@@ -47,10 +82,14 @@ if connected_envea_sondes:
bytesize=serial.EIGHTBITS,
timeout=1
)
debug_print(f"✓ Opened serial port for {name} on /dev/{port}")
except serial.SerialException as e:
print(f"Error opening serial port for {name}: {e}")
debug_print(f"Error opening serial port for {name}: {e}")
else:
debug_print("! No connected ENVEA sensors found in configuration")
global data_h2s, data_no2, data_o3
# Initialize sensor data variables
global data_h2s, data_no2, data_o3, data_co, data_nh3, data_so2
data_h2s = 0
data_no2 = 0
data_o3 = 0
@@ -60,38 +99,65 @@ data_so2 = 0
try:
if connected_envea_sondes:
debug_print("\n--- Reading Sensor Data ---")
for port, name, coefficient in connected_envea_sondes:
if name in serial_connections:
serial_connection = serial_connections[name]
try:
serial_connection.write(
b"\xFF\x02\x13\x30\x01\x02\x03\x04\x05\x06\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x12\xAF\x88\x03"
)
debug_print(f"Reading from {name}...")
# Send command to sensor
command = b"\xFF\x02\x13\x30\x01\x02\x03\x04\x05\x06\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x12\xAF\x88\x03"
serial_connection.write(command)
debug_print(f" → Sent command: {command.hex()}")
# Read response
data_envea = serial_connection.readline()
debug_print(f" ← Received {len(data_envea)} bytes: {data_envea.hex()}")
if len(data_envea) >= 20:
byte_20 = data_envea[19] * coefficient
byte_20 = data_envea[19]
raw_value = byte_20
calculated_value = byte_20 * coefficient
debug_print(f" → Byte 20 value: {raw_value} (0x{raw_value:02X})")
debug_print(f" → Calculated value: {raw_value} × {coefficient} = {calculated_value}")
if name == "h2s":
data_h2s = byte_20
data_h2s = calculated_value
elif name == "no2":
data_no2 = byte_20
data_no2 = calculated_value
elif name == "o3":
data_o3 = byte_20
data_o3 = calculated_value
elif name == "co":
data_co = byte_20
data_co = calculated_value
elif name == "nh3":
data_nh3 = byte_20
data_nh3 = calculated_value
elif name == "so2":
data_so2 = byte_20
data_so2 = calculated_value
debug_print(f"{name.upper()} = {calculated_value}")
else:
debug_print(f" ✗ Response too short (expected ≥20 bytes)")
except serial.SerialException as e:
print(f"Error communicating with {name}: {e}")
debug_print(f"Error communicating with {name}: {e}")
else:
debug_print(f"! No serial connection available for {name}")
except Exception as e:
print("An error occurred while gathering data:", e)
debug_print(f"\nAn error occurred while gathering data: {e}")
traceback.print_exc()
# Display all collected data
debug_print(f"\n--- Collected Sensor Data ---")
debug_print(f"H2S: {data_h2s} ppb")
debug_print(f"NO2: {data_no2} ppb")
debug_print(f"O3: {data_o3} ppb")
debug_print(f"CO: {data_co} ppb")
debug_print(f"NH3: {data_nh3} ppb")
debug_print(f"SO2: {data_so2} ppb")
#print(f" H2S: {data_h2s}, NO2: {data_no2}, O3: {data_o3}, CO : {data_co}, nh3: {data_nh3}, so2: {data_so2} ")
#save to sqlite database
# Save to sqlite database
try:
cursor.execute('''
INSERT INTO data_envea (timestamp, h2s, no2, o3, co, nh3, so2) VALUES (?,?,?,?,?,?,?)'''
@@ -100,12 +166,17 @@ try:
# Commit and close the connection
conn.commit()
#print("Sensor data saved successfully!")
except Exception as e:
print(f"Database error: {e}")
debug_print(f"Database error: {e}")
traceback.print_exc()
# Close serial connections
if serial_connections:
for name, connection in serial_connections.items():
try:
connection.close()
except:
pass
conn.close()
debug_print("\n=== ENVEA Sensor Reader Finished ===\n")

View File

@@ -28,7 +28,7 @@ CSV PAYLOAD (AirCarto Servers)
ATTENTION : do not change order !
CSV size: 18
{PM1},{PM25},{PM10},{temp},{hum},{press},{avg_noise},{max_noise},{min_noise},{envea_no2},{envea_h2s},{envea_o3},{4g_signal_quality}
{PM1},{PM25},{PM10},{temp},{hum},{press},{avg_noise},{max_noise},{min_noise},{envea_no2},{envea_h2s},{envea_nh3},{4g_signal_quality}
0 -> PM1 (μg/m3)
1 -> PM25 (μg/m3)
2 -> PM10 (μg/m3)
@@ -56,6 +56,8 @@ CSV PAYLOAD (AirCarto Servers)
24 -> charger_status
25 -> Wind speed
26 -> Wind direction
27 -> envea_CO
28 -> envea_O3
CSV FOR UDP (miotiq)
{device_id},{timestamp},{PM1},{PM25},{PM10},{temp},{hum},{press},{avg_noise},{max_noise},{min_noise},{envea_no2},{envea_h2s},{envea_o3},{4g_signal_quality}
@@ -138,6 +140,7 @@ if uptime_seconds < 120:
payload_csv = [None] * 30
#Payload UPD to be sent to miotiq
payload_udp = [None] * 30
#Payload JSON to be sent to uSpot
payload_json = {
"nebuleairid": "XXX",
@@ -743,6 +746,8 @@ try:
payload_csv[9] = averages[0] # envea_no2
payload_csv[10] = averages[1] # envea_h2s
payload_csv[11] = averages[2] # envea_nh3
payload_csv[27] = averages[3] # envea_CO
payload_csv[28] = averages[4] # envea_O3
#Add data to payload JSON
payload_json["sensordatavalues"].append({"value_type": "CAIRSENS_NO2", "value": str(averages[0])})