'''
  _   _ ____  __  __ 
 | \ | |  _ \|  \/  |
 |  \| | |_) | |\/| |
 | |\  |  __/| |  | |
 |_| \_|_|   |_|  |_|
 
Script to get NPM values
need parameter: port
/usr/bin/python3 /var/www/nebuleair_pro_4g/NPM/get_data.py ttyAMA5
'''

import serial
import requests
import json
import sys
import time

parameter = sys.argv[1:]  # Exclude the script name
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\x11\x6E')      #data10s
#ser.write(b'\x81\x12\x6D')      #data60s

while True:
    try:
        byte_data = ser.readline()
        
        # Convert raw data to hex string for debugging
        raw_hex = byte_data.hex() if byte_data else ""
        
        # Check if we received data
        if not byte_data or len(byte_data) < 15:
            data = {
                'PM1': 0.0,
                'PM25': 0.0,
                'PM10': 0.0,
                'sleep': 0,
                'degradedState': 0,
                'notReady': 0,
                'heatError': 0,
                't_rhError': 0,
                'fanError': 0,
                'memoryError': 0,
                'laserError': 0,
                'raw': raw_hex,
                'message': f"No data received or incomplete frame (length: {len(byte_data)})"
            }
            json_data = json.dumps(data)
            print(json_data)
            break
        
        stateByte = int.from_bytes(byte_data[2:3], byteorder='big')
        Statebits = [int(bit) for bit in bin(stateByte)[2:].zfill(8)]
        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
        
        # Create JSON with raw data and status message
        data = {
            'PM1': PM1,
            'PM25': PM25,
            'PM10': PM10,
            'sleep': Statebits[0],
            'degradedState': Statebits[1],
            'notReady': Statebits[2],
            'heatError': Statebits[3],
            't_rhError': Statebits[4],
            'fanError': Statebits[5],
            'memoryError': Statebits[6],
            'laserError': Statebits[7],
            'raw': raw_hex,
            'message': 'OK' if sum(Statebits[1:]) == 0 else 'Sensor error detected'
        }
        json_data = json.dumps(data)
        print(json_data)
        break
        
    except KeyboardInterrupt:
        data = {
            'PM1': 0.0,
            'PM25': 0.0,
            'PM10': 0.0,
            'sleep': 0,
            'degradedState': 0,
            'notReady': 0,
            'heatError': 0,
            't_rhError': 0,
            'fanError': 0,
            'memoryError': 0,
            'laserError': 0,
            'raw': '',
            'message': 'User interrupt encountered'
        }
        print(json.dumps(data))
        time.sleep(3)
        exit()
        
    except Exception as e:
        data = {
            'PM1': 0.0,
            'PM25': 0.0,
            'PM10': 0.0,
            'sleep': 0,
            'degradedState': 0,
            'notReady': 0,
            'heatError': 0,
            't_rhError': 0,
            'fanError': 0,
            'memoryError': 0,
            'laserError': 0,
            'raw': '',
            'message': f'Error: {str(e)}'
        }
        print(json.dumps(data))
        time.sleep(3)
        exit()