#!/usr/bin/env python3
#-*- coding: utf-8 -*-

#--------------------------------------------------------------------------------------------------
import time
import struct
import smbus2

#--------------------------------------------------------------------------------------------------
import globals
import CRC8

#--------------------------------------------------------------------------------------------------
# variables et constantes globales
#--------------------------------------------------------------------------------------------------
I2C_SCD30 = 0x61
Count_data_ready_maxi = 20

#--------------------------------------------------------------------------------------------------
SCD30_INTERVALLE = 2

#-----------------------------------------------------------------------------
def SCD30_open():
	global SCD30_open_flag

	try :
		if ( globals.BUS_5_OK_flag ) :
		
			if globals.DEBUG_SCD30:
				print("SCD30_open : starting...")
				print(" ")
			globals.bus_5.read_byte(I2C_SCD30)
			SCD30_open_flag = True
			return True
		else :
			SCD30_open_flag = False
			return False
	except:
		SCD30_open_flag = False
		return False

#--------------------------------------------------------------------------------------------------
def SCD30_init(QNH_value,To_value,ASC_string):

	global SCD30_set_FRC_FLAG, SCD30_set_To_FLAG
	
	try:
	
		#------------------------------------------------------------------------------------------
		if SCD30_open_flag :
		
			#------------------------------------------------------------------------------------------
			if globals.DEBUG_SCD30:
				print("SCD30_init : en cours...")
				print(" ")
				
			#------------------------------------------------------------------------------------------
			if not SCD30_stop_continuous_measurement():
				return False
				
			#------------------------------------------------------------------------------------------
			if (  not SCD30_set_meas_interval(SCD30_INTERVALLE) ) :
				return False
				
			#------------------------------------------------------------------------------------------
			if (  not SCD30_set_altitude(QNH_value) ) :
				return False
				
			#------------------------------------------------------------------------------------------
			if (  not SCD30_set_offset_T(To_value) ) :
				return False
				
			#------------------------------------------------------------------------------------------
			if (  not SCD30_set_ASC(ASC_string) ) :
				return False
			
			#------------------------------------------------------------------------------------------
			if not SCD30_start_continuous_measurement(0):
				return False
				
			#------------------------------------------------------------------------------------------
			if globals.DEBUG_SCD30:
				print(" ")
			
			return True
		
		else :
			#---------------------------------------------------------------------
			if globals.DEBUG_SCD30 :
				print("SCD30_init : SCD30_open_flag = False !")
				print(" ")
				
			return False

	except: 
		if globals.DEBUG_SCD30:
			print("SCD30_init : exception !")
			print(" ")
			
		return False
		
#--------------------------------------------------------------------------------------------------
# read To, QNH, ASC
#--------------------------------------------------------------------------------------------------
def SCD30_READ_To_QNH_ASC_FW():

	try :
		retour = [False, "?", "?", "?", "?"]
		SCD30_READ_To  = SCD30_get_offset_T()
		SCD30_READ_QNH = SCD30_get_altitude()
		SCD30_READ_ASC = SCD30_get_ASC()
		SCD30_READ_FWV = SCD30_get_FWV()
		
		if ( SCD30_READ_To[0] and SCD30_READ_ASC[0] and SCD30_READ_QNH[0] and SCD30_READ_FWV[0] ) :
			SCD30_READ_To_string = format( (SCD30_READ_To[1]/100.0) , '.2f')
			retour = [True, SCD30_READ_To_string, SCD30_READ_QNH[2], SCD30_READ_ASC[2], SCD30_READ_FWV[1]]
			
			if globals.DEBUG_SCD30:
				print("  SCD30_READ_To_QNH_ASC_FW -> To = " + SCD30_READ_To_string + " °C ; QNH = " + SCD30_READ_QNH[2] + " m ; ASC = " + SCD30_READ_ASC[2] + " ; FW = " + SCD30_READ_FWV[1])
				print(" ")
				
		else :
			if globals.DEBUG_SCD30:
				print("  SCD30_READ_To_QNH_ASC_FW -> erreur !")
				print(" ")
	
	except :
		retour = [False, "?", "?", "?", "?"]
		if globals.DEBUG_SCD30:
			print("  SCD30_READ_To_QNH_ASC_FW -> exception !")
			print(" ")
	
	finally :
		time.sleep(0.05)
		return retour

