#ifndef MICRODOWELL_H
#define MICRODOWELL_H

#ifdef ENTERPRISE_PROTOCOL

#include <ctype.h>


#define STX_CHAR					'['
#define ERR_COM_NO_CHARS      -999  // nessun carattere dalla porta seriale
#define ERR_MSG_TOO_SHORT     -998  // messaggio troppo breve: non arriva sino al Checksum
#define ERR_MSG_CHECKSUM      -997  // checksum non valido
#define ERR_COM_TIMEOUT       -996  // timeout in lettura
#define ERR_CLR_RX_BUFF			-900  // bisogna cancellare il buffer (non è un errore!)
#define COMMAND_NOT_VALID     -50   // comando non valido
#define PARAMETER_NOT_VALID   -51   // parametro non valido
#define ERR_UPS_NOT_FOUND     -10   // non trovo un UPS
#define ERR_COM_PORT_OPEN     -11   // impossibile aprire la porta di comunicazione
#define ERR_COM_SET_PORT      -12   // impossibile configurare la porta di comunicazione
#define ERR_COM_UNDEF_PORT    -20   // porta non valida o non esistente
#define ERR_USB_DRIVER        -13   // impossibile aprire il driver USB
#define ERR_USB_COMM_KO       -14   // interfaccia USB OK: gruppo spento o guasto
#define ERR_UPS_UNKNOWN       -30   // impossibile identificare l'UPS
#define ERR_PRG_THREAD        -40   // impossibile creare uno thread
#define ERR_PRG_INVALID_DATA  -60   // dati non validi

#define ERR_NO_ERROR				0x00  // no errors
#define ERR_I2C_BUSY       	0x01	// I2C bus busy (e2prom)
#define ERR_CMD_CHECKSUM      0x10	// Checksum not valid
#define ERR_CMD_UNRECOG       0x11	// unrecognized command
#define ERR_EEP_NOBLOCK    	0x08	// WRITE: eeprom address not multiple of 8
#define ERR_EEP_OOBOUND    	0x09	// READ: eeprom address out of bound (with size)
#define ERR_EEP_WADDR1     	0x28	// error writing e2prom address
#define ERR_EEP_WSADDR1    	0x29	// error writing e2prom subaddress
#define ERR_EEP_RDATA      	0x2A	// error reading e2prom data
#define ERR_EEP_WADDR2     	0x50	// error writing e2prom address
#define ERR_EEP_WSADDR2    	0x51	// error reading e2prom subaddress
#define ERR_EEP_WDATA      	0x52	// error writing e2prom data
#define ERR_EEP_WADDRVER   	0x53	// error writing e2prom address during data verification
#define ERR_EEP_WDATAVER   	0x54	// error verification e2prom data
#define ERR_EEP_VERIFY     	0x55	// e2prom data are different from those in the write buffer
#define ERR_EEP_CHECKSUM   	0x90	// e2prom checksum error



#define  CMD_ACK              0x06  // ACK
#define  CMD_NACK             0x15  // NACK

#define  CMD_GET_STATUS       0x00  // comando di acquisizione STATUS
#define  CMD_GET_MEASURES     0x01  // comando di acquisizione MISURE
#define  CMD_GET_CONFIG       0x02  // comando di acquisizione CONFIGURAZIONE
#define  CMD_GET_BATT_STAT    0x03  // comando di acquisizione Battery+Load Status
#define  CMD_GET_BAT_LD       0x03  // comando di acquisizione Battery+Load Status
#define  CMD_GET_MASK         0x07  // comando di acquisizione MASCHERA PUNTI
#define  CMD_SET_TIMER        0x20  // comando di CONFIGURAZIONE TIMER
#define  CMD_BATT_TEST        0x21  // comando di CONFIGURAZIONE TEST BATTERIA
#define  CMD_GET_BATT_TEST    0x22  // comando di       LETTURA  TEST BATTERIA
#define  CMD_SD_ONESHOT       0x40  // comando di SCRITTURA SHUTDOWN ONESHOT
#define  CMD_GET_SD_ONESHOT   0x41  // comando di  LETTURA  SHUTDOWN ONESHOT
#define  CMD_SET_SCHEDULE     0x42  // comando di SCRITTURA SCHEDULE
#define  CMD_GET_SCHEDULE     0x43  // comando di  LETTURA  SCHEDULE
#define  CMD_GET_EEP_BLOCK    0x50  // comando di  LETTURA  BLOCCO EEPROM
#define  CMD_SET_EEP_BLOCK    0x51  // comando di SCRITTURA BLOCCO EEPROM
#define  CMD_GET_EEP_SEED     0x52  // comando di acquisizione SEME PROGR. EEPROM
#define  CMD_INIT             0xF0  // comando di REINIZIALIZZAZIONE UPS


