diff --git a/NPM/get_data.py b/NPM/get_data.py index 75eb03b..a694cf1 100755 --- a/NPM/get_data.py +++ b/NPM/get_data.py @@ -1,4 +1,10 @@ ''' + _ _ ____ __ __ + | \ | | _ \| \/ | + | \| | |_) | |\/| | + | |\ | __/| | | | + |_| \_|_| |_| |_| + Script to get NPM values need parameter: port /usr/bin/python3 /var/www/nebuleair_pro_4g/NPM/get_data.py ttyAMA5 diff --git a/NPM/get_data_temp_hum.py b/NPM/get_data_temp_hum.py new file mode 100644 index 0000000..5abe1c9 --- /dev/null +++ b/NPM/get_data_temp_hum.py @@ -0,0 +1,52 @@ +''' + _ _ ____ __ __ + | \ | | _ \| \/ | + | \| | |_) | |\/| | + | |\ | __/| | | | + |_| \_|_| |_| |_| + +Script to get NPM values: ONLY temp and hum +need parameter: port +/usr/bin/python3 /var/www/nebuleair_pro_4g/NPM/get_data_temp_hum.py ttyAMA5 +''' + +import serial +import requests +import json +import sys + +parameter = sys.argv[1:] # Exclude the script name +#print("Parameters received:") +port='/dev/'+parameter[0] + +ser = serial.Serial( + port=port, + baudrate=115200, + parity=serial.PARITY_EVEN, + stopbits=serial.STOPBITS_ONE, + bytesize=serial.EIGHTBITS, + timeout = 1 +) + +ser.write(b'\x81\x14\x6B') # Temp and humidity command + +while True: + try: + byte_data_temp_hum = ser.readline() + # Decode temperature and humidity values + temperature = int.from_bytes(byte_data_temp_hum[3:5], byteorder='big') / 100.0 + humidity = int.from_bytes(byte_data_temp_hum[5:7], byteorder='big') / 100.0 + + print(f"temp: {temperature}") + print(f"hum: {humidity}") + break + except KeyboardInterrupt: + print("User interrupt encountered. Exiting...") + time.sleep(3) + exit() + except: + # for all other kinds of error, but not specifying which one + print("Unknown error...") + time.sleep(3) + exit() + diff --git a/NPM/get_data_v2.py b/NPM/get_data_v2.py index e38e8f8..b145eea 100644 --- a/NPM/get_data_v2.py +++ b/NPM/get_data_v2.py @@ -48,9 +48,11 @@ ser = serial.Serial( timeout = 0.5 ) +# 1️⃣ Request PM Data (PM1, PM2.5, PM10) + #ser.write(b'\x81\x11\x6E') #data10s ser.write(b'\x81\x12\x6D') #data60s - +time.sleep(0.5) # Small delay to allow the sensor to process the request #print("Start get_data_v2.py script") byte_data = ser.readline() @@ -61,8 +63,9 @@ PM1 = int.from_bytes(byte_data[9:11], byteorder='big')/10 PM25 = int.from_bytes(byte_data[11:13], byteorder='big')/10 PM10 = int.from_bytes(byte_data[13:15], byteorder='big')/10 -# Write command to retrieve temperature and humidity data +# 2️⃣ Request Temperature & Humidity ser.write(b'\x81\x14\x6B') # Temp and humidity command +time.sleep(0.5) # Small delay to allow the sensor to process the request byte_data_temp_hum = ser.readline() # Decode temperature and humidity values diff --git a/config.json.dist b/config.json.dist index 5ff1daa..fd44607 100755 --- a/config.json.dist +++ b/config.json.dist @@ -8,6 +8,7 @@ "loop/SARA_send_data_v2.py": true, "RTC/save_to_db.py": true, "BME280/get_data_v2.py": true, + "envea/read_value_v2.py": true, "deviceID": "XXXX", "deviceName": "NebuleAir-proXXX", "SaraR4_baudrate": 115200, @@ -15,7 +16,6 @@ "NextPM_ports": [ "ttyAMA5" ], - "NextPM_5channels": false, "i2C_sound": false, "i2c_BME": false, "i2c_RTC": false, diff --git a/envea/read_value_loop.py b/envea/read_value_loop.py index bb80f49..443a7ed 100755 --- a/envea/read_value_loop.py +++ b/envea/read_value_loop.py @@ -1,4 +1,10 @@ """ + _____ _ ___ _______ _ + | ____| \ | \ \ / / ____| / \ + | _| | \| |\ \ / /| _| / _ \ + | |___| |\ | \ V / | |___ / ___ \ + |_____|_| \_| \_/ |_____/_/ \_\ + Main loop to gather data from envea Sensors Need to run every minutes diff --git a/envea/read_value_loop_json.py b/envea/read_value_loop_json.py index 7e75850..af88de3 100755 --- a/envea/read_value_loop_json.py +++ b/envea/read_value_loop_json.py @@ -1,4 +1,10 @@ """ + _____ _ ___ _______ _ + | ____| \ | \ \ / / ____| / \ + | _| | \| |\ \ / /| _| / _ \ + | |___| |\ | \ V / | |___ / ___ \ + |_____|_| \_| \_/ |_____/_/ \_\ + Main loop to gather data from Envea Sensors Runs every minute via cron: diff --git a/envea/read_value_v2.py b/envea/read_value_v2.py new file mode 100644 index 0000000..469c381 --- /dev/null +++ b/envea/read_value_v2.py @@ -0,0 +1,121 @@ +""" + _____ _ ___ _______ _ + | ____| \ | \ \ / / ____| / \ + | _| | \| |\ \ / /| _| / _ \ + | |___| |\ | \ V / | |___ / ___ \ + |_____|_| \_| \_/ |_____/_/ \_\ + +Gather data from envea Sensors and store them to the SQlite table +Use the RTC time for the timestamp + +/usr/bin/python3 /var/www/nebuleair_pro_4g/envea/read_value_v2.py + +""" + +import json +import serial +import time +import traceback +import sqlite3 +from datetime import datetime + +# Connect to the SQLite database +conn = sqlite3.connect("/var/www/nebuleair_pro_4g/sqlite/sensors.db") +cursor = conn.cursor() + +#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' + +# Function to load config data +def load_config(config_file): + try: + with open(config_file, 'r') as file: + config_data = json.load(file) + return config_data + except Exception as e: + print(f"Error loading config file: {e}") + return {} + +# Define the config file path +config_file = '/var/www/nebuleair_pro_4g/config.json' + +# Load the configuration data +config = load_config(config_file) + +# Initialize sensors and serial connections +envea_sondes = config.get('envea_sondes', []) +connected_envea_sondes = [sonde for sonde in envea_sondes if sonde.get('connected', False)] +serial_connections = {} + +if connected_envea_sondes: + for device in connected_envea_sondes: + port = device.get('port', 'Unknown') + name = device.get('name', 'Unknown') + try: + serial_connections[name] = serial.Serial( + port=f'/dev/{port}', + baudrate=9600, + parity=serial.PARITY_NONE, + stopbits=serial.STOPBITS_ONE, + bytesize=serial.EIGHTBITS, + timeout=1 + ) + except serial.SerialException as e: + print(f"Error opening serial port for {name}: {e}") + +global data_h2s, data_no2, data_o3 +data_h2s = 0 +data_no2 = 0 +data_o3 = 0 +data_co = 0 +data_nh3 = 0 + +try: + if connected_envea_sondes: + for device in connected_envea_sondes: + name = device.get('name', 'Unknown') + coefficient = device.get('coefficient', 1) + 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" + ) + data_envea = serial_connection.readline() + if len(data_envea) >= 20: + byte_20 = data_envea[19] * coefficient + if name == "h2s": + data_h2s = byte_20 + elif name == "no2": + data_no2 = byte_20 + elif name == "o3": + data_o3 = byte_20 + except serial.SerialException as e: + print(f"Error communicating with {name}: {e}") +except Exception as e: + print("An error occurred while gathering data:", e) + traceback.print_exc() + + +#print(f" H2S: {data_h2s}, NO2: {data_no2}, O3: {data_o3}") + +#save to sqlite database +try: + cursor.execute(''' + INSERT INTO data_envea (timestamp,h2s, no2, o3, co, nh3) VALUES (?,?,?,?,?,?)''' + , (rtc_time_str,data_h2s,data_no2,data_o3,data_co,data_nh3 )) + + # Commit and close the connection + conn.commit() + + #print("Sensor data saved successfully!") + +except Exception as e: + print(f"Database error: {e}") + + +conn.close() + + diff --git a/html/database.html b/html/database.html index a1b4c07..0af2ff1 100644 --- a/html/database.html +++ b/html/database.html @@ -67,11 +67,10 @@ - - + @@ -93,6 +92,7 @@ + @@ -244,6 +244,16 @@ function get_data_sqlite(table, limit, download , startDate = "", endDate = "")