/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    yunhorn_sts_process.c      									   *   
  * @author  Yunhorn (r) Technology Limited Application Team	               *
  * @brief   Yunhorn (r) SmarToilets (r) Product configuration file.		   *
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 Yunhorn Technology Limited.
  * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "stdint.h"
#include "platform.h"
#include "sys_conf.h"
#include "sys_app.h"
#include "stdio.h"
#include "stm32_systime.h"
#include "adc_if.h"
#include "gpio.h"
#include "LmHandler.h"
#include "app_tof.h"
#include "lora_app.h"
#include "yunhorn_sts_prd_conf.h"
#include "yunhorn_sts_sensors.h"
#include "sts_cmox_hmac_sha.h"

/* USER CODE BEGIN Includes */
extern volatile sts_cfg_nvm_t sts_cfg_nvm;
extern volatile uint8_t sts_ac_code[20];
volatile uint8_t sts_service_mask;
volatile uint32_t rfac_timer;
extern volatile uint8_t sensor_data_ready;
extern volatile uint8_t sts_work_mode;
volatile uint8_t sts_reed_hall_result, last_sts_reed_hall_result,sts_reed_hall_changed_flag;
volatile uint32_t event_start_time, event_stop_time;
volatile uint8_t sts_soap_level_state;


extern volatile uint8_t sts_reed_hall_result, sts_work_mode, sts_service_mask;
volatile uint8_t sts_reed_hall_ext_int = 0;
volatile uint8_t sts_occupancy_status;
volatile uint8_t sts_reed_hall_changed_flag = 0;
volatile uint8_t sts_reed_hall_result =0;
volatile uint8_t sts_water_leakage_result=0;
volatile uint8_t sts_water_leakage_changed_flag=0;
extern volatile uint8_t sensor_data_ready;
#ifdef YUNHORN_STS_R4_ENABLED
volatile STS_R0_SensorDataTypeDef r4_data;
#endif

#ifdef YUNHORN_STS_O5_ENABLED

#endif
#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111))
extern volatile STS_OO_RSS_SensorTuneDataTypeDef sts_presence_rss_config;
extern volatile uint8_t sts_rss_result, sts_rss_2nd_result;
extern volatile distance_measure_cfg_t distance_cfg;
volatile uint8_t sts_work_mode = STS_DUAL_MODE;
extern uint8_t luminance_level;
extern volatile uint8_t sts_status_color;
extern volatile uint8_t sts_lamp_bar_color;		//puColor
extern volatile uint8_t sts_cloud_netcolor;		//netColor

volatile uint8_t sts_tof_result_changed_flag = 0;

volatile uint8_t sts_rss_result_changed_flag = 0;
volatile uint8_t sts_rss_result = STS_RESULT_NO_MOTION;
volatile uint8_t sts_rss_2nd_result = STS_RESULT_NO_MOTION;		//2nd RSS sensor status
volatile uint8_t sts_tof_result = STS_RESULT_NO_MOTION;
volatile uint8_t last_sts_rss_result;
extern volatile uint8_t last_sts_rss_result;
extern volatile uint8_t last_sts_reed_hall_result;
extern volatile uint8_t last_lamp_bar_color;
extern volatile float sts_presence_rss_distance;

#endif   


/*
  	    // UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventP4), CFG_SEQ_Prio_0);
	  	// P1    --- REEDSWITCH, HALL ELEMENT, WATER LEAKAGE
	   	// P2    --- SEE ABOVE, RSS PRESENCE
	   	// P3    ----LAMP BAR SCOLLER PROCESS
	   	// P4    --- TOF DISTANCE  VL53L0X simple distance
	   	// P5    --- TOF IN OUT COUNT  VL53L3X in out or duration
	   	// P6    --- SOAP Level, capacitive measurement
	   	// P7    --- UltraSonic, 2nd wave UltraSonic range measure
	   	// P8    --- AIR QUALITY AND ODOR LEVEL, SMOKING DETECTION
*/


/* USER CODE END Includes */

/* External variables ---------------------------------------------------------*/
/* USER CODE BEGIN EV */

/* USER CODE END EV */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/

/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111))

#endif

/* USER CODE END PFP */

/* Exported functions --------------------------------------------------------*/