#define  LEN_ACK              1  // ACK
#define  LEN_NACK             2  // NACK

#define  LEN_GET_STATUS       1  // comando di acquisizione STATUS
#define  LEN_GET_MEASURES     1  // comando di acquisizione MISURE
#define  LEN_GET_CONFIG       1  // comando di acquisizione CONFIGURAZIONE
#define  LEN_GET_BATT_STAT    1  // comando di acquisizione Battery+Load Status
#define  LEN_GET_BAT_LD       1  // comando di acquisizione Battery+Load Status
#define  LEN_GET_MASK         1  // comando di acquisizione MASCHERA PUNTI
#define  LEN_SET_TIMER        5  // comando di CONFIGURAZIONE TIMER
#define  LEN_BATT_TEST        4  // comando di CONFIGURAZIONE TEST BATTERIA
#define  LEN_GET_BATT_TEST    1  // comando di       LETTURA  TEST BATTERIA
#define  LEN_SD_ONESHOT       8  // comando di SCRITTURA SHUTDOWN ONESHOT
#define  LEN_GET_SD_ONESHOT   1  // comando di  LETTURA  SHUTDOWN ONESHOT
#define  LEN_SET_SCHEDULE     8  // comando di SCRITTURA SCHEDULE
#define  LEN_GET_SCHEDULE     2  // comando di  LETTURA  SCHEDULE
#define  LEN_GET_EEP_BLOCK    3  // comando di SCRITTURA BLOCCO EEPROM
#define  LEN_SET_EEP_BLOCK    12 // comando di SCRITTURA BLOCCO EEPROM
#define  LEN_GET_EEP_SEED     1  // comando di acquisizione SEME PROGR. EEPROM
#define  LEN_INIT             1  // comando di REINIZIALIZZAZIONE UPS


// non completamente definiti!
#define  RET_GET_STATUS       10  // comando di acquisizione STATUS
#define  RET_GET_MEASURES     15  // comando di acquisizione MISURE
#define  RET_GET_CONFIG       11  // comando di acquisizione CONFIGURAZIONE
#define  RET_GET_BATT_STAT    10  // comando di acquisizione Battery+Load Status
#define  RET_GET_BAT_LD       10  // comando di acquisizione Battery+Load Status
#define  RET_GET_MASK         1  // comando di acquisizione MASCHERA PUNTI
#define  RET_SET_TIMER        5  // comando di CONFIGURAZIONE TIMER
#define  RET_BATT_TEST        4  // comando di CONFIGURAZIONE TEST BATTERIA
#define  RET_GET_BATT_TEST    1  // comando di       LETTURA  TEST BATTERIA
#define  RET_SD_ONESHOT       8  // comando di SCRITTURA SHUTDOWN ONESHOT
#define  RET_GET_SD_ONESHOT   1  // comando di  LETTURA  SHUTDOWN ONESHOT
#define  RET_SET_SCHEDULE     8  // comando di SCRITTURA SCHEDULE
#define  RET_GET_SCHEDULE     8  // comando di  LETTURA  SCHEDULE
#define  RET_GET_EEP_BLOCK    11  // comando di SCRITTURA BLOCCO EEPROM
#define  RET_SET_EEP_BLOCK    12 // comando di SCRITTURA BLOCCO EEPROM
#define  RET_GET_EEP_SEED     1  // comando di acquisizione SEME PROGR. EEPROM
#define  RET_INIT             1  // comando di REINIZIALIZZAZIONE UPS


//=======================================================
// Indirizzi delle variabili memorizzate nella EEPROM: //
//=======================================================
#define  EEP_OPT_BYTE_BLK 0x00 // Option Bytes block
#define  EEP_MAGIC        0x00 // magic number: deve essere a 0xAA
#define  EEP_CHECKSUM     0x01 // XOR longitudinale da 0x?? a 0x??
#define  EEP_OUT_CONFIG   0x02 // vedi documentazione
#define  EEP_OPT_BYTE_0   0x02 // vedi documentazione
#define  EEP_OPT_BYTE_1   0x03 // vedi documentazione
#define  EEP_STATUS       0x04 // Status UPS

