#ifndef INC_SLAVE_MONITORING_H
#define INC_SLAVE_MONITORING_H

#include <stdint.h>

#define N_SLAVES 6
#define N_CELLS_SERIES 17
#define N_CELLS_PARALLEL 5
#define N_TEMP_SENSORS 32

#define SLAVE_TIMEOUT 500
#define SLAVE_PANIC_OT 0
#define SLAVE_PANIC_UT 1
#define SLAVE_PANIC_OV 2
#define SLAVE_PANIC_UV 3
#define SLAVE_PANIC_TOO_FEW_TEMPS 4
#define SLAVE_PANIC_OPENWIRE 5
#define SLAVE_PANIC_EEPROM_ERROR 6
#define SLAVE_PANIC_INTERNAL_BMS_TIMEOUT 7
#define SLAVE_PANIC_INTERNAL_BMS_CHECKSUM 8
#define SLAVE_PANIC_INTERNAL_BMS_OVERTEMP 9
#define SLAVE_PANIC_INTERNAL_BMS_FAULT 10

typedef enum {
  SLAVE_ERR_NONE,
  SLAVE_ERR_TIMEOUT,
  SLAVE_ERR_OT,
  SLAVE_ERR_UT,
  SLAVE_ERR_OV,
  SLAVE_ERR_UV,
  SLAVE_ERR_TOO_FEW_TEMPS,
  SLAVE_ERR_OPENWIRE,
  SLAVE_ERR_EEPROM,
  SLAVE_ERR_INTERNAL_BMS_TIMEOUT,
  SLAVE_ERR_INTERNAL_BMS_CHECKSUM,
  SLAVE_ERR_INTERNAL_BMS_OVERTEMP,
  SLAVE_ERR_INTERNAL_BMS_FAULT,
  SLAVE_ERR_UNKNOWN,
} SlaveErrorKind;

typedef struct {
  SlaveErrorKind kind;
  uint32_t data; // Cell/temperature ID etc
} SlaveError;

typedef struct {
  uint8_t id;
  SlaveError error;
  uint8_t soc;
  uint16_t min_voltage;
  uint16_t max_voltage;
  int16_t max_temp;
  uint32_t last_message;
} SlaveHandle;

extern SlaveHandle slaves[N_SLAVES];
extern uint16_t min_voltage;
extern int16_t max_temp;

void slaves_init();
void slaves_check();

void slaves_handle_panic(const uint8_t *data);
void slaves_handle_status(const uint8_t *data);
void slaves_handle_log(const uint8_t *data);

#endif // INC_SLAVE_MONITORING_H