void STS_YunhornAuthenticationCode_Process(void)
{
	if ((sts_ac_code[0] == 0x00) && (sts_ac_code[19]== 0x0)) {
		APP_LOG(TS_OFF,VLEVEL_M, "Initial AC CODE blank... \r\n");
		return;
	}

	sts_service_mask = (sts_hmac_verify()!= 0)? STS_SERVICE_MASK_L2:STS_SERVICE_MASK_L0;
	if (sts_service_mask == STS_SERVICE_MASK_L2) {
		sts_ac_code[0] = 0x0;
		sts_ac_code[19]= 0x0;
	}
	APP_LOG(TS_OFF, VLEVEL_H, "STS_SERVICE_MASK:%d \r\n",sts_service_mask);
}

void STS_YunhornSTSEventRFAC_Process(void)
{
	if ((sts_ac_code[0] ==0x0)&& (sts_ac_code[19]== 0x0))
	{
		if ((rfac_timer >= STS_BURN_IN_RFAC) && (rfac_timer < (STS_BURN_IN_RFAC +3)))
		{
			APP_LOG(TS_OFF, VLEVEL_M, "\r\n -------------------RFAC Process\r\n");
			STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, 4, "RFAC");
		}
		if ((rfac_timer > (STS_BURN_IN_RFAC + 2)))
		{
			APP_LOG(TS_OFF, VLEVEL_M, "\r\n -------------------Verify RFAC Success or Not\r\n");
			sts_service_mask = (sts_hmac_verify()!= 0)? STS_SERVICE_MASK_L2:STS_SERVICE_MASK_L0;
			if (sts_service_mask == STS_SERVICE_MASK_L2) {
				sts_ac_code[0] = 0x0;
				sts_ac_code[19] = 0x0;
			}
		}
	}

}

/*
 *  STS-P1    --- REEDSWITCH, HALL ELEMENT, WATER LEAKAGE
 */

void STS_YunhornSTSEventP1_Process(void)
{

#if defined(YUNHORN_STS_O5_ENABLED)

	if ((sts_work_mode == STS_WIRED_MODE) || (sts_work_mode == STS_REEDSWITCH_MODE) || (sts_work_mode == STS_DUAL_MODE))
		{
			STS_Reed_Hall_Presence_Detection();

			if (sts_reed_hall_result == last_sts_reed_hall_result) {
				sts_reed_hall_changed_flag = 0;
			} else {
				sts_reed_hall_changed_flag = 1;
#ifdef LED_ONBOARD
				STS_Combined_Status_Processing();
#endif
			}

			last_sts_reed_hall_result = sts_reed_hall_result;
		}

#endif
#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111))
	if ((sts_work_mode == STS_WIRED_MODE) || (sts_work_mode == STS_REEDSWITCH_MODE) || (sts_work_mode == STS_DUAL_MODE))
	{
		STS_Reed_Hall_Presence_Detection();

		if (sts_reed_hall_result == last_sts_reed_hall_result) {
			sts_reed_hall_changed_flag = 0;
		} else {
			sts_reed_hall_changed_flag = 1;
			STS_Combined_Status_Processing();
		}

		last_sts_reed_hall_result = sts_reed_hall_result;
	}
#endif

}


/*
 *  STS-P2    --- SEE ABOVE, RSS PRESENCE
 */
void STS_YunhornSTSEventP2_Process(void)
{
#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111))
	if ((sts_work_mode >= STS_RSS_MODE) && (sts_work_mode <= STS_TOF_RSS_MODE))
	{
		STS_RSS_Smart_Presence_Detection();
		STS_Reed_Hall_Presence_Detection();

		if (sts_rss_result == last_sts_rss_result) {
			sts_rss_result_changed_flag =0;
		} else 	{
			sts_rss_result_changed_flag =1;
		}

		if (sts_reed_hall_result == last_sts_reed_hall_result)
		{
			sts_reed_hall_changed_flag = 0;

		} else
		{
			sts_reed_hall_changed_flag = 1;
		}

		STS_Combined_Status_Processing();

		last_sts_rss_result = sts_rss_result;
		last_sts_reed_hall_result = sts_reed_hall_result;
	}
#endif
}