#--------------------------------------------------------------------------------------------------
# soft_reset : 0xd3, 0x04, 0,  0
#--------------------------------------------------------------------------------------------------
def SCD30_reset():
	try:
		SCD30_reset_STATUS = False

		raw_message = [0xd3, 0x04]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)

		time.sleep(2.5)
		
		SCD30_reset_STATUS = True
		
		if globals.DEBUG_SCD30:
			print("  SCD30_reset -> OK")
		
	except:
		if globals.DEBUG_SCD30:
			print("  SCD30_reset : exception !")

	finally :
		if globals.DEBUG_SCD30:
			print(" ")

		return SCD30_reset_STATUS
		
#--------------------------------------------------------------------------------------------------
# start_continuous_measurement : 0x00, 0x10, 3,  0
#--------------------------------------------------------------------------------------------------
def SCD30_start_continuous_measurement(PRESSURE):
	try:
		LSB = 0xFF & PRESSURE
		MSB = 0xFF & (PRESSURE >> 8)
		valeur_pression = [MSB,LSB]
		
		data_crc8 = CRC8.crc8_scd30(valeur_pression[0],valeur_pression[1])

		PRESSURE_value     = valeur_pression[0] * 256 + valeur_pression[1]
		PRESSURE_value_str = str( PRESSURE_value )

		if globals.DEBUG_SCD30:
			print("  SCD30_start_continuous_measurement : P = " + PRESSURE_value_str + " mbar ; " + str(valeur_pression[0]) + "_" +  str(valeur_pression[1]) + " ; CRC = " +  str(data_crc8) )

		raw_message = [ 0x00, 0x10, valeur_pression[0], valeur_pression[1], data_crc8 ]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)

		time.sleep(0.25)
		
		return True
		
	except:
		if globals.DEBUG_SCD30:
			print("  SCD30_start_continuous_measurement : exception !")
		
		return False

#--------------------------------------------------------------------------------------------------
# stop_continuous_measurement :	0x01, 0x04, 0,  0
#--------------------------------------------------------------------------------------------------
def SCD30_stop_continuous_measurement():
	try:
		raw_message = [0x01, 0x04]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)
		
		time.sleep(0.25)
		
		if globals.DEBUG_SCD30:
			print("  SCD30_stop_continuous_measurement -> OK")
		
		return True
		
	except:
		if globals.DEBUG_SCD30:
			print("  SCD30_stop_continuous_measurement : exception !")

		return False
		
#--------------------------------------------------------------------------------------------------
# set ASC mode : after get verify
#--------------------------------------------------------------------------------------------------
def SCD30_set_ASC(ASC_mode_string):
	try :
		SCD30_set_ASC_STATUS = False
		SCD30_answer = SCD30_get_ASC()
		
		if ( SCD30_answer[0] ) :
			if globals.DEBUG_SCD30:
				print( "  SCD30_get_ASC = " + SCD30_answer[2] )
				
			if ( SCD30_answer[2] == ASC_mode_string ) :
				if globals.DEBUG_SCD30:
					print("  SCD30_get_ASC -> OK")
				SCD30_set_ASC_STATUS = True
			else :
				if globals.DEBUG_SCD30:
					print("  SCD30_get_ASC -> not OK")
					print("  SCD30_set_ASC_only = " + ASC_mode_string )
					
				if SCD30_set_ASC_only(ASC_mode_string) :
					if globals.DEBUG_SCD30:
						print("  SCD30_set_ASC_only : -> OK")
					SCD30_set_ASC_STATUS = True
				else :
					if globals.DEBUG_SCD30:
						print("  SCD30_set_ASC_only -> erreur !")
		else :
			if globals.DEBUG_SCD30:
				print("  SCD30_set_ASC -> erreur !")
	
	except :
		if globals.DEBUG_SCD30:
			print("  SCD30_set_ASC -> exception !")
	
	finally :
		if globals.DEBUG_SCD30:
			print(" ")
		time.sleep(0.25)
		return SCD30_set_ASC_STATUS
		
