From 25c5a7a65aba10cdb1ae1e731d5eff284700597a Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 22 Jul 2025 15:36:36 +0200 Subject: [PATCH] update --- envea/read_ref_v2.py | 17 +++++ envea/read_value.py | 4 +- envea/read_value_v2.py | 143 ++++++++++++++++++++++++++++---------- loop/SARA_send_data_v2.py | 7 +- 4 files changed, 132 insertions(+), 39 deletions(-) diff --git a/envea/read_ref_v2.py b/envea/read_ref_v2.py index 56556a1..d89c422 100644 --- a/envea/read_ref_v2.py +++ b/envea/read_ref_v2.py @@ -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 diff --git a/envea/read_value.py b/envea/read_value.py index 1407172..9246547 100755 --- a/envea/read_value.py +++ b/envea/read_value.py @@ -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 diff --git a/envea/read_value_v2.py b/envea/read_value_v2.py index 2820d43..36defbe 100755 --- a/envea/read_value_v2.py +++ b/envea/read_value_v2.py @@ -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 -conn = sqlite3.connect("/var/www/nebuleair_pro_4g/sqlite/sensors.db") -cursor = conn.cursor() +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 -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' +# 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 -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) +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) + 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,52 +99,84 @@ 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"\n✗ An 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 (?,?,?,?,?,?,?)''' - , (rtc_time_str,data_h2s,data_no2,data_o3,data_co,data_nh3,data_so2)) - + INSERT INTO data_envea (timestamp, h2s, no2, o3, co, nh3, so2) VALUES (?,?,?,?,?,?,?)''' + , (rtc_time_str, data_h2s, data_no2, data_o3, data_co, data_nh3, data_so2)) + # 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") \ No newline at end of file diff --git a/loop/SARA_send_data_v2.py b/loop/SARA_send_data_v2.py index 0f87778..16d44a7 100755 --- a/loop/SARA_send_data_v2.py +++ b/loop/SARA_send_data_v2.py @@ -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])})