void STS_Reed_Hall_Presence_Detection(void)
{
#if (defined(YUNHORN_STS_O5_ENABLED) || defined(YUNHORN_STS_O6_ENABLED) || defined(USE_ACCONEER_A111))
	HAL_Delay(50);										// BOUNCING ELIMIATION
	if (STS_Reed_Hall_State == STS_Status_Door_Open)
	{
		sts_reed_hall_result = STS_Status_Door_Open;

	} else if (STS_Reed_Hall_State == STS_Status_Door_Close)
	{
		sts_reed_hall_result = STS_Status_Door_Close;

	}
	HAL_Delay(20);										// BOUNCING ELIMIATION
	sts_reed_hall_changed_flag = 0;
	sts_reed_hall_ext_int = 0;
#endif
}

void STS_RSS_Smart_Presence_Detection(void)
{
#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111))
	sts_presence_rss_presence_detection();
#endif
}

/*
 *  STS P3 process, Lamp Bar Scoller
 */
void STS_YunhornSTSEventP3_Process(void)
{
#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111))
		if (STS_Reed_Hall_State == STS_Status_Door_Open)
		{
			sts_lamp_bar_color =STS_GREEN;
		}
		else
		{
			sts_lamp_bar_color =STS_RED;
		}
		STS_Lamp_Bar_Scoller(sts_lamp_bar_color, luminance_level);
#endif
}

/*
 *  STS-P4 Detection ToF distance (VL53L0X)
 *
 */
void STS_YunhornSTSEventP4_Process(void)
{
	STS_SENSOR_Power_ON(0);
#ifdef	LED_ONBOARD
	LED_ON;
	HAL_Delay(10);
	LED_OFF;
#endif
#if defined(TOF_1)||defined(TOF_2)
	APP_LOG(TS_OFF, VLEVEL_H, "\r\n TOF_1, TOF_2 RANGING Process\r\n");
	STS_TOF_VL53L0X_Range_Process();
#endif

#ifdef TOF_3
	APP_LOG(TS_OFF, VLEVEL_H, "\r\n TOF 3 RANGING Process ---- TOF250 Ranging \r\n");
	STS_TOF250_Range_Process();
#endif

	STS_SENSOR_Power_OFF(0);

}


/*
 *  STS P5 Process, Detection ToF IN-OUT PEOPLE COUNT (VL53L3X)
 *
 */
void STS_YunhornSTSEventP5_Process(void)
{
	APP_LOG(TS_OFF, VLEVEL_L, "\r\n P5 Testing Process\r\n");
}

/*
 * STS-P6	--- SOAP Level, capacitive measurement
 * STS Soap Level Detection Process, STS_CAP_Sensor_Detection Process
 * STS_CAP_SWITCH(ON) Boost Voltage to 5V, then hold for 1000 ms
 * HAL_Delay(1000) (ms)
 * STS_CAP_Read_Data()	Read STS_CAP_DATA state
 * STS_CAP_SWITCH(OFF)   Switch Off Boosted Voltage
 */
void STS_YunhornSTSEventP6_Process(void)
{
	APP_LOG(TS_OFF, VLEVEL_H, "\r\n P6 Testing Process\r\n");
	STS_SENSOR_Power_ON(0);
#ifdef LED_ONBOARD
	LED_ON;
	HAL_Delay(20);
	LED_OFF;
#endif
/* 1. Sensor  Power On */
#if defined(SOAP_LEVEL)
	HAL_GPIO_WritePin(SOAP_SWITCH_GPIO_Port, SOAP_SWITCH_Pin, GPIO_PIN_SET);

	HAL_Delay(1000);
	/* 2. Read sensor state */

	sts_soap_level_state = HAL_GPIO_ReadPin(SOAP_STATUS_GPIO_Port,SOAP_STATUS_Pin);
	APP_LOG(TS_OFF, VLEVEL_L, "\r\n Soap State = %s \r\n", (sts_soap_level_state==0x0)?"  +++  Liquid Detected":"  ---  No Liquid");

	HAL_GPIO_WritePin(SOAP_SWITCH_GPIO_Port, SOAP_SWITCH_Pin, GPIO_PIN_RESET);

	if (sts_soap_level_state == 0x0)
	{
#ifdef LED_ONBOARD
		LED_ON;
		HAL_Delay(20);
		LED_OFF;
#endif
	}

#endif
/* 3. Sensor  Power Off */
	STS_SENSOR_Power_OFF(0);
}


/*
 *  STS P7 Process, Detection IAQ Sensors
 *  air quality and odor level sensors
 */