#--------------------------------------------------------------------------------------------------
# set ASC : 0x53, 0x06, 3,  0    ( enable -> 1 ; disable -> 0 )
#--------------------------------------------------------------------------------------------------
def SCD30_set_ASC_only(MODE_string):
	try:
		if globals.DEBUG_SCD30:
			print( "  SCD30_set_ASC_only : " + MODE_string )

		if ( MODE_string == "ON") :
			raw_message = [0x53, 0x06, 0x00, 0x01, 0xB0]

			globals.RPi.i2c_write_device(handle_i2c_SCD30, [0x53, 0x06, 0x00, 0x01, 0xB0])
		else :
			raw_message = [0x53, 0x06, 0x00, 0x00, 0x81]

		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)
		
		time.sleep(0.050)
		return True
		
	except: 
		if globals.DEBUG_SCD30:
			print("  SCD30_set_ASC_only : exception !")
		time.sleep(0.050)
		return False
		
#--------------------------------------------------------------------------------------------------
# get ASC : 0x53, 0x06, 3,  0
#--------------------------------------------------------------------------------------------------
def SCD30_get_ASC():
	try:
		retour = [False, 0, "OFF"]
		
		raw_message = [0x53, 0x06]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)

		time.sleep(0.050)
		
		read_txn = smbus2.i2c_msg.read(I2C_SCD30, 0x03)
		globals.bus_5.i2c_rdwr(read_txn)
		data = list(read_txn)

		if ( len(data) == 3 ):


			data_crc8 = CRC8.crc8_scd30(data[0],data[1])
			
			ASC_value        = data[0] * 256 + data[1]
			if ( ASC_value == 0 ) :
				ASC_value_string = "OFF"
			else :
				ASC_value_string = "ON"
			
			if globals.DEBUG_SCD30:
				print("  SCD30_get_ASC : " + ASC_value_string + " ; " + str(data[0]) + "_" +  str(data[1]) + "_" +  str(data[2]) + " ; CRC = " +  str(data_crc8) )
	
			if data[2] == data_crc8:
				retour = [True, ASC_value, ASC_value_string]
			else:
				if globals.DEBUG_SCD30:
					print("  SCD30_get_ASC : erreur CRC !")
				
		else:
			if globals.DEBUG_SCD30:
				print("  SCD30_get_ASC : erreur Nb bytes !")
		
	except: 
		if globals.DEBUG_SCD30:
			print("  SCD30_get_ASC : exception !")

	finally :
		time.sleep(0.050)
		return retour

#--------------------------------------------------------------------------------------------------
# set measurement_interval : after get verify
#--------------------------------------------------------------------------------------------------
def SCD30_set_meas_interval(INTERVALLE_value):

	try :
		SCD30_set_meas_interval_STATUS = False
		INTERVALLE_value_string = str(INTERVALLE_value)
		SCD30_answer = SCD30_get_meas_interval()
		
		if ( SCD30_answer[0] ) :
			if globals.DEBUG_SCD30:
				print("  SCD30_get_meas_interval = " + SCD30_answer[2] + " s")
				
			if ( int(SCD30_answer[1]) == INTERVALLE_value ) :
				if globals.DEBUG_SCD30:
					print("  SCD30_get_meas_interval -> OK")
				SCD30_set_meas_interval_STATUS = True
				
			else :
				if globals.DEBUG_SCD30:
					print("  SCD30_get_meas_interval -> not OK")
					print("  SCD30_set_meas_interval_only = " + INTERVALLE_value_string + " s...")
					
				if SCD30_set_meas_interval_only(INTERVALLE_value) :
					if globals.DEBUG_SCD30:
						print("  SCD30_set_meas_interval_only : -> OK")
					SCD30_set_meas_interval_STATUS = True
				else :
					if globals.DEBUG_SCD30:
						print("  SCD30_set_meas_interval_only -> erreur !")
		else :
			if globals.DEBUG_SCD30:
				print("  SCD30_get_meas_interval -> erreur !")
	
	except :
		if globals.DEBUG_SCD30:
			print("  SCD30_set_meas_interval -> exception !")
	
	finally :
		if globals.DEBUG_SCD30:
			print(" ")
		time.sleep(0.25)
		return SCD30_set_meas_interval_STATUS

