/*#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif*/
//clase sensor mqtt------------------------------------
#define DEBUG_PS 1//si 1 se envia log a puerto serie si no 0
#define MAX_SENS_MQTT	32
#define MAX_INTERRUP_SENS_MQTT  12 //ojo si se cambia hay que hacer mas funciones de interrupcion
#define MAX_RF_IN_SENS_MQTT  16
#define VERSION_SENS_MQTT	102
#include <EEPROM.h>
#include <PubSubClient.h>
#include <SimpleDHT.h>
#include <RCSwitch.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>

class PubSubClient;
class LiquidCrystal;
void conecta_serie(int veloc);
template <class Carg1>
void envia_serie(Carg1 s)
{
  if(DEBUG_PS)
    Serial.print(s);
};

template <class Carg2>
void envia_serieln(Carg2 s)
{
  if(DEBUG_PS)
    Serial.println(s);
};

bool pasa_incre( unsigned long *tt, unsigned long incre);
bool pasa_incre( volatile unsigned long *tt, unsigned long incre);

 ICACHE_RAM_ATTR void interrupcion1();
 ICACHE_RAM_ATTR void interrupcion2();
 ICACHE_RAM_ATTR void interrupcion3();
 ICACHE_RAM_ATTR void interrupcion4();
 ICACHE_RAM_ATTR void interrupcion5();
 ICACHE_RAM_ATTR void interrupcion6();
 ICACHE_RAM_ATTR void interrupcion7();
 ICACHE_RAM_ATTR void interrupcion8();
 ICACHE_RAM_ATTR void interrupcion9();
 ICACHE_RAM_ATTR void interrupcion10();
 ICACHE_RAM_ATTR void interrupcion11();
 ICACHE_RAM_ATTR void interrupcion12();
 
//**************************************************************************************************************************************************

class Ceprom_manager
{
  public:
	int nb;
 
	Ceprom_manager();
 
	void leeb(byte *p);//lee un byte y deja en p
	void grabab(byte p);//graba en eprom un byte
  void graba_st(char *st);
  void fin_grabacion();//hace efectivos los cambios en la eprom
	void cursor(int pos=0);//mueve cursor a posicion indicada
	template <class Cgeneg>
	void get(Cgeneg* dout)//lee entero
	{
		byte *b=(byte)dout;
		for(int i=sizeof(Cgeneg); i>0;i--)
			leeb(&b[i]);
	};
	template <class Cgenes>
  
	void set(Cgenes* dout)//lee entero
	{
		byte *b=(byte*)dout;
		for(int i=sizeof(Cgenes); i>0;i--)
			grabab(b[i]);
	};
};
/*
 * calse sensor individual de domotica, esta clase administra sensores particulares
 * 
 * Sensor dht22 (sensor out)
 *  lectura de temperatura y humedad
 *  tipo: SENS_DHT22
 *  val: no usado 
 *  pin: pin digital donde se conecta el sensor
 *  val_old:no usado
 *  retard:no usado
 *  id:no usado
 *  pun: se almacena el puntero a la clase dht
 * 
 * Sensor bmp180
 *  lectura de temperatura presion y altitud varimetrica
 *  tipo: SENS_BMP180
 *  val: no usado 
 *  pin: pin digital donde se conecta el sensor
 *  val_old:no usado
 *  retard:no usado
 *  id:no usado
 *  pun: se almacena el puntero de la clase bmp
 * 
 * Sensor de entrada analogico
 *  lectura de 0 a 100 de sensor analogico
 *  tipo: SENS_ANALOG_IN
 *  val: si es 0 es directa si es uno es indirecta (la señal de salida es directa o inversamente proporcional a el valor analogico)
 *  pin: pin analogico donde se conecta el sensor
 *  val_old:no usado
 *  retard:no usado
 *  id:no usado
 *  pun: no usado
 *  
 * Sensor de entrada digital
 *  el sensor de entrada digital funciona por interrucciones, el valor se actualiza inmediatamente
 *  tipo: SENS_DIGI_IN
 *  val:valor actual del sensor
 *  pin: pin digital al que esta conectado
 *  val_old: guarda el valor anterior
 *  retard: usado para cambiar automaticamente el valor al anterior
 *  id:no usado
 *  pun: no usado

 * Sensor de entrada y salida digital (dos pines uno de entrada y otro de salida que tiene que tener el mismo valor)
 *  el sensor de entrada digital funciona por interrucciones, el valor se actualiza inmediatamente
 *  tipo: SENS_DIGI_IN_OUT
 *  val:valor actual del sensor
 *  pin: pin digital  de salida (out)
 *  val_old:no usado
 *  retard:no usado
 *  id:pin digital de entrada (pin digital de entrada)
 *  pun: no usado
 */