void STS_YunhornSTSEventP7_Process(void)
{
	APP_LOG(TS_OFF, VLEVEL_L, "\r\n P7 Testing Process\r\n");
	STS_SENSOR_Power_ON(0);

	STS_SENSOR_Power_OFF(0);
}


/*
 *  STS P8 Process, Detection ETR Sensors, Water flow sensors, pulse counting
 *  PA5 sensors , TIM2_ETR, STS-M4
 */
void STS_YunhornSTSEventP8_Process(void)
{
	APP_LOG(TS_OFF, VLEVEL_L, "\r\n P8 Testing Process\r\n");

}

/*
 *  STS P_IO_RS485 Process, Send Out Sensor Data Via RS485 interface
 *  sensors
 */

void STS_YunhornSTSEventPIORS485_Process(void)
{
	APP_LOG(TS_OFF, VLEVEL_L, "\r\n P_IO_RS485 Process\r\n");
}


void STS_Combined_Status_Processing(void)
{
#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111))
	switch (sts_work_mode)
	{
		case STS_NETWORK_MODE:
			sts_status_color = sts_cloud_netcolor;
			break;
		case STS_WIRED_MODE:				// NO LAMP BAR FOR THOSE WATER LEAKAGE SENSOR OR SOAP CAPACITY SENSORS
			sts_status_color = STS_DARK;
			sts_water_leakage_result = sts_reed_hall_result; // == STS_Status_Door_Open )?1U:0U; //STS_RESULT_WATER_LEAKAGE_YES:STS_RESULT_WATER_LEAKAGE_NO;
			sts_water_leakage_changed_flag = 1;
			break;
		case STS_REEDSWITCH_MODE:

			sts_status_color = (sts_reed_hall_result == STS_Status_Door_Open )? STS_GREEN: STS_RED;

			break;
		case STS_RSS_MODE:
			if (sts_rss_result == STS_RESULT_NO_MOTION){
				sts_status_color = STS_GREEN;
			} else if ((sts_rss_result == STS_RESULT_MOTION))
			{
				sts_status_color = STS_RED;
			}
			break;
		case STS_DUAL_MODE:
			if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_reed_hall_result == STS_Status_Door_Open ))
			{
				sts_status_color = STS_GREEN;

			} else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close ))
			{
				sts_status_color = STS_RED;
			}
			break;
		case STS_DUAL_RSS_MODE:
			if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_rss_2nd_result == STS_RESULT_NO_MOTION))
			{
				sts_status_color = STS_GREEN;
			} else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_rss_2nd_result == STS_RESULT_MOTION))
			{
				sts_status_color = STS_RED;
			}

			break;
		case STS_TOF_RSS_MODE:
			if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_tof_result == STS_RESULT_NO_PRESENCE)){
				sts_status_color = STS_GREEN;

			} else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_tof_result == STS_RESULT_PRESENCE))
			{
				sts_status_color = STS_RED;
			}

			break;
//   TO-DO LIST  ***********************************************************
		case STS_TOF_DISTANCE_MODE:
			if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) {
				sts_status_color = STS_GREEN;
			} else if ((sts_tof_result == STS_RESULT_PRESENCE)) {
				sts_status_color = STS_RED;
			}
			break;
		case STS_TOF_PRESENCE_MODE:
			if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) {
				sts_status_color = STS_GREEN;
			} else if ((sts_tof_result == STS_RESULT_PRESENCE)) {
				sts_status_color = STS_RED;
			}
			break;
		case STS_TOF_IN_OUT_MODE:
			if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) {
				sts_status_color = STS_GREEN;
			} else if ((sts_tof_result == STS_RESULT_PRESENCE)) {
				sts_status_color = STS_RED;
			}
			break;
//   TO-DO LIST  ***********************************************************
		default:
			break;
	}
	if (sts_work_mode != STS_WIRED_MODE)
	{
		if ((last_lamp_bar_color != sts_status_color))
		{
			sts_lamp_bar_color = ((sts_service_mask == STS_SERVICE_MASK_L0)? STS_DARK: sts_status_color);

				STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level);
				if ((sts_service_mask == STS_SERVICE_MASK_L0) || (sts_lamp_bar_color == STS_DARK))
				{
					STS_WS2812B_Refresh();
				}

			last_lamp_bar_color = sts_lamp_bar_color;
		}
	} else STS_Lamp_Bar_Set_Dark();

	if ((sts_rss_result_changed_flag + sts_reed_hall_changed_flag + sts_tof_result_changed_flag +sts_water_leakage_changed_flag))
		sensor_data_ready = 1U;
	STS_PRESENCE_SENSOR_Prepare_Send_Data();