#--------------------------------------------------------------------------------------------------
# set measurement_interval : 0x46, 0x00, 3,  0
#--------------------------------------------------------------------------------------------------
def SCD30_set_meas_interval_only(INTERVALLE):
	try:
		LSB = 0xFF & INTERVALLE
		MSB = 0xFF & (INTERVALLE >> 8)
		intervalle_mesures = [MSB,LSB]

		data_crc8 = CRC8.crc8_scd30(intervalle_mesures[0],intervalle_mesures[1])

		if globals.DEBUG_SCD30:
			print("  SCD30_set_meas_interval_only : " + str(intervalle_mesures[0]) + "_" +  str(intervalle_mesures[1]) + " ; CRC = " +  str(intervalle_mesures_crc8) )

		raw_message = [0x46, 0x00, intervalle_mesures[0], intervalle_mesures[1], intervalle_mesures_crc8]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)

		time.sleep(0.050)
		return True
		
	except: 
		if globals.DEBUG_SCD30:
			print("  SCD30_set_meas_interval_only : exception !")
		time.sleep(0.050)
		return False
		
#--------------------------------------------------------------------------------------------------
# get measurement_interval : 0x46, 0x00, 3,  0
#--------------------------------------------------------------------------------------------------
def SCD30_get_meas_interval():
	try:
		retour = [False, 0, "0000"]
		
		raw_message = [0x46, 0x00]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)

		time.sleep(0.050)
		
		read_txn = smbus2.i2c_msg.read(I2C_SCD30, 0x03)
		globals.bus_5.i2c_rdwr(read_txn)
		data = list(read_txn)

		if ( len(data) == 3 ):

			MEASURE_INTERVALLE     = data[0] * 256 + data[1]
			MEASURE_INTERVALLE_str = str(MEASURE_INTERVALLE)
			data_crc8              = CRC8.crc8_scd30(data[0],data[1])
			
			if globals.DEBUG_SCD30:
				print("  SCD30_get_meas_interval : " + MEASURE_INTERVALLE_str + " s ; " + str(data[0]) + "_" +  str(data[1]) + "_" +  str(data[2]) +  " ; CRC = " +  str(data_crc8) )
	
			if data[2] == data_crc8:
				retour = [True, MEASURE_INTERVALLE, MEASURE_INTERVALLE_str]
			else:
				if globals.DEBUG_SCD30:
					print("  SCD30_get_meas_interval : erreur CRC !")
				
		else:
			if globals.DEBUG_SCD30:
				print("  SCD30_get_meas_interval : erreur Nb bytes !")
		
	except: 
		if globals.DEBUG_SCD30:
			print("  SCD30_get_meas_interval : exception !")

	finally :
		time.sleep(0.050)
		return retour

#--------------------------------------------------------------------------------------------------
# set altitude_compensation : after get verify
#--------------------------------------------------------------------------------------------------
def SCD30_set_altitude(altitude_value):
	try :
		SCD30_set_altitude_STATUS = False
		altitude_value_string = str(altitude_value)
		SCD30_answer = SCD30_get_altitude()
		
		if ( SCD30_answer[0] ) :
			if globals.DEBUG_SCD30:
				print("  SCD30_get_altitude -> " + SCD30_answer[2] + " m")

			if ( SCD30_answer[1] == altitude_value ) :
				SCD30_set_altitude_STATUS = True
				if globals.DEBUG_SCD30:
					print("  SCD30_get_altitude -> OK")
			else :
				if globals.DEBUG_SCD30:
					print("  SCD30_get_altitude -> not OK")
					print("  SCD30_set_altitude = " + altitude_value_string + " m...")
					
				if SCD30_set_altitude_only(altitude_value) :
					SCD30_set_altitude_STATUS = True
					if globals.DEBUG_SCD30:
						print("  SCD30_set_altitude_only -> OK")
				else :
					if globals.DEBUG_SCD30:
						print("  SCD30_set_altitude_only -> échec !")			
		else :
			if globals.DEBUG_SCD30:
				print("  SCD30_get_altitude -> erreur !")
	
	except :
		if globals.DEBUG_SCD30:
			print("  SCD30_set_altitude -> exception !")
	
	finally :
		if globals.DEBUG_SCD30:
			print(" ")
		time.sleep(0.25)	
		return SCD30_set_altitude_STATUS
		
