/*
 * signals.h
 *
 *  Created on: Jan 28, 2022
 *      Author: xavie
 */

#ifndef SRC_SIGNALS_H_
#define SRC_SIGNALS_H_

#include "main.h"
#include "cmsis_os.h"

#include <stdint.h>
#include <stdbool.h>
#include "commonMsg.h"

#define SOIL_SENSORS	6
#define AIR_SENSORS		2
#define WATER_SENSORS	2


#define MCU_S_ANEMOMETER			0x110
#define MCU_S_RAINGAUGE				0x111
#define MCU_S_WATERTANK				0x210
#define MCU_S_DISDROMETER			0x211
#define MCU_S_TEST					0x215
#define MCU_S_PYRANOMETER			0x221
#define MCU_S_THERMOMETER			0x222
#define MCU_S_SUBSONICGAUGE			0x250
//#define MCU_S_FRAME1					0x311
//#define MCU_S_FRAME2					0x312
//#define MCU_S_FRAME3					0x313
//#define MCU_S_FRAME4					0x314
//#define MCU_S_FRAME5					0x315
//#define MCU_S_FRAME6					0x316
//#define MCU_S_SKYDOME1				0x321
//#define MCU_S_SKYDOME2				0x322

#define MCU_R_COMMAND				0x0FE

typedef union{
		uint8_t data[1];
		struct {
			states stm : 2 ;
			};
	} __attribute__((packed)) FiniteStateMachine;


typedef union{
		uint8_t data[5];
		struct {
			uint16_t MCU_WindSpeed : 9;
			uint16_t MCU_WindDir : 9;
			uint16_t MCU_OutsideTemp : 7; 	// -40 to +87°C
			uint16_t MCU_AtmPressure : 8;
			uint8_t MCU_MaxBeaufort : 4;
			} __attribute__((packed));
	} dev_anemometer;

typedef union{
		uint8_t data[1];
		struct {
			uint8_t MCU_DropDetection : 1;
			uint8_t MCU_CondensationSensing : 1;
			uint8_t MCU_RainingCondition : 3;
			uint8_t MCU_IceSensing : 1;
			} __attribute__((packed));
	} dev_rain_gauge;

typedef union{
		uint8_t data[5];
		struct {
			uint32_t MCU_WaterConsumption : 20;
			uint8_t  MCU_Rain : 1;
			uint16_t MCU_WaterTankLevel : 7;	// 0 to 100
			uint16_t MCU_WaterFlowRate : 6;
			uint8_t MCU_State : 4;
			} __attribute__((packed));
	} dev_watertank;

typedef union{
		uint8_t data[2];
		struct {
			uint16_t MCU_ExternalTemperature : 7;
			uint16_t MCU_BusVoltage : 8;
			}__attribute__((packed));
	}  dev_test;

typedef union{
		uint8_t data[5];
		struct {
			uint16_t MCU_SolarIrradiance : 13;	// 0.0 to 819.1 W/m²
			uint16_t MCU_SolarIrradianceSum : 10;	// 0.00 to 10.23 Wh/m²/day
			uint8_t dummy : 1;
			uint16_t MCU_JunctionTemp : 8;
			uint16_t MCU_BusVoltage : 8 ;
			} __attribute__((packed));
	} dev_pyranometer;

typedef union{
		uint8_t data[4];
		struct {
			uint8_t MCU_InsideTemp : 7;	// -40 to +87°C
			uint8_t dummy : 1;
			uint8_t MCU_InsideHumidity : 7;	// 0 to 100%
			uint8_t dummy1 : 1;
			uint8_t MCU_InsideMaxTemp : 7;
			uint8_t dummy2 : 1;
			uint8_t MCU_InsideMinTemp : 7;
			uint8_t dummy3 : 1;
			} __attribute__((packed));
	} dev_thermometer;

typedef union{
		uint8_t data[2];
		struct {
			uint16_t MCU_BusVoltage : 8;
			uint16_t MCU_AiSimilarity : 8;
			} __attribute__((packed));
	}  dev_subsonic_gauge;