#define  EEP_THRESHOLD_0  0x08 // Blocco 0 con gli threshold
#define  EEP_MEAN_MIN     0x08 // UPS minimum AC voltage intervention point
#define  EEP_MEAN_MAX     0x0A // UPS maximum AC voltage intervention point
#define  EEP_AVR_MIN      0x0C // AVR minimum AC voltage intervention point
#define  EEP_AVR_MAX      0x0E // AVR maximum AC voltage intervention point

#define  EEP_THRESHOLD_1  0x10 // Blocco 1 con gli threshold
#define  EEP_BLOW_VALUE   0x10 // Battery LOW threshold voltage
#define  EEP_BEND_VALUE   0x12 // Battery END threshold voltage
#define  EEP_VMETER_0     0x14 // Led 0 Voltage indicator threshold
#define  EEP_VMETER_1     0x16 // Led 1 Voltage indicator threshold

#define  EEP_THRESHOLD_2  0x18 // Blocco 2 con gli threshold
#define  EEP_VMETER_2     0x18 // Led 2 Voltage indicator threshold
#define  EEP_VMETER_3     0x1A // Led 3 Voltage indicator threshold
#define  EEP_VMETER_4     0x1C // Led 4 Voltage indicator threshold

#define  EEP_FAULT_POINTS 0x20 // number of fault points (in an half sine wave) after which USP enter battery mode
#define  EEP_CHARGER_MIN  0x21 // Threshold voltage for battery charger

#define  EEP_TEMP_MAX     0x28 // Maximum temperature: over this value an alarm will be generated
#define  EEP_TEMP_FAULT   0x2A // Fault temperature: over this value, UPS will shut down immediately
#define  EEP_FANSPEED_0   0x2C // Temperature for fan activation (low speed)
#define  EEP_FANSPEED_1   0x2E // Temperature for fan activation (medium speed)

#define  EEP_FANSPEED_2   0x30 // Temperature for fan activation (high speed)

#define  EEP_IOUT         0x38 //
#define  EEP_IOUT_OVRLD   0x38 // Maximum current: over this value an alarm will be generated
#define  EEP_IOUT_FAULT   0x3A // Fault current: over this value, UPS will shut down immediately
#define  EEP_PWRMTR_0     0x3C // Led 0 Power indicator threshold
#define  EEP_PWRMTR_1     0x3E // Led 1 Power indicator threshold

#define  EEP_PWRMTR_2     0x40 // Led 2 Power indicator threshold
#define  EEP_PWRMTR_3     0x42 // Led 3 Power indicator threshold
#define  EEP_PWRMTR_4     0x44 // Led 4 Power indicator threshold
#define  EEP_PWRMTR_5     0x46 // Between "Full power" and "Overload" Power indicator level

#define  EEP_INPUT_MASK_0 0x48 // Half sine input mask (0-7 of 10 points)
#define  EEP_INPUT_MASK_8 0x50 // Half sine input mask (8-9 of 10 points)

#define  EEP_MIN_VBATT    0x60 // Minimum battery voltaged reached from the last power-on
#define  EEP_RUNTIME_H    0x62 // Working time in minutes (max ~=32 years) (MSB first)
#define  EEP_BAT_TIME_M   0x65 // Time in Battery mode: seconds*2 (max ~=390 days). (MSB first)


#define  EEP_UPS_MODEL    0x80 // Model of the UPS in ASCII. For the Enterprise line, the structure is:
                               //    ENTxxyyy
                               // where:	 xx = Power rating in watts/100 (zero padded at left)
                               //          yyy = model variants (if not defined, space padded to the right)

#define  EEP_NETWRK_ID    0x88 // Network ID in ASCII (not used) - space padded
#define  EEP_NETWRK_NAME  0x90 // Network Name in ASCII (not used) - space padded
#define  EEP_SERIAL_NUM   0x98 // Serial Number in ASCII - zero padded (at left)

#define  EEP_PROD_DATE    0xA0 //
#define  EEP_PROD_YEAR    0xA0 // Year of production (add 2000)
#define  EEP_PROD_WEEK    0xA1 // Week of production [0-51]
#define  EEP_PROD_HW_VER  0xA2 // Hardware version: 2 nibbles ?  Major and Minor number.
#define  EEP_PROD_BRD_VER 0xA3 // Board version: 2 nibbles ?  Major and Minor number.
#define  EEP_PROD_FW_VER  0xA4 // Firmware version: 2 nibbles ?  Major and Minor number.
#define  EEP_PROD_FW_SVER 0xA5 // Firmware SUBversion: 2 nibbles ?  Major and Minor number.
#define  EEP_PROD_BTTRS   0xA6 // number of batteries installed in the UPS