#--------------------------------------------------------------------------------------------------
# set_get_altitude_compensation : 0x51, 0x02, 3,  0
#--------------------------------------------------------------------------------------------------
def SCD30_set_altitude_only(ALTITUDE):
	try:
		LSB = 0xFF & ALTITUDE
		MSB = 0xFF & (ALTITUDE >> 8)
		valeur_altitude = [MSB,LSB]
		
		data_crc8 = CRC8.crc8_scd30(valeur_altitude[0],valeur_altitude[1])
				
		if globals.DEBUG_SCD30:
			print("  SCD30_set_altitude : " + str(valeur_altitude[0]) + "_" +  str(valeur_altitude[1]) + " ; CRC = " +  str(data_crc8) )
		
		raw_message = [0x51, 0x02, valeur_altitude[0], valeur_altitude[1], data_crc8]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)

		time.sleep(0.050)
		return True
		
	except: 
		if globals.DEBUG_SCD30:
			print("  SCD30_set_altitude : exception !")
		time.sleep(0.050)
		return False
		
#--------------------------------------------------------------------------------------------------
# set_get_altitude_compensation : 0x51, 0x02, 3,  0
#--------------------------------------------------------------------------------------------------
def SCD30_get_altitude():
	try:
		retour = [False, 0, "0000"]
		
		raw_message = [0x51, 0x02]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)

		time.sleep(0.050)
		
		read_txn = smbus2.i2c_msg.read(I2C_SCD30, 0x03)
		globals.bus_5.i2c_rdwr(read_txn)
		data = list(read_txn)

		if ( len(data) == 3 ):

			ALTITUDE_OFFSET     = data[0] * 256 + data[1]
			ALTITUDE_OFFSET_str = str(ALTITUDE_OFFSET)
			data_crc8           = CRC8.crc8_scd30(data[0],data[1])
			
			if globals.DEBUG_SCD30:
				print("  SCD30_get_altitude : " + ALTITUDE_OFFSET_str + " m ; " + str(data[0]) + "_" +  str(data[1]) +  "_" +  str(data[2]) + " ; CRC = " +  str(data_crc8) )
	
			if data[2] == data_crc8:
				retour = [True, ALTITUDE_OFFSET, ALTITUDE_OFFSET_str]
			else:
				if globals.DEBUG_SCD30:
					print("  SCD30_get_altitude : erreur CRC !")
				
		else:
			if globals.DEBUG_SCD30:
				print("  SCD30_get_altitude : erreur Nb bytes !")
		
	except: 
		if globals.DEBUG_SCD30:
			print("  SCD30_get_altitude : exception !")

	finally :
		time.sleep(0.050)
		return retour
		
#--------------------------------------------------------------------------------------------------
# set temperature_offset : after get verify
#--------------------------------------------------------------------------------------------------
def SCD30_set_offset_T(To_value) :
	try :
		SCD30_set_offset_T_STATUS = False
		To_string_x_100 = str( To_value )
		SCD30_answer = SCD30_get_offset_T()
	
		if ( SCD30_answer[0] ) :
			if globals.DEBUG_SCD30:
				print("  SCD30_get_offset_T -> " + SCD30_answer[2] + " °C (x100)")

			if ( abs( SCD30_answer[1] - To_value ) < 2 ) :
				SCD30_set_offset_T_STATUS = True
				if globals.DEBUG_SCD30:
					print("  SCD30_get_offset_T -> OK")
			else :
				if globals.DEBUG_SCD30:
					print("  SCD30_get_offset_T -> not OK")
					print("  SCD30_set_offset_T = " + To_string_x_100 + " °C (x100)")
					
				if SCD30_set_offset_T_only(To_value) :
					SCD30_set_offset_T_STATUS = True
					if globals.DEBUG_SCD30:
						print("  SCD30_set_offset_T -> OK")
				else :
					if globals.DEBUG_SCD30:
						print("  SCD30_set_offset_T -> not OK !")			
		else :
			if globals.DEBUG_SCD30:
				print("  SCD30_get_offset_T -> erreur !")
			
	except :
		if globals.DEBUG_SCD30:
			print("  SCD30_set_offset_T -> exception !")
	
	finally :
		if globals.DEBUG_SCD30:
			print(" ")
		time.sleep(0.25)	
		return SCD30_set_offset_T_STATUS