class Csens_mqtt
{
  public:
  
  //generales--------------------
  byte tipo;//tipo sensor
  byte val;//se usa para guradar valor en algunos sensores y flags en otros//byte
  int pin;//pin de conexion scl para bmp
  char topic[8];//topic de mqtt que se anadira
  //-----------------------------
  //especificas
   byte val_old;//byte
   volatile unsigned long t;
   unsigned long retard;
   long id;     //pin sda para bmp
   void *pun;
   //c y d----------------------
   Csens_mqtt();
   ~Csens_mqtt();
   
   bool envia_mqtt(PubSubClient *client_qqtt, char *top, bool envia);//envia estado del sensor por mqtt
   //bool recive_mqtt(PubSubClient *client_qqtt, char *top);//recive estado de sensor por mqtt
   //bool inicia();//inicia sensor (previamente ya seteado)
   bool set(char *conf);//rellena sensor segun trama de configuracion
   bool get(char *conf);//anade a la trama la configuracion correspondiente a este sensor
  
  enum Tipo_sens//indica el tipo de sensor
  {
      SENS_NO_ASIG=0,//sensor sin asignar
      SENS_DHT22,//sensor temperatura y humedad
      SENS_BMP180,//sensor presion
      SENS_ANALOG_IN,//sensor analogico in
      SENS_DIGI_IN,//sensor digital in
      SENS_DIGI_OUT,//sensor digital out
	  SENS_DIGI_IN_OUT,//sensor doble de entrada y salida (dos pines que tienen que tener el mismo valor)
      SENS_RF_OUT,//sensor transmisor de rf
      SENS_RF_IN,//sensor receptor de rf
      SENS_RF_DATA_IN//dato a recivir por rf
  };
};
//clase manager de sensores mqtt-----------------------

class Csens_domo_mqtt
{
  public:
  SimpleDHT22 cdht;//clase para leer de dht
  Adafruit_BMP085 bmp;//clase bmp
  PubSubClient *client_qqtt;
  bool bmppillado;//indica si el bmp esta asignado o no
  RCSwitch rf; 
  bool bloqueo_sens;//bloquea todos los sensores (para poder editarlos)
  byte rf_in_pillado;//indica si rf in esta asignado
  bool rf_out_pillado;//indica si rf_out esta asignado
  byte ind_interrup[MAX_INTERRUP_SENS_MQTT];//array de interrupciones (indices a sensor)
  int n,//numero de sensores
  n_inter,//numero de interrupciones
  flags;
  unsigned long t_inter, t_rev_interrup;
  byte ind_rf_in[MAX_RF_IN_SENS_MQTT];
  int n_rf_in;
  
  char top[16];//topic_id_sensor
  Csens_mqtt sen[MAX_SENS_MQTT];
  
  Csens_domo_mqtt();//constructor
  //funciones-------------------------------
  bool inicia(int i);//inicia el sensor iesimo
  bool conf();//configura de eprom
  void envia_comunes();//envia por mqtt la info de sensores comunes
  void revisa_interrupciones();//revisa sensores con interrupciones
  void revisa_rf();//revisa entradas de rf
  bool graba_conf();//graba configuracion en eprom
  void para_sens();//desconfigura todos los sensores (a nivel de hardware)
  void del(int i);//borra el sensor iesimo
  void subscribe_mqtt();//pone en suspcripcion de los sensores que sean necesarios
  
  bool on_mqtt(char* topic, char* payload);//recibe traza mqtt
  void on_interrupcion(int i);//ejecuta interrupcion iesima
  void atachea(int i);//habilita interrupcion iesima
 
};
#ifndef PCLASE_SENS_DOMO
#define PCLASE_SENS_DOMO
static void *pclase_sens_domo_mq;
#endif
