#!/usr/bin/env python3

import numpy as np
import bme680
from time import *
from bme688 import *
import socket
from colorama import Fore

# BME680 initialization
bme680_temp_offset = -1  # T° To be adapted according to your configuration
sensor680 = bme680.BME680(i2c_addr=bme680.I2C_ADDR_PRIMARY)

sensor680.set_humidity_oversample(bme680.OS_2X)
sensor680.set_pressure_oversample(bme680.OS_4X)
sensor680.set_temperature_oversample(bme680.OS_8X)
sensor680.set_filter(bme680.FILTER_SIZE_3)
sensor680.set_gas_status(bme680.ENABLE_GAS_MEAS)

sensor680.set_gas_heater_temperature(320)
sensor680.set_gas_heater_duration(150)
sensor680.select_gas_heater_profile(0)
sensor680.set_temp_offset(bme680_temp_offset)

sensor680.get_sensor_data()

temp = 0
press = 0
hum = 0
R_gas = 0
burnincycle = 300
burncycle = 1800
airtmp = 100
udpdataSend = 1 # 0 None; 1 = send UDP data on local network; 2 = print Data on console

print("""

██████  ███    ███ ███████  ██████   █████   █████  
██   ██ ████  ████ ██      ██       ██   ██ ██   ██ 
██████  ██ ████ ██ █████   ███████   █████   █████  
██   ██ ██  ██  ██ ██      ██    ██ ██   ██ ██   ██ 
██████  ██      ██ ███████  ██████   █████   █████  

""")

print(Fore.BLUE + 'BME688 soft ...')
print(Fore.CYAN + '[press Ctrl+C to exit]')

# UDP server
UDP_IP = "192.168.1.152" # Change with your Local IP
UDP_PORT = 18000 # Do not modify to connect to BME688_UDP on Windows
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# send data UDP local network or print on console
def sendData(datasend):
	if udpdataSend == 1:
		bytesToSend = str.encode(datasend)
		sock.sendto(bytesToSend, (UDP_IP, UDP_PORT))
	else:
		if udpdataSend == 2:
			print(datasend)
	
# Data prompt function
def prompt_data(burnincycle, burncycle, temp, press, hum, R_gas, AQ):
	if AQ == None:		
		out_string = "Tmp: {0:.2f} C".format(temp)
		sendData(out_string)
		out_string = "Pres: {0:.2f} hPa".format(press)
		sendData(out_string)
		out_string = "Hum: {0:.2f} %RH".format(hum)
		sendData(out_string)
		out_string = "Gas: {0:.3f} kOhm".format(R_gas/1000)
		sendData(out_string)
		out_string = "burn-in {0:.0f}".format(burnincycle)
		sendData(out_string)		
	else:
		out_string = "Tmp: {0:.2f} C".format(temp)
		sendData(out_string)
		out_string = "Pres: {0:.2f} hPa".format(press)
		sendData(out_string)
		out_string = "Hum: {0:.2f} %RH".format(hum)
		sendData(out_string)
		out_string = "Gas: {0:.3f} kOhm".format(R_gas/1000)
		sendData(out_string)		
		out_string = "Air: {0:.2f} %aq".format(AQ)
		sendData(out_string)		
		out_string = "cycle burn {0:.0f}".format(burncycle)
		sendData(out_string)

# Initialize IAQ calculator
iaq_tracker = IAQTracker()

# Main loop
try:
	
	while True:
		if sensor680.get_sensor_data():
			temp = sensor680.data.temperature
			press = sensor680.data.pressure
			hum = sensor680.data.humidity
			
			if burnincycle <= 0:
				burnincycle = 300
			else:
				burnincycle -= 1
		
			if sensor680.data.heat_stable:
				R_gas = sensor680.data.gas_resistance
				AQ = iaq_tracker.getIAQ(sensor680.data)
				
				if AQ != None:
					airtmp = AQ
				if burncycle <= 0:
					burncycle = 1800
				else:
					burncycle -= 1
			else:
				R_gas = 0
				AQ = None
			
			prompt_data(burnincycle, burncycle, temp, press, hum, R_gas, AQ)
		
		sleep(1)

except KeyboardInterrupt:
    pass