#--------------------------------------------------------------------------------------------------
# set_temperature_offset : 0x54, 0x03, 3,  0
#--------------------------------------------------------------------------------------------------
def SCD30_set_offset_T_only(OFFSET_To):
	try:
		LSB = 0xFF &  OFFSET_To
		MSB = 0xFF & (OFFSET_To >> 8)
		valeur_offset_T = [MSB,LSB]
		
		data_crc8 = CRC8.crc8_scd30(valeur_offset_T[0],valeur_offset_T[1])
				
		if globals.DEBUG_SCD30:
			print("  SCD30_set_offset_T : " + str(valeur_offset_T[0]) + "_" +  str(valeur_offset_T[1]) + " ; CRC = " +  str(data_crc8) )
		
		raw_message = [0x54, 0x03, valeur_offset_T[0], valeur_offset_T[1], data_crc8]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)
		
		time.sleep(0.050)
		return True
		
	except: 
		if globals.DEBUG_SCD30:
			print("  SCD30_set_offset_T : exception !")
		time.sleep(0.050)
		return False
		
#--------------------------------------------------------------------------------------------------
# get_temperature_offset : 0x54, 0x03, 3,  0
#--------------------------------------------------------------------------------------------------
def SCD30_get_offset_T():
	try:
		retour = [False, 0, "0000"]
		
		raw_message = [0x54, 0x03]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)

		time.sleep(0.050)
		
		read_txn = smbus2.i2c_msg.read(I2C_SCD30, 0x03)
		globals.bus_5.i2c_rdwr(read_txn)
		data = list(read_txn)

		if ( len(data) == 3 ):
			OFFSET_To     = data[0] * 256 + data[1]
			OFFSET_To_str = str( OFFSET_To )
			data_crc8     = CRC8.crc8_scd30(data[0],data[1])
			
			if globals.DEBUG_SCD30:
				print("  SCD30_get_offset_T : " + OFFSET_To_str + " °C (x100) ; " + str(data[0]) + "_" +  str(data[1]) + "_" +  str(data[2]) + " ; CRC = " +  str(data_crc8) )
	
			if data[2] == data_crc8:
				retour = [True, OFFSET_To, OFFSET_To_str]
			else:
				retour = [True, OFFSET_To, OFFSET_To_str]
				if globals.DEBUG_SCD30:
					print("  SCD30_get_offset_T : erreur CRC !")
				
		else:
			if globals.DEBUG_SCD30:
				print("  SCD30_get_offset_T : erreur Nb bytes !")
		
	except: 
		if globals.DEBUG_SCD30:
			print("  SCD30_get_offset_T : exception !")

	finally :
		time.sleep(0.050)
		return retour

#--------------------------------------------------------------------------------------------------
# get firmware version : 0xd1, 0x00, 3,  0
#--------------------------------------------------------------------------------------------------
def SCD30_get_FWV():
	try:
		retour = [False, "0x00_0x00"]
		
		raw_message = [0xd1, 0x00]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)

		time.sleep(0.050)
		
		read_txn = smbus2.i2c_msg.read(I2C_SCD30, 0x03)
		globals.bus_5.i2c_rdwr(read_txn)
		data = list(read_txn)

		if ( len(data) == 3 ):

			data_crc8 = CRC8.crc8_scd30(data[0],data[1])
			
			if globals.DEBUG_SCD30:
				print("  SCD30_get_FWV : " + "0x%02x"%data[0] + "_" +  "0x%02x"%data[1] + "_" +  "0x%02x"%data[2] + " ; CRC = " +  "0x%02x"%data_crc8 )
	
			if data[2] == data_crc8 :
				retour = [True, ( "0x%02x" % (data[0]) ) + "-" + ( "0x%02x" % (data[1]) ) ]
			else:
				if globals.DEBUG_SCD30:
					print("  SCD30_get_FWV : erreur CRC !")
				
		else:
			if globals.DEBUG_SCD30:
				print("  SCD30_get_FWV : erreur Nb bytes !")
		
	except: 
		if globals.DEBUG_SCD30:
			print("  SCD30_get_FWV : exception !")

	finally :
		time.sleep(0.050)
		return retour

