/*
    FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.
    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT
    http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
    ***************************************************************************
     *                                                                       *
     *    FreeRTOS tutorial books are available in pdf and paperback.        *
     *    Complete, revised, and edited pdf reference manuals are also       *
     *    available.                                                         *
     *                                                                       *
     *    Purchasing FreeRTOS documentation will not only help you, by       *
     *    ensuring you get running as quickly as possible and with an        *
     *    in-depth knowledge of how to use FreeRTOS, it will also help       *
     *    the FreeRTOS project to continue with its mission of providing     *
     *    professional grade, cross platform, de facto standard solutions    *
     *    for microcontrollers - completely free of charge!                  *
     *                                                                       *
     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *
     *                                                                       *
     *    Thank you for using FreeRTOS, and thank you for your support!      *
     *                                                                       *
    ***************************************************************************
    This file is part of the FreeRTOS distribution.
    FreeRTOS is free software; you can redistribute it and/or modify it under
    the terms of the GNU General Public License (version 2) as published by the
    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
    >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
    distribute a combined work that includes FreeRTOS without being obliged to
    provide the source code for proprietary components outside of the FreeRTOS
    kernel.
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    details. You should have received a copy of the GNU General Public License
    and the FreeRTOS license exception along with FreeRTOS; if not itcan be
    viewed here: http://www.freertos.org/a00114.html and also obtained by
    writing to Real Time Engineers Ltd., contact details for whom are available
    on the FreeRTOS WEB site.
    1 tab == 4 spaces!
    ***************************************************************************
     *                                                                       *
     *    Having a problem?  Start by reading the FAQ "My application does   *
     *    not run, what could be wrong?"                                     *
     *                                                                       *
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
     *                                                                       *
    ***************************************************************************
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
    license and Real Time Engineers Ltd. contact details.
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
    including FreeRTOS+Trace - an indispensable productivity tool, and our new
    fully thread aware and reentrant UDP/IP stack.
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
    Integrity Systems, who sell the code with commercial support,
    indemnification and middleware, under the OpenRTOS brand.

    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
    engineered and independently SIL3 certified version for use in safety and
    mission critical applications that require provable dependability.
*/

#ifndef INC_AUTOM_H
#define INC_AUTOM_H

    /* Header file includes */
#include "FreeRTOS.h"
#include "cmsis_os.h"
#include "time.h"
#include "task.h"
#include "queue.h"
#include "stdbool.h"

#include "commonMsg.h"

#define DATA_VERSION 0x30313250

#define ACTIVE_LOW // comment out this line if your relays are active high
//
#define VALVES_MASK 	0x00FF					// Flushing valve is excluded
#define ALL_VALVES_MASK	(VALVES_MASK|0x8000)	// Flushing valve is included
#define VALVES_ON		(VALVES_MASK)
#define ACTUATORS_MASK	(0x1F00)
#define BITSHIFT_OUTPUT(a) (1U << a)
#define ALL_OUTPUTS_OFF (0x0000)

#define UNDEF_FLOWRATE	255

#ifdef ACTIVE_LOW
// Valve output pin is high when valve is closed
// Actuator output pins is low when actuator is stopped
#define CONVERT_STATE(a) ((~(a) & ALL_VALVES_MASK) | (a & ACTUATORS_MASK))
#else
#define CONVERT_STATE(a) (~(a & ACTUATORS_MASK) | (a & ALL_VALVES_MASK))
#endif


#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte)  \
  (byte & 0x80 ? '8' : '.'), \
  (byte & 0x40 ? '7' : '.'), \
  (byte & 0x20 ? '6' : '.'), \
  (byte & 0x10 ? '5' : '.'), \
  (byte & 0x08 ? '4' : '.'), \
  (byte & 0x04 ? '3' : '.'), \
  (byte & 0x02 ? '2' : '.'), \
  (byte & 0x01 ? '1' : '.')

/* Features */
#define	AUTO_COOLING		0x0300		// Binary
#define	AUTO_CABLE_HEATING	0x0301		// Binary
#define AUTO_SUMP_PUMPING	0x0302
#define CALIBRATION			0x0305		// Module calibration

typedef enum {
  AAR_DISABLE=0x00,
  // actuators will auto start if ...
  AAR_OVER,			// over first setpoint - hysteresis with second setpoint
  AAR_ABOVE, 		// above first setpoint - hysteresis with second setpoint
  AAR_INRANGE, 		// in range of setpoints
  AAR_OUTOFRANGE	// out of range of setpoints
} ActuatorAutoRunning;

