''' Script to get CO2 values from Senseair S88 sensor and write to database /usr/bin/python3 /var/www/nebuleair_pro_4g/S88/write_data.py Port and protocol details come from config_table (key S88_port). The actual sensor read protocol is implemented in read_co2() below. ''' import serial import sqlite3 import sys DB_PATH = "/var/www/nebuleair_pro_4g/sqlite/sensors.db" DEFAULT_PORT = "/dev/ttyAMA5" BAUDRATE = 9600 def get_config(cursor, key, default): cursor.execute("SELECT value FROM config_table WHERE key = ?", (key,)) row = cursor.fetchone() return row[0] if row else default def read_co2(ser): # TODO: implement the Senseair S88 read protocol once the datasheet is provided. # Expected return: integer CO2 concentration in ppm, or None on failure. raise NotImplementedError("Senseair S88 read protocol not implemented yet") def main(): conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() port = get_config(cursor, "S88_port", DEFAULT_PORT) try: ser = serial.Serial( port=port, baudrate=BAUDRATE, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=1, ) except Exception as e: print(f"Error opening serial port {port}: {e}") conn.close() sys.exit(1) try: co2 = read_co2(ser) if co2 is None: print("Failed to read CO2 from S88.") return co2_ppm = int(round(co2)) cursor.execute("SELECT last_updated FROM timestamp_table LIMIT 1") row = cursor.fetchone() rtc_time_str = row[0] cursor.execute( "INSERT INTO data_S88 (timestamp, CO2) VALUES (?, ?)", (rtc_time_str, co2_ppm), ) conn.commit() print(f"CO2: {co2_ppm} ppm (saved at {rtc_time_str})") except NotImplementedError as e: print(f"S88 not ready: {e}") except Exception as e: print(f"S88 error: {e}") finally: try: ser.close() except Exception: pass conn.close() if __name__ == "__main__": main()