#--------------------------------------------------------------------------------------------------
# set REF CO2 (FRC) : 0x52, 0x04, 3,  0
#--------------------------------------------------------------------------------------------------
def SCD30_set_FRC(REF_CO2_string):
	try:
		REF_CO2_value = int(REF_CO2_string)
		LSB = 0xFF &   REF_CO2_value
		MSB = 0xFF & ( REF_CO2_value >> 8 )
		CO2_reference_bytes = [MSB,LSB]
		
		data_crc8 = CRC8.crc8_scd30(CO2_reference_bytes[0],CO2_reference_bytes[1])
		
		if globals.DEBUG_SCD30:
			print("  SCD30_set_FRC : " + str(CO2_reference_bytes[0]) + "_" +  str(CO2_reference_bytes[1]) + " ; CRC = " +  str(data_crc8) )
		
		raw_message = [0x52, 0x04, CO2_reference_bytes[0], CO2_reference_bytes[1], data_crc8]
		write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
		globals.bus_5.i2c_rdwr(write_txn)

		time.sleep(0.050)
		return True
		
	except:
		if globals.DEBUG_SCD30:
			print("  SCD30_set_FRC : exception !")
		time.sleep(0.050)
		return False
		
#--------------------------------------------------------------------------------------------------
def SCD30_data_ready():
	try:
		Count_data_ready = Count_data_ready_maxi
		
		while True:

			raw_message = [0x02, 0x02]
			write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
			globals.bus_5.i2c_rdwr(write_txn)

			time.sleep(0.050)
			
			read_txn = smbus2.i2c_msg.read(I2C_SCD30, 0x03)
			globals.bus_5.i2c_rdwr(read_txn)
			data = list(read_txn)

			if ( len(data) == 3 ):

				data_crc8 = CRC8.crc8_scd30(data[0],data[1])
				
				if globals.DEBUG_SCD30:
					print("  SCD30_data_ready : " + str(data[0]) + "_" +  str(data[1]) + "_" +  str(data[2]) + " ; CRC = " +  str(data_crc8) )
		
				if data[2] == data_crc8:
				
					if (data[0] == 0) and (data[1] == 1):
						return True
						
					else:
						if globals.DEBUG_SCD30:
							print("  SCD30_data_ready : not ready !")

				else:
					if globals.DEBUG_SCD30:
						print("  SCD30_data_ready : erreur CRC !")
					
			else:
				if globals.DEBUG_SCD30:
					print("  SCD30_data_ready : erreur Nb bytes !")
			
			Count_data_ready = Count_data_ready - 1
			if (Count_data_ready <= 0):
				if globals.DEBUG_SCD30:
					print("  SCD30_data_ready : échec après " + str(Count_data_ready_maxi) + " tentatives !")
				return False
				
			time.sleep(0.250)
			
	except:
		if globals.DEBUG_SCD30:
			print("  SCD30_data_ready : exception !")
		time.sleep(0.050)
		return False
		