#endif
}

void STS_SENSOR_Power_ON(uint8_t cnt)
{
	switch (cnt) {
		case 0:
		case 1:
		case 2:
#if	(defined(YUNHORN_STS_M7_ENABLED) || defined(YUNHORN_STS_R0_ENABLED))
		HAL_GPIO_WritePin(MEMS_POWER_GPIO_Port, MEMS_POWER_Pin, GPIO_PIN_SET);
#endif


		break;
		default:
		break;
	}

}
void STS_SENSOR_Power_OFF(uint8_t cnt)
{
	switch (cnt) {
		case 0:
		case 1:
		case 2:
#if	(defined(YUNHORN_STS_M7_ENABLED) || defined(YUNHORN_STS_R0_ENABLED))
		HAL_GPIO_WritePin(MEMS_POWER_GPIO_Port, MEMS_POWER_Pin, GPIO_PIN_RESET);
#endif

		break;
		default:
		break;
	}
}

void STS_SENSOR_MEMS_Reset(uint8_t cnt)
{
	switch (cnt) {
		case 0:
		case 1:
		case 2:
#if	(defined(YUNHORN_STS_M7_ENABLED) || defined(YUNHORN_STS_R0_ENABLED))
		HAL_GPIO_WritePin(MEMS_RESET_GPIO_Port, MEMS_RESET_Pin, GPIO_PIN_SET);
		HAL_Delay(50);
		HAL_GPIO_WritePin(MEMS_RESET_GPIO_Port, MEMS_RESET_Pin, GPIO_PIN_RESET);
#endif
		HAL_GPIO_WritePin(MEMS_RESET_GPIO_Port, MEMS_RESET_Pin, GPIO_PIN_SET);
		HAL_Delay(50);
		HAL_GPIO_WritePin(MEMS_RESET_GPIO_Port, MEMS_RESET_Pin, GPIO_PIN_RESET);
		break;
		default:
		break;
	}

}


void YUNHORN_STS_R4_SENSOR_Read(STS_R0_SensorDataTypeDef *r4_data)
{
#ifdef	SOAP_LEVEL
	r4_data->on_off_event = (sts_soap_level_state==0x0)? 1:0;
	r4_data->measure_tech = 0x0;	// capacity measure
#endif

	sensor_data_ready = 0x1;
}

void YUNHORN_STS_R4_SENSOR_Init(void)
{
	r4_data.on_off_event = 0x0;
	r4_data.measure_tech = 0x0;
	sensor_data_ready = 0x0;
}

#if	defined(YUNHORN_STS_R4_ENABLED)
void STS_R0_SENSOR_Read(STS_R0_SensorDataTypeDef *r0_data)
{
#ifdef SOAP_LEVEL
	r0_data->on_off_event = sts_soap_level_state;
	r0_data->measure_tech = 0;  /* 0: capacit, 1:dTof, 2: ultrasonic  */
#elif defined(TOF_1)||defined(TOF_2)||defined(TOF_3)
	r0_data->measure_tech = 1;  /* 0: capacit, 1:dTof, 2: ultrasonic  */
	r0_data->distance_mm  = sts_tof_distance_data[0];
	r0_data->distance1_mm = sts_tof_distance_data[1];
	r0_data->distance2_mm = sts_tof_distance_data[2];
#elif 	defined(ROCTEC_R5)
	r0_data->distance1_mm = sts_tof_distance_data[0]+sts_tof_distance_data[1]+sts_tof_distance_data[2];
#endif

	sensor_data_ready = 1;
}
#endif

void STS_SENSOR_NVM_CFG(void)
{

}

void STS_SENSOR_NVM_CFG_SIMPLE(void)
{

}

#if	defined(YUNHORN_STS_O5_ENABLED)
void STS_O5_SENSOR_Read(STS_OO_SensorDataTypeDef *oo_data)
{

	oo_data->state_sensor1_on_off  = sts_reed_hall_result;


	sensor_data_ready = 1;
}
#endif

/* USER CODE BEGIN EF */

/* USER CODE END EF */

/* Private Functions Definition -----------------------------------------------*/
/* USER CODE BEGIN PrFD */

/* USER CODE END PrFD */
