#!/usr/bin/env python
#-*- coding: utf-8 -*-
#----------------------------------------------------------------------
# bibliothèques "système"
#----------------------------------------------------------------------
import time
import smbus2
import sys
import math

#----------------------------------------------------------------------
# bibliothèques "locales"
#----------------------------------------------------------------------
import globals
import CRC8

#----------------------------------------------------------------------
# variables et constantes
#----------------------------------------------------------------------
I2C_SFA40 = 0x5D

#--------------------------------------------------------------------------------------------------
def SFA40_open() :

	global SFA40_open_flag

	try :
		if ( globals.BUS_8_OK_flag ) :
		
			if globals.DEBUG_SFA40:
				print("SFA40_open : starting...")
				print(" ")
				
			if not SFA40_stopMeasurement() :
				return False
			
			time.sleep(0.020)

			'''
			'''
			if not SFA40_get_serial_number() :
				return False

			SFA40_open_flag = True
			return True
			
		else :
			SFA40_open_flag = False
			return False
			
	except:
	
		print("SFA40_open : exception...")
		print(" ")
		SFA40_open_flag = False
		return False

#-----------------------------------------------------------------------------
def SFA40_init():
	
	try:
		if SFA40_open_flag :
		
			#---------------------------------------------------------------------
			if globals.DEBUG_SFA40:
				print("SFA40_init : starting...")

			#---------------------------------------------------------------------
			if not SFA40_startMeasurement():
				return False
			
			#---------------------------------------------------------------------
			if globals.DEBUG_SFA40:
				print(" ")
			
			return True
		
		else :
			#---------------------------------------------------------------------
			if globals.DEBUG_SFA40:
				print("SFA40_init : SFA40_open_flag = False !")
				print(" ")
				
			return False
		
	except:
		#---------------------------------------------------------------------
		print("SFA40_init : exception !")
		print(" ")

		return False
		
#-----------------------------------------------------------------------------
def SFA40_startMeasurement():

	try:
		raw_message = [0x00, 0xAC]
		write_txn = smbus2.i2c_msg.write(I2C_SFA40, raw_message)
		globals.bus_8.i2c_rdwr(write_txn)

		if globals.DEBUG_SFA40:
			print("  SFA40_startMeasurement -> OK")

		return True
	
	except Exception as except_str:
		print("  SFA40_startMeasurement : exception -> ", except_str )
		print(" ")
		
		return False
		
#----------------------------------------------------------------------
def SFA40_stopMeasurement():

	try:
		raw_message = [0x50, 0xD2]
		write_txn = smbus2.i2c_msg.write(I2C_SFA40, raw_message)
		globals.bus_8.i2c_rdwr(write_txn)

		if globals.DEBUG_SFA40:
			print("  SFA40_stopMeasurement -> OK")

		return True
	
	except:
		print("SFA40_stopMeasurement : exception !")
		print(" ")
		
		return False
		
#----------------------------------------------------------------------
def SFA40_get_serial_number():

	try:
	
		SFA40_get_ID_STATUS = False
		
		raw_message = [0x02, 0xCE]
		write_txn = smbus2.i2c_msg.write(I2C_SFA40, raw_message)
		globals.bus_8.i2c_rdwr(write_txn)

		time.sleep(0.100)
		
		read_txn = smbus2.i2c_msg.read(I2C_SFA40, 9)
		globals.bus_8.i2c_rdwr(read_txn)
		data = list(read_txn)
		
		hex_serial_number = '0x' + '' . join( format(x, '02x') for x in data )
		
		print(hex_serial_number)

		if globals.DEBUG_SFA40:
			print("  SFA40_get_serial_number -> OK")
			print(" ")
		
		SFA40_get_ID_STATUS = True
		
	except Exception as e:

		exception_type, exception_object, exception_traceback = sys.exc_info()
		line_number = exception_traceback.tb_lineno

		exception_string = "type : " + str(exception_type) + " ; ligne = " + str(line_number)
		print(exception_string)
		print(" ")
		
		SFA40_get_ID_STATUS = False
		print("  SFA40_get_serial_number : exception !")
		print(" ")

	finally :
		return SFA40_get_ID_STATUS
		