#--------------------------------------------------------------------------------------------------
def SCD30_read():
	try:
		chaine_SCD30 = [ "99.9", "99.9", "9999" ]
		
		if SCD30_data_ready():
		
			raw_message = [0x03, 0x00]
			write_txn = smbus2.i2c_msg.write(I2C_SCD30, raw_message)
			globals.bus_5.i2c_rdwr(write_txn)

			time.sleep(0.050)
			
			read_txn = smbus2.i2c_msg.read(I2C_SCD30, 18)
			globals.bus_5.i2c_rdwr(read_txn)
			data = list(read_txn)

			if ( len(data) == 18 ):
			
				#----------------------------------------------------------------------------------
				# calcul des CRC
				#----------------------------------------------------------------------------------
				data_crc8 = [0,0,0,0,0,0]
				for i in range(6):

					data_crc8[i] = CRC8.crc8_scd30(data[3*i],data[3*i+1])
					
				if globals.DEBUG_SCD30:
					print("  SCD30_read_CO2 : " + str(data[0]) + "_" +  str(data[1]) + "_" +  str(data[2])  + "_CRC=" +  str(data_crc8[0]) + " , " + str(data[3]) + "_" +  str(data[4]) + "_" +  str(data[5]) + "_CRC = " +  str(data_crc8[1]) )
					print("  SCD30_read_T   : " + str(data[6]) + "_" +  str(data[7]) + "_" +  str(data[8])  + "_CRC=" +  str(data_crc8[2]) + " , " + str(data[9]) + "_" +  str(data[10]) + "_" +  str(data[11]) + "_CRC = " +  str(data_crc8[3]) )
					print("  SCD30_read_HR  : " + str(data[12]) + "_" +  str(data[13]) + "_" +  str(data[14])  + "_CRC=" +  str(data_crc8[4]) + " , " + str(data[15]) + "_" +  str(data[16]) + "_" +  str(data[17]) + "_CRC = " +  str(data_crc8[5]) )

				#----------------------------------------------------------------------------------
				# test des CRC
				#----------------------------------------------------------------------------------
				if ( ( data[2]  == data_crc8[0] )  and ( data[5]  == data_crc8[1] ) and 
					 ( data[8]  == data_crc8[2] )  and ( data[11] == data_crc8[3] ) and 
					 ( data[14] == data_crc8[4] )  and ( data[17] == data_crc8[5] ) ):
					 
					struct_CO2 = struct.pack('>BBBB', data[0], data[1], data[3], data[4])
					SCD30_CO2 = struct.unpack('>f', struct_CO2)
					chaine_SCD30_CO2 = "%d" % SCD30_CO2
					if int(chaine_SCD30_CO2) > 9999 :
						chaine_SCD30_CO2 = "9999"

					struct_T = struct.pack('>BBBB', data[6], data[7], data[9], data[10])
					SCD30_T = struct.unpack('>f', struct_T)
					chaine_SCD30_T = "%2.2f" % SCD30_T

					struct_HR = struct.pack('>BBBB', data[12], data[13], data[15], data[16])
					SCD30_HR = struct.unpack('>f', struct_HR)
					chaine_SCD30_HR = "%2.1f" % SCD30_HR

					if globals.DEBUG_SCD30:
						print("  SCD30_raw = " + chaine_SCD30_CO2 + " ppm ; " +  chaine_SCD30_T + " °C ; " + chaine_SCD30_HR + " %" )
						print(" ")

					chaine_SCD30 = [ chaine_SCD30_T, chaine_SCD30_HR, chaine_SCD30_CO2 ]
					
				else:
					globals.Flag_mesures_OK = ( globals.Flag_mesures_OK & 0xFFFFFFFFFFF0 )  | 0x000000000001
					globals.SCD30_FLAG = False
					if globals.DEBUG_SCD30:
						print("  SCD30_read : erreur CRC !")
					
			else:
				globals.Flag_mesures_OK = ( globals.Flag_mesures_OK & 0xFFFFFFFFFFF0 )  | 0x000000000002
				globals.SCD30_FLAG = False
				if globals.DEBUG_SCD30:
					print("  SCD30_read : erreur_nb_bytes !")
		else:
			globals.Flag_mesures_OK = ( globals.Flag_mesures_OK & 0xFFFFFFFFFFF0 )  | 0x000000000003
			globals.SCD30_FLAG = False
			if globals.DEBUG_SCD30:
				print("  SCD30_read : data not ready !")
			
	except:
		globals.Flag_mesures_OK = ( globals.Flag_mesures_OK & 0xFFFFFFFFFFF0 )  | 0x000000000004
		globals.SCD30_FLAG = False
		if globals.DEBUG_SCD30:
			print("  SCD30_read : exception !")
		
	finally:
		time.sleep(0.050)
		return chaine_SCD30
		




		