typedef union{
		uint8_t data[6];
		struct {
			uint16_t MCU_AvgRainDropRate : 16;
			uint16_t MCU_AvgRainDropSize : 10;
			uint16_t MCU_AvgRainDropSpeed : 9;
			uint16_t MCU_RainDropCount : 12;
			} __attribute__((packed));
	}  dev_disdrometer;

typedef union{
		uint8_t data[6];
		struct {
			uint16_t RQ_Device : 12;
			uint8_t RQ_OpCode: 3;
			uint8_t dummy: 1;
			uint16_t setpoints[2];
			} __attribute__((packed));
	} dev_command_request;

/**
  * LoRaWAN Sensor data parameters
  */
typedef struct
{
  float atmosphericPressure;     /*!< in mbar */
  float outsideAirTemperature;   /*!< all temperature in degC */
  float greenHouseAirTemperature;
  float	windSpeed;		  /*!< wind speed in m/s */
  uint8_t windDirection;  /*!< wind direction in 1/10° */
  uint8_t maxBeaufort;
  uint8_t greenHouseHumidity;
  float solarIrradiance;  /*!< solar irradiance in W/m² */
  int32_t latitude;       /*!< latitude converted to binary */
  int32_t longitude ;     /*!< longitude converted to binary */
  uint8_t waterLevel;
  bool dropDetection;
  float avgRainProbability;
  float avgRainDropRate;  /*!< in mm/h */
  /**more may be added*/
} LoRaWAN_sensor_t;

typedef struct
{
  uint8_t subsonic_AI_similarity;
  /**more may be added*/
} LoRaWAN_event_sensor_t;

// Function prototypes
float getAvgFloatValue( float tab[], uint16_t size );
float getOutsideTemperature( dev_anemometer s );
uint16_t getAtmPressure( dev_anemometer s );
bool getRain( dev_watertank s );
uint8_t getWaterTankLevel( dev_watertank s );
float getWindSpeed( dev_anemometer s );
uint8_t getWindDirection( dev_anemometer s );
uint8_t getWindBeaufort( dev_anemometer s );
float getSolarIrradiance( dev_pyranometer s );
float getInsideTemperature( dev_thermometer s );
uint8_t getInsideRelativeHumidity( dev_thermometer s );
uint8_t getRainingCondition( dev_rain_gauge s );

uint8_t getSubsonicAiSimilarity( dev_subsonic_gauge s );
float getAvgRainDropRate( dev_disdrometer s );

/**
  * @brief  System data
  */
extern float meas_case_temperature;			// Ampere
extern float meas_valves_current;			// Ampere
extern float meas_drives_current;			// degree Celsius
extern float meas_battery_voltage;			// mV
extern uint16_t VREF;						// mV
/**
  * @brief  Environmental data
  */
extern float gh_outsideTemperature[];		// degree Celsius
extern float gh_insideTemperature[];
extern uint8_t gh_insideHumidity[];
extern float gh_waterTankTemperature[];
extern uint8_t gh_waterTankLevel[];			// Percent
extern uint16_t gh_atmPressure[];			// hecto Pascal
extern uint16_t gh_windSpeed[];
extern uint16_t gh_windDirection[];
extern float gh_soilTemperature[];
extern float gh_solarIrradiance[];
extern uint8_t gh_windMaxBeaufort[];
extern bool gh_dropDetection[];				// No/Yes
extern uint8_t gh_rainingCondition[];
extern uint8_t gh_soilVibesAiSimilarity[];
extern float gh_averageRainDropRate[];
/**
  * @brief  Environmental sensor  read.
  * @param  sensor_data sensor data
  */
int32_t EnvSensors_Read(LoRaWAN_sensor_t *sensor_data);
int32_t EventSensors_Read(LoRaWAN_event_sensor_t *sensor_data);

#endif /* SRC_SIGNALS_H_ */