#define  EEP_BATT_SUBST   0xA8 // battery replacement block
#define  EEP_BATT_YEAR_0  0xA8 // Year of 1st battery replacement (add 2000)
#define  EEP_BATT_WEEK_0  0xA9 // Week of 1st battery replacement
#define  EEP_BATT_YEAR_1  0xAA // Year of 2nd battery replacement (add 2000)
#define  EEP_BATT_WEEK_1  0xAB // Week of 2nd battery replacement
#define  EEP_BATT_YEAR_2  0xAC // Year of 3rd battery replacement (add 2000)
#define  EEP_BATT_WEEK_2  0xAD // Week of 3rd battery replacement
#define  EEP_BATT_YEAR_3  0xAE // Year of 4th battery replacement (add 2000)
#define  EEP_BATT_WEEK_3  0xAF // Week of 4th battery replacement


#define  EEP_SCHEDULE     0xC8 // Start of SCHEDULING table
#define  EEP_SCHEDULE_0   0xC8 // 1st Scheduling slot
#define  EEP_SCHEDULE_1   0xD0 // 2nd Scheduling slot
#define  EEP_SCHEDULE_2   0xD8 // 3rd Scheduling slot
#define  EEP_SCHEDULE_3   0xE0 // 4th Scheduling slot
#define  EEP_SCHEDULE_4   0xE8 // 5th Scheduling slot
#define  EEP_SCHEDULE_5   0xF0 // 6th Scheduling slot


#define 	BIT_NO_COMM_UPS 			0x0001	// Event  2 - communications with the UPS lost
#define	BIT_COMM_OK 				0x0002	// Event  3 - communications with the UPS reestablished
#define	BIT_BATTERY_MODE 			0x0004	// Event  5 - the UPS is in Battery mode
#define	BIT_BATTERY_LOW   		0x0008	// Event  6 - the UPS has a LOW battery level
#define	BIT_MAINS_OK 				0x0010	// Event  7 - return of the mains
#define	BIT_OVERLOAD 				0x0020	// Event  8 - the UPS is overloaded
#define	BIT_HIGH_TEMPERATURE		0x0040	// Event  9 - the UPS is in overtemperature
#define	BIT_GENERIC_FAULT 		0x0080	// Event 11 - there is a generic fault
#define	BIT_SYSTEM_SHUTDOWN 		0x0100	// Event 14 - the UPS will shut down IMMEDIATELY
#define	BIT_STANDBY			 		0x0200	// Event 32 - the UPS went in STANDBY MODE
#define	BIT_BATTERY_END   		0x0400	// Event 33 - the UPS went in battery END
#define	BIT_EVENT_0					0x1000	// evento ??
#define	BIT_EVENT_1					0x2000	// evento ??
#define	BIT_FIRST_TIME				0x4000	// se è la prima volta che chiamo la funzione
#define	BIT_POLL_RESTART			0x8000	// se riesco ad identificare l'UPS dopo lo scollegamento, reinvio i dati