#----------------------------------------------------------------------

def SFA40_read():

	SFA40_To_value = -8.00
	SFA40_HRo_value = 0.00

	try:
		#--------------------------------------------------------------
		chaine_SFA40 = [False, "000.0", "00.0", "00.00"]
		
		#--------------------------------------------------------------
		if True :
			raw_message = [0xE0, 0x6D]
			write_txn = smbus2.i2c_msg.write(I2C_SFA40, raw_message)
			globals.bus_8.i2c_rdwr(write_txn)

			time.sleep(0.010)
			
			read_txn = smbus2.i2c_msg.read(I2C_SFA40, 12)
			globals.bus_8.i2c_rdwr(read_txn)
			data = list(read_txn)
			
			print(data)

			if ( len(data) == 12 ):
			
				data_crc8 = [0,0,0]
				Flag_crc8 = True
				for i in range(3):
					data_crc8[i] = CRC8.crc8_scd30(data[3*i],data[3*i+1])
					
					Flag_crc8 = Flag_crc8 and ( data[3*i+2]  == data_crc8[i] )
					
				if Flag_crc8:
				
					if ( data[10] == 0x00 ) :
					
						SFA40_HCHO = ( 1.000  * ( float(256*data[0] + data[1]) ) * ( 1.0 ) )			# LSB
						SFA40_HCHO = ( 1.248  * ( float(256*data[0] + data[1]) ) * ( 0.1 ) )			# ug/m3 ( avec 1.248 * 0.1 )
						SFA40_HCHO = ( 1.248  * ( float(256*data[0] + data[1]) ) * ( 1000.0/65535.0 ) )	# ug/m3 ( avec 1.248 * 1000/65535 )

						SFA40_HR   = ( 125.0  * ( float(256*data[3] + data[4]) ) / 65535.0 ) - 6.0
						SFA40_T    = ( 175.0  * ( float(256*data[6] + data[7]) ) / 65535.0 ) - 45.0
						
						SFA40_TEMP_corr = SFA40_T + SFA40_To_value

						coeff_correction_HUMI	= math.exp( ( ( 17.62 * 243.21 ) * ( SFA40_T - SFA40_TEMP_corr ) ) / ( ( 243.21 + SFA40_TEMP_corr ) * ( 243.21 + SFA40_T ) ) )
						SFA40_HUMI_corr			= SFA40_HR * coeff_correction_HUMI + SFA40_HRo_value

						chaine_SFA40 = [ 
							True,
							"{0:.1f}".format( SFA40_HCHO ) , 
							"{0:.1f}".format( SFA40_HUMI_corr ) , 
							"{0:.2f}".format( SFA40_TEMP_corr ) 
						 ]
					
				else:
					globals.Flag_mesures_OK = ( globals.Flag_mesures_OK & 0xFFFF0FFFFFFF ) | 0x000010000000
					if globals.DEBUG_SFA40:
						print("SFA40_read : erreur CRC !")
			else:
				globals.Flag_mesures_OK = ( globals.Flag_mesures_OK & 0xFFFF0FFFFFFF ) | 0x000020000000
				if globals.DEBUG_SFA40:
					print("SFA40_read : erreur nb bytes !")
		else:
			globals.Flag_mesures_OK = ( globals.Flag_mesures_OK & 0xFFFF0FFFFFFF ) | 0x000030000000
			if globals.DEBUG_SFA40:
				print("SFA40_read : data not ready !")
			
	except Exception as e:

		globals.Flag_mesures_OK = ( globals.Flag_mesures_OK & 0xFFFF0FFFFFFF ) | 0x000040000000
		print("SFA40_read : exception !")

		exception_type, exception_object, exception_traceback = sys.exc_info()
		line_number = exception_traceback.tb_lineno

		exception_string = "type : " + str(exception_type) + " ; ligne = " + str(line_number)
		print(exception_string)

		print(" ")

	finally:
		if globals.DEBUG_SFA40:
			print(" ")
			
		return chaine_SFA40
		
#-----------------------------------------------------------------------------