typedef enum {
	PER_SELECT,
	PER_EVEN,
	PER_ODD,
	PER_ODD31,
	OVER_2_DAYS,
	OVER_3_DAYS,
	OVER_4_DAYS,
	OVER_5_DAYS
} SelectDays;

typedef struct {
	uint8_t id;
    uint8_t wateringWeekDay;
	uint8_t period;
	uint8_t dummy;
	uint8_t nStartTimes;
	uint16_t startTimes[8];		// in minutes past 00:00
	uint8_t seasonalAdjust;
	bool monthlySeasonalAdjust;
	uint8_t valveDelay;
} WATERING_PROGRAM;

typedef struct {
    uint8_t outputNum;			// ID
    bool autoRunEnabled;
    uint8_t setpoints[2];		// Setpoints used to start and stop the actuator
    uint8_t autoRunFeature;
    float avgCurrentConsumption;	// Average current consumption. Used to safety stop the actuator if overload
} WATERING_ACTUATOR;

typedef struct {
	uint16_t startYearDay;	// Starting at year day - 0 means start only this one immediately
	uint8_t cycleTime;		// Cycle+Soak parameters allow pulsed watering
	uint8_t soakTime;   	// in minutes
	uint16_t runTime[4]; 	// in minutes - 4 programs
} WATERING_SEQUENCE;

typedef struct {
	uint8_t id;
	bool MV_Pump;
	bool sensorsOverride;	// Allow to bypass rain gauge sensor driver (watering even if it is raining)
	bool dummy;
	WATERING_SEQUENCE sequence[4];
	uint8_t pumpAdjust;
} WATERING_VALVE;


typedef struct {
	uint32_t versionID;			// Data version
	int8_t PumpStartDelay;		// Starting pump delay at first valve opening in seconds (+:after -:before)
	int8_t PumpStopDelay;		// Stopping pump delay af last valve closing in seconds (+:after -:before)
	uint8_t FlushingTime;		// Flushing pipes time in seconds
	uint16_t auxStartTime;		// Enable AUX output at specified time, in minutes past 00:00
	uint16_t auxEndTime;		// Disable AUX output at specified time, in minutes past 00:00
	int8_t timeZoneOffset;		// timezone offset in hour
	WATERING_ACTUATOR actuators[5];		// Auxilary actuators( fan, second pump, ...)
	WATERING_VALVE valves[8];			// Watering valves
	WATERING_PROGRAM programs[4];		// Watering programs
	uint16_t seasonalMonthlyParam[12];	// Seasonal monthly watering correction
} WATERING_GENERAL;

typedef struct {
	time_t jTime;					// Start time from 00:00
	char progId;					// Active programs ID
	uint8_t valves;					// Valves selected (bitfield)
	bool tempState;					// ON/OFF Valve
	uint8_t pumpRate;				// From 600 to 100, Default: 90
} WATERING_OF_THE_DAY_STRUCT;


typedef struct {
WATERING_GENERAL settings;
PARAM_SYS_STRUCT paramSys;
} FLASH_STRUCT __attribute__((__aligned__(8)));


int8_t getCaseTemperature(void);
uint16_t findValvesStepState( uint8_t step );
void wateringStats( uint16_t month_id );
int dailyStepWatering( uint8_t step, char* buffer );
void dailyWatering( char* buffer );
int dayCycleRemaining( time_t current_t, int programId );
bool isWateringDay( WATERING_PROGRAM* o, struct tm* t );
int compareWateringList(const void *s1, const void *s2);
uint16_t wateringList( struct tm* current_time, WATERING_OF_THE_DAY_STRUCT list[] );
WATERING_OF_THE_DAY_STRUCT findFirstStartAtNextWatering( time_t t_day );
int findDayDelay( uint8_t st );
uint16_t optimizeWatering( WATERING_OF_THE_DAY_STRUCT list[] );
uint16_t initDaylyWateringList();
uint8_t findSprinklingStep();
uint8_t findAverageFlowRate( uint16_t );
void initCurrentDayCycle( void* ptr );
void Automation_sendCommandToActuators( uint16_t id, ActuatorStates state, uint8_t pumpRate );
void updateAUXtimer( uint16_t actuatorId );
void mainStatement(ActuatorStates state);
bool saveSettings( FLASH_STRUCT* data );
void actuator_reset_state();
void actuator_process( uint8_t id, uint16_t reference );
void vAutomationTask( void *pvParameters );
extern xQueueHandle AutomationQueue;

#endif /* INC_AUTOM_H */