typedef struct
   {
   int Port ;       // porta a cui è collegato l' UPS:
                     //    0 = USB
                     //    n = COMn
   char Opened ;    // BOOL flag che identifica se la porta è aperta
   int ErrCode ;		// ultimo codice di errore in fase di lettura
   int ErrCount ; 	// conteggio degli errori
   unsigned char PollFlag ;	// identifica se posso accedere all'UPS
   									// 0x01: se TRUE, polling abilitato
   									// 0x02: se TRUE, la routine di polling dati è attiva: devo attendere
   									// 0x04: se TRUE, bisogna rileggere la configurazione del gruppo
   //------------------------------------------------------------------------
   unsigned long Counter ;    // contatore: viene incrementato ad ogni nuovo POLL
	unsigned char CommStatus ;	// stato delle comunicazioni
	unsigned char FramePointer ; // puntatore al carattere di START dei dati ricevuti
   //------------------------------------------------------------------------
   char UpsModel[9] ;		// modello UPS (8 caratteri)
	unsigned char ge_2kVA ;	// if more or equal to 2KVA
   char SerialNumber[9] ;	// numero di serie dell'UPS

   unsigned short int  YearOfProd ;	// anno di produzione dell'UPS
   unsigned char MonthOfProd ;		// Mese di produzione dell'UPS
   unsigned char DayOfProd ;			// Giorno di produzione dell'UPS
   unsigned char HW_MajorVersion ;	// Hardware: Major version
   unsigned char HW_MinorVersion ;	// Hardware: Minor version
   unsigned char BR_MajorVersion ;	// BoardHardware: Major version
   unsigned char BR_MinorVersion ;	// BoardHardware: Minor version
   unsigned char FW_MajorVersion ;	// Firmware: Major version
   unsigned char FW_MinorVersion ;	// Firmware: Minor version
   unsigned char FW_SubVersion ;		// Firmware: SUBVERSION (special releases
												//					for particular customers)

   unsigned char BatteryNumber ;		// number of batteries in UPS
   //------------------------------------------------------------------------
   unsigned long StatusUPS ;	// flag di stato dell'UPS 4 byte): 1=TRUE
									//		bit  0 => BATTERY_MODE
									//		bit  1 => BATTERY_LOW
									//		bit  2 => BATTERY_END
									//		bit  3 => ONLINE (funzionamento in rete)
									//		bit  4 => MAINS_ON (rete di ingresso presente)
									//		bit  5 => STANDBY (UPS in modo Standby)
									//		bit  6 => WAIT_MAINS	(UPS in fase di INIT + attesa rete)
									//		bit  7 => INIT (UPS in fase di inizializzazione)
									//		------
									//		bit  8 => MASK_OK (semionda OK)
									//		bit  9 => MEAN_OK (media tensione di ingresso OK)
									//		bit 10 => SYNC_OK (sincronizzazione semionda OK)
									//		bit 11 => FAULT (generico)
									//		bit 12 => TEMP_MAX (superato livello critico di temperatura)
									//		bit 13 => TEMP_FAULT (Fault da temperatura: UPS si spegne)
									//		bit 14 => LOAD_MAX (soglia overload superata)
									//		bit 15 => LOAD_FAULT (Fault da carico: UPS si spegne)
									//		------
									//		bit 16 => INV_FAULT (Fault dell'inverter)
									//		bit 17 => IINV_MAX (eccessiva corrente sull'inverter)
									//		bit 18 => IINV_FAULT (Fault sulla corrente inverter: l'UPS si spegne)
									//		bit 19 => 50_60Hz (1=60Hz)
									//		bit 20 => EEP_FAULT (problemi con la EEPROM)
									//		bit 21 => VOUT_FAULT (tensione uscita troppo bassa)
									//		bit 22 => - non definito -
									//		bit 23 => - non definito -
									//		------
									//		bit 24 to 31 => - NON DEFINITI -

   unsigned short int  ShortStatus ;   // the LSB 2 bytes of the status
   unsigned char OutConfig  ; // stato uscite UPS
   float Vinput     ; // tensione di INPUT in 1/10 di Volt
   float Voutput    ; // tensione di OUTPUT in 1/10 di Volt
   float Temp       ; // temperatura in 1/10 di grado
   float InpFreq    ; // Frequenza di INPUT in 1/10 di Hz
   float OutFreq    ; // Frequenza di OUTPUT in 1/10 di Hz
   float OutCurrent ; // Corrente di Output in 1/10 di A
   unsigned char LoadPerc   ; // Percentuale di carico
   unsigned short int  LoadVA     ; // Carico in VA
   float ChgCurrent ; // corrente carica batterie

   float Vbatt     ; // tensione delle batterie in 1/10 di Volt
   unsigned char PercBatt  ; // percentuale di carica della batteria
   unsigned short int  RtimeEmpty; // minuti alla scarica della batteria
   unsigned char PercEmpty ; // percentuale alla scarica: 0%=scarica, 100%=carica
   unsigned char OutStatus ; // stato delle uscite

   unsigned char Year      ; //
   unsigned char Month     ; //
   unsigned char Day       ; //
   unsigned char WeekDay   ; // Giorno della settimana
   unsigned char Hour      ; // Ora
   unsigned char Min       ; // minuti
   unsigned char Sec       ; // secondi

	unsigned char BattLowPerc ; // percentuale carica batteria quando va in BLOW
   unsigned long Rtime     ; // numero di minuti di accensione dell'UPS
   unsigned long RtimeBatt ; // numero di secondi*2 in modalità batteria dall'accensione
   //------------------------------------------------------------------------
	unsigned int ShutdownDelay ;	// Shutdown delay in seconds
	unsigned int WakeUpDelay ;		// WakeUp delay in seconds
   } ENT_STRUCT ;



#endif	// ENTERPRISE_PROTOCOL

#endif