Version estable con interrupciones

master
Gerardo 2022-01-18 22:11:46 +01:00
parent fcc10556a5
commit 991f2856bb
14 changed files with 2022 additions and 1 deletions

@ -1 +0,0 @@
Subproject commit 310874dac84bf8a72171da4714ccac40f5b9f9ad

View File

@ -0,0 +1,74 @@
#include "DomoEspManager.h"
DomoEspManager::DomoEspManager()
{
vars.config(NULL, NULL);
vars.AddListenner(&sens);
sens.Config(&vars);
suscrito=false;
}
void DomoEspManager::inicia(PubSubClient *mqttClient, WiFiClient* espClient, DomoConfig* conf)
{
#ifdef DEBUG_PS
Serial.println("Inicia Wifi");
#endif
wifi.inicia(espClient, conf->ssidWifi, conf->keyWifi);
#ifdef DEBUG_PS
Serial.println("Inicia Mqtt");
#endif
mqtt.inicia(mqttClient,conf->ideEsp, conf->hostMQTT, conf->portMQTT, this);
#ifdef DEBUG_PS
Serial.println("Configura Sensores");
#endif
//pasar funcion de configuracion de añadir sensores
conf->ConfigSens(&sens);
#ifdef DEBUG_PS
Serial.println("Inicia variables");
#endif
vars.inicia(mqttClient);
#ifdef DEBUG_PS
Serial.println("Inicia Sensores");
#endif
sens.inicia();
#ifdef DEBUG_PS
Serial.println("Iniciado esp");
#endif
}
void DomoEspManager::loop()
{
if(!wifi.loop())
{
suscrito=false;
return;
}
if(!mqtt.loop())
{
suscrito=false;
return;
}
if(!suscrito)
{
vars.Suscribe();
suscrito=true;
}
sens.loop();
vars.loop();
}
void DomoEspManager::OnMqtt(char* topic, char* payload)
{
vars.OnMqtt(topic, payload);
}
void DomoEspManager::SubscribeMqtt(PubSubClient *client_mqtt)
{
}

View File

@ -0,0 +1,70 @@
#ifndef DomoEspManagerDef
#define DomoEspManagerDef 1
//#include <ESP8266WiFi.h>//este para esp8266
//#include <PubSubClient.h>
#include <SPI.h>
/*
#include <SimpleDHT.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
*/
#include "MqttVarManager.h"
#include "MqttUtiles.h"
#include "MqttSensManager.h"
class PubSubClient;
class WiFiClient;
class MqttSensManager;
/*
* clase principal
*/
class DomoConfig
{
public:
char ssidWifi[24];
char keyWifi[32];
char ideEsp[16];//identificador unico por esp
char hostMQTT[16];
int portMQTT;
int velocidadPortSerie;
int refresTimeVars;//tiempo de refresco en segundos de las variables
int refresTimeSens;//tiempo de refresco en segundos de los sensores
virtual void ConfigSens(MqttSensManager* sens)=0;
};
//TODO falta funcion en configuracion para añadir sensores y variables
class DomoEspManager: public MqttReceiver
{
public:
//variables-------------
//MqttVarArray avar;
//MqttTopicAttay topics;
MqttVarManager vars;
MqttSensManager sens;
WifiManager wifi;
MqttManager mqtt;
bool suscrito;
//PubSubClient client_qqtt(WifiManager::espClient);
DomoEspManager();
//PubSubClient client_qqtt(espClient);
void inicia(PubSubClient *mqttClient, WiFiClient* espClient, DomoConfig* conf);
void loop();
//funciones auxiliares
virtual void OnMqtt(char* topic, char* payload);
virtual void SubscribeMqtt(PubSubClient *client_mqtt);
};
#endif

View File

@ -0,0 +1,64 @@
/*
* Software basico sersor domotica con esp8266 / esp32 nodemcu
* Controlado por mqtt
* ---------------------------------------------------------------
* compatible con:
* sensor temperatura y humedad hdt22
* sensores digitales de entrada (gestionado por interrupciones)
* presion y altura por sensor bmp180
* sensores digitales de salida
* receptor rf
* emisor rf
* --------------------------------------------------------------
*/
/*
* la temperatura se tiene que cambiar a digital interrupcion
*/
/*falta transimsion en rf out
Y PROBAR RF*/
#define VERSION_PROG "V0201"//indica version del programa
//#define CONEXION_ETERNET 0//indica si la conexion es ethernet o wifi (para aruino uno)
//falta guardar estado de relees en eprom--------------------------
//includes-----------------------------------------
#include <ESP8266WiFi.h>//este para esp8266
//#include <WiFi.h>//este para esp32
#include <SimpleDHT.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
//#include <PubSubClient.h>
#include "DomoEspManager.h"
#include "config_rf.h"
//variables globales----------------------------
DomoEspManager domoManager;
DomoEspManager domoEspManager;
WiFiClient EspClient;
PubSubClient clienteMqtt(EspClient);
//funciones principales------------------------
void setup()
{
#ifdef DEBUG_PS
Serial.begin(ConfiguracionActual.velocidadPortSerie);
delay(10);
Serial.println("");
Serial.println("Iniciando");
#endif
domoManager.inicia(&clienteMqtt,&EspClient,&ConfiguracionActual);
}
void loop()
{
domoManager.loop();
}

11
DomoEsp_v01/MqttDefines.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef MqttDefinesDef
#define MqttDefinesDef 1
#define DEBUG_PS 1
class MqttOnVarChangeListenner
{
public:
virtual void OnVarChange(int ivar)=0;
};
#endif

View File

@ -0,0 +1,166 @@
#include "MqttDesencadenadorManager.h"
MqttOper::MqttOper()
{
}
bool MqttOper::Test(MqttVarManager* vars)
{
return false;
}
//*******************************************************************
MqttOperArray::MqttOperArray()
{
n=0;
}
MqttOper* MqttOperArray:: Get(int i)
{
return &(data[i]);
}
int MqttOperArray::Add(MqttOper* var)
{
data[n]=*var;
n++;
return n-1;
}
//*******************************************************************
MqttCausa::MqttCausa()
{
}
bool MqttCausa::Test(MqttVarManager *vars)
{
return true;
}
//*******************************************************************
MqttCausaArray::MqttCausaArray()
{
n=0;
}
MqttCausa* MqttCausaArray:: Get(int i)
{
return &(data[i]);
}
int MqttCausaArray::Add(MqttCausa* var)
{
data[n]=*var;
n++;
return n-1;
}
//*******************************************************************
MqttCausaManager::MqttCausaManager()
{
}
bool MqttCausaManager::IsTrue(int icau, MqttVarManager *vars)
{
return false;
}
//*******************************************************************
MqttEfecto::MqttEfecto()
{
}
void MqttEfecto::Exe(MqttVarManager *vars)
{
switch((int)tipo)
{
case((int)MqttEfecto::InvierteValVar):
{
vars->InvierteVar(ia);
break;
}
case((int)MqttEfecto::SetValVar):
{
vars->SetVal(ia, val);
break;
}
default:
break;
}
}
//*******************************************************************
MqttDesencadenador::MqttDesencadenador()
{
tipo=0;
}
void MqttDesencadenador::Exe(MqttVarManager *vars, MqttEfectoArray *efe, MqttCausaManager* caus)
{
switch(tipo)
{
default:
if(caus->IsTrue(ie,vars))
efe->Get(ie)->Exe(vars);
break;
}
}
//*******************************************************************
MqttDesencadenadorArray::MqttDesencadenadorArray()
{
n=0;
}
MqttDesencadenador* MqttDesencadenadorArray::Get(int i)
{
return &(data[i]);
}
int MqttDesencadenadorArray::Add(MqttDesencadenador* var)
{
data[n]=*var;
n++;
return n-1;
}
//*******************************************************************
MqttDesencadenadorManager::MqttDesencadenadorManager()
{
revisa=true;
}
void MqttDesencadenadorManager::OnVarChange(int ivar)
{
revisa=true;
//marca Accion--
}
void MqttDesencadenadorManager::inicia( MqttVarManager *v)
{
vars=v;
}
void MqttDesencadenadorManager::Suscribe()
{
}
int MqttDesencadenadorManager::OnMqtt(char* topic, char* payload)
{
}
void MqttDesencadenadorManager::loop()
{
if(revisa)
{
revisa=false;
RevisaDesencadenadores();
}
}
void MqttDesencadenadorManager::RevisaDesencadenadores()
{
for(int i=0; i<des.n; i++)
{
des.Get(i)->Exe(vars, &act, &caus);
}
//desmarca Var de volatiles
vars->ResetVolatileVar();
}

View File

@ -0,0 +1,167 @@
#ifndef MqttDesencadenadorManagerDef
#define MqttDesencadenadorManagerDef 1
#include <SPI.h>
#include "MqttVarManager.h"
//clase de relacciones/operaciones************************************************
class MqttOper
{
public:
byte x;//indice a variable 1
byte y;//indice a variable 2
byte oper;
MqttOper();
bool Test(MqttVarManager* vars);
};
//array de operaciones--------------------------------------------------------------
class MqttOperArray
{
public:
MqttOper data[32];
int n;
MqttOperArray();
MqttOper* Get(int i);
int Add(MqttOper* var);
};
class MqttCausa
{
public:
byte ini;//indice a primer oper
byte n;//numero de operadores totales
byte tipo;//tipo de causa (and or ...)
MqttCausa();
bool Test(MqttVarManager *i);
};
class MqttCausaArray
{
public:
MqttCausa data[16];
int n;
MqttCausaArray();
MqttCausa* Get(int i);
int Add(MqttCausa* var);;
};
class MqttCausaManager
{
public:
MqttCausaArray caus;
MqttOperArray oper;
MqttCausaManager();
bool IsTrue(int icau, MqttVarManager *vars);
};
class MqttEfecto
{
public:
enum TipoEfecto
{
InvierteValVar=1,//invierte valor a variable
SetValVar//setea el valor asignado en el efecto a la variable
};
MQTTvalor val;
byte ia;//indice externo (dependiendo del tipo puede ser a una variable o topic o sensor ...)
byte tipo;//tipo de accion (and or ...)
MqttEfecto();
void Exe(MqttVarManager *i);
};
class MqttEfectoArray
{
public:
MqttEfecto data[16];
int n;
MqttEfectoArray();
MqttEfecto* Get(int i);
int Add(MqttEfecto* var);
};
class MqttDesencadenador
{
public:
MQTTvalor val;
byte ie;//indice a efecto
byte ic;//indice a causa
byte tipo;//tipo de accion (and or ...)
MqttDesencadenador();
void Exe(MqttVarManager *i, MqttEfectoArray *act, MqttCausaManager* caus);
};
class MqttDesencadenadorArray
{
public:
MqttDesencadenador data[16];
int n;
MqttDesencadenadorArray();
MqttDesencadenador* Get(int i);
int Add(MqttDesencadenador* var);
};
//falta acciones y efectos
//acciones tienen valor, tipo y ivar(indice a variable)
class MqttDesencadenadorManager: public MqttOnVarChangeListenner
{
public:
MqttVarManager *vars;
MqttEfectoArray act;
MqttCausaManager caus;
MqttDesencadenadorArray des;
bool revisa;
MqttDesencadenadorManager();
void inicia( MqttVarManager *vars);//inicia variables si hace falta
void Suscribe();//subscribe variables a mqtt
int OnMqtt(char* topic, char* payload);//entra trama mqtt devuelve indice a sensor cambiado
void loop();//publica datos variables
virtual void OnVarChange(int ivar);
void RevisaDesencadenadores();
};
/*
*
*/
#endif

View File

@ -0,0 +1,485 @@
//#include <ESP8266WiFi.h>//este para esp8266
#include "MqttSensManager.h"
#include "MqttVarManager.h"
#include "MqttUtiles.h"
MqttSensor::MqttSensor()
{
}
void MqttSensor::Set(MqttSensor *s)
{
tipo=s->tipo;
flags=s->flags;
pin=s->pin;
ivar=s->ivar;
ie=s->ie;
}
//*******************************************************************
MqttSensArray::MqttSensArray()
{
n=0;
}
MqttSensor* MqttSensArray:: Get(int i)
{
return &(sens[i]);
}
MqttSensor* MqttSensArray::Ivar2Sen(int ivar)
{
MqttSensor* res;
for(int i=0; i<n; i++)
{
res=Get(i);
if(res->ivar==ivar)
return res;
}
return NULL;
}
int MqttSensArray::Add(MqttSensor* var)
{
sens[n].Set(var);
n++;
return n-1;
}
//*******************************************************************
MqttSensManager::MqttSensManager()
{
n_inter=0;
bloqueo_sens=false;
tiempo_sens=0;
SetTimeRefres(15);//por defecto 15 segundos
n_inter=0;
pMqttSensManager=this;
cambioInterrup=0;
}
void MqttSensManager::SetTimeRefres(int seg)
{
incre_tsens=seg*1000;
}
void MqttSensManager::Config(MqttVarManager* var)
{
vars=var;
}
MqttSensor* MqttSensManager::Get(int i)
{
}
void MqttSensManager::inicia()
{
}
void MqttSensManager::inicia(int i)
{
}
void MqttSensManager::loop()
{
if(bloqueo_sens)
return;
procesaInterrupciones();
if(MqttUtiles::pasa_incre(&tiempo_sens, incre_tsens))
{
#ifdef DEBUG_PS
Serial.println("Procesa Sens");
#endif
procesaSens();
}
}
void MqttSensManager::AddAnalogIn(int pin, char* topic, bool valNegado)
{
MqttSensor s;
s.tipo=(int)MqttSensor::SENS_ANALOG_IN;
s.pin=pin;
if(valNegado)
s.flags=MqttSensor::FLAG_NEG;
s.ivar=vars->AddVar((byte)(MqttVar::IN_VAR | MqttVar::FLOAT_VAR),topic);
int isen=sens.Add(&s);
//pinMode(s.pin, INPUT);
}
void MqttSensManager::AddDout(int pin, char* topic, bool defautlValor)
{
MqttSensor s;
s.tipo=(int)MqttSensor::SENS_DIGI_OUT;
s.pin=pin;
s.ivar=vars->AddVar((byte)(MqttVar::IN_VAR|MqttVar::OUT_VAR|MqttVar::ACCION_VAR),topic);
sens.Add(&s);
pinMode(s.pin, OUTPUT);
digitalWrite(s.pin, defautlValor);
}
void MqttSensManager::AddDin(int pin, char* topic)
{
MqttSensor s;
s.tipo=(int)MqttSensor::SENS_DIGI_IN;
s.pin=pin;
s.ivar=vars->AddVar((byte)(MqttVar::IN_VAR|MqttVar::ACCION_VAR),topic);
int isen=sens.Add(&s);
pinMode(s.pin, INPUT);
ConfiguraInterrupcion(isen);
}
void MqttSensManager::AddDinAccion(int pin, char* topic)
{
MqttSensor s;
s.tipo=(int)MqttSensor::SENS_DIGI_IN_PULSANTE;
s.pin=pin;
s.ivar=vars->AddVar((byte)MqttVar::ACCION_VAR,topic);
int isen=sens.Add(&s);
pinMode(s.pin, INPUT);
ConfiguraInterrupcion(isen);
}
void MqttSensManager::AddHDT22(int pin, char* topic)
{
char buffer_t[32];
MqttSensor s;
s.tipo=(int)MqttSensor::SENS_DHT22;
s.pin=pin;
s.ie.dht.p=&cdht;
sprintf(buffer_t, "%s/t", topic);
s.ivar=vars->AddVar((byte)MqttVar::IN_VAR| MqttVar::FLOAT_VAR,buffer_t);//variable temperatura
sprintf(buffer_t, "%s/h", topic);
s.ie.dht.ivarH=vars->AddVar((byte)MqttVar::IN_VAR| MqttVar::FLOAT_VAR,buffer_t);//variable humedad
sens.Add(&s);
}
void MqttSensManager::AddBMP180(int sda,int scl, char* topic)
{
/*
if(bmppillado)
return;
bmppillado=true;
*/
char buffer_t[32];
MqttSensor s;
s.tipo=(int)MqttSensor::SENS_BMP180;
s.pin=sda;
s.ie.bmp.p=&bmp;
s.ie.bmp.pinScl=scl;
sprintf(buffer_t, "%s/t", topic);
s.ivar=vars->AddVar((byte)MqttVar::IN_VAR | MqttVar::FLOAT_VAR,buffer_t);//variable temperatura
sprintf(buffer_t, "%s/p", topic);
s.ie.bmp.ivarP=vars->AddVar((byte)MqttVar::IN_VAR,buffer_t);//variable presion
sprintf(buffer_t, "%s/a", topic);
s.ie.bmp.ivarA=vars->AddVar((byte)MqttVar::IN_VAR| MqttVar::FLOAT_VAR,buffer_t);//variable altura
sens.Add(&s);
//inicia------------------
Wire.begin( s.pin,s.ie.bmp.pinScl);
int i=0;
while(!bmp.begin(), i<300)
{
i++;
delay(10);
}
}
void MqttSensManager::procesaSens()
{
for(int i=0; i<sens.n; i++)
procesaSensor(i);
}
void MqttSensManager::procesaSensor(int i)
{
MqttSensor *s=sens.Get(i);
MqttVar *v=vars->Get(s->ivar);
switch((int)s->tipo)
{
case((int)MqttSensor::SENS_DHT22)://pilla temperatura y humedad
{
MqttVar *vh=vars->Get(s->ie.dht.ivarH);
float t,h;
for(int i=0; i<4; i++)
{
if (s->ie.dht.p->read2(s->pin, &t, &h, NULL) != SimpleDHTErrSuccess)
{
delay(20);
continue;
}
/*#ifdef DEBUG_PS
char buffer_p[32];
Serial.print("LeeDht, t:");
dtostrf(t,3, 2, buffer_p);
Serial.print(buffer_p);
Serial.print(" h:");
dtostrf(h,3, 2, buffer_p);
Serial.print(buffer_p);
Serial.println("");
#endif*/
v->val.f=t;
vh->val.f=h;
break;
}
break;
}
case((int)MqttSensor::SENS_BMP180)://pilla temperatura y humedad
{
MqttVar *vp=vars->Get(s->ie.bmp.ivarP);
MqttVar *va=vars->Get(s->ie.bmp.ivarA);
v->val.f=s->ie.bmp.p->readTemperature();
vp->val.i=s->ie.bmp.p->readPressure();//pascales;
va->val.f=s->ie.bmp.p->readAltitude();
break;
}
case((int)MqttSensor::SENS_ANALOG_IN)://pilla temperatura y humedad
{
if(s->flags | MqttSensor::FLAG_NEG)
v->val.f=100.*((float)(1024- analogRead(s->pin)))/1024;
else
v->val.f=100.*((float)(analogRead(s->pin)))/1024;
/*#ifdef DEBUG_PS
char buffer_p[32];
Serial.print("Lee analog:");
dtostrf( v->val.f,3, 2, buffer_p);
Serial.print(buffer_p);
Serial.println("");
#endif*/
break;
}
case((int)MqttSensor::SENS_DIGI_IN)://pilla temperatura y humedad
{
if(s->flags | MqttSensor::FLAG_NEG)
v->val.i=(byte)(1- digitalRead(s->pin));
else
v->val.i=(byte)digitalRead(s->pin);
break;
}
default:
{
break;
}
}
}
void MqttSensManager::OnVarChange(int ivar)
{
#ifdef DEBUG_PS
Serial.println("Sens::OnVarChange");
#endif
MqttSensor *s = sens.Ivar2Sen(ivar);
MqttVar *v=vars->Get(ivar);
if(!s)
{
#ifdef DEBUG_PS
Serial.println("Sens::OnVarChange Sensor no encontrado");
#endif
return;
}
switch(s->tipo)
{
case((int)MqttSensor::SENS_DIGI_OUT):
{
#ifdef DEBUG_PS
Serial.println("Sens::OnVarChangeSensor Dout cambiado");
#endif
if(s->flags & MqttSensor::FLAG_NEG)
digitalWrite( s->pin, (1-v->val.i));
else
digitalWrite( s->pin, v->val.i);
break;
}
default:
break;
}
}
void MqttSensManager::procesaInterrupciones()
{
if(!MqttChangeInterrup)
{
return;
}
noInterrupts();
MqttChangeInterrup=false;
interrupts();
for(int i=0; i<n_inter; i++)
{
MqttSensor* s=sens.Get(ind_interrup[i]);
//if(chg_interrup[i])
{
#ifdef DEBUG_PS
Serial.println("Detectado cambio en interrupcion");
#endif
//lee variable
MqttVar *v=vars->Get(s->ivar);
byte val=digitalRead(s->pin);
switch((int)s->tipo)
{
case((int)MqttSensor::SENS_DIGI_IN):
{
//lee y llama a cambio si es necesario
if(val!=v->val.i)
{
v->val.i=val;
vars->OnChange(s->ivar);
}
break;
}
case((int)MqttSensor::SENS_DIGI_IN_PULSANTE):
{
//lee y llama a cambio si es necesario
if(val!=v->val.i)
{
v->val.i=val;
vars->OnChange(s->ivar);
}
//v->val.i=val;
//vars->OnChange(s->ivar);
break;
}
default:
break;
}
}
}
}
//funciones auxiliares de interrupcion-------------------------------
void MqttSensManager::OnInterrupcion(int i)
{
MqttSensor* s=sens.Get(ind_interrup[i]);
#ifdef DEBUG_PS
Serial.print("OnInterrupcion: ");
Serial.print(i);
Serial.print(" Sensor en cambio:");
Serial.println(chg_interrup[i]);
#endif
chg_interrup[i]=true;
MqttChangeInterrup=true;
}
void MqttSensManager::ConfiguraInterrupcion(int isen)
{
#ifdef DEBUG_PS
Serial.println("Configurando interrupcion");
#endif
ind_interrup[n_inter++]=isen;
int pin=sens.Get(isen)->pin;
switch(n_inter-1)
{
case(0):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion0, CHANGE);
break;
case(1):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion1, CHANGE);
break;
case(2):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion2, CHANGE);
break;
case(3):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion3, CHANGE);
break;
case(4):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion4, CHANGE);
break;
case(5):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion5, CHANGE);
break;
case(6):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion6, CHANGE);
break;
case(7):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion7, CHANGE);
break;
case(8):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion8, CHANGE);
break;
case(9):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion9, CHANGE);
break;
case(10):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion10, CHANGE);
break;
case(11):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion11, CHANGE);
break;
case(12):
attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion12, CHANGE);
break;
}
}
//chapuza que no se como hacerlo de otra manera
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion0()
{
pMqttSensManager->OnInterrupcion(0);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion1()
{
pMqttSensManager->OnInterrupcion(1);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion2()
{
pMqttSensManager->OnInterrupcion(2);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion3()
{
pMqttSensManager->OnInterrupcion(3);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion4()
{
pMqttSensManager->OnInterrupcion(4);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion5()
{
pMqttSensManager->OnInterrupcion(5);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion6()
{
pMqttSensManager->OnInterrupcion(6);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion7()
{
pMqttSensManager->OnInterrupcion(7);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion8()
{
pMqttSensManager->OnInterrupcion(8);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion9()
{
pMqttSensManager->OnInterrupcion(9);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion10()
{
pMqttSensManager->OnInterrupcion(10);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion11()
{
pMqttSensManager->OnInterrupcion(11);
}
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion12()
{
pMqttSensManager->OnInterrupcion(12);
}

View File

@ -0,0 +1,194 @@
#ifndef MqttSensManagerDef
#define MqttSensManagerDef 1
/*
* cambiar en lugar de a topic a variable----------
SENS_DIGI_IN y SENS_ANALOG_IN
publican un topic (set) con el valor correspondiente
SENS_DIGI_OUT
escuchara los set de un topic y publicara el get
SENS_DHT22,//sensor temperatura y humedad
sensor dobles de tipo SENS_ANALOG_IN
publicaran set del topic asociado pñadiendo /t/set /h/set
para temperatura y humedad
SENS_BMP180,//sensor presion
sensor triple SENS_ANALOG_IN
ublicaran set del topic asociado pñadiendo /t/set /p/set /a/set
para temperatura, presion, altitud
*/
#include "MqttDefines.h"
#include <PubSubClient.h>
//class PubSubClient;
class MqttVarManager;
#include <SimpleDHT.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
struct DhtExt
{
byte ivarH;//puntero a variable humedad
SimpleDHT22 *p;
};
struct BmpExt
{
byte ivarP;
byte ivarA;
int pinScl;
Adafruit_BMP085 *p;
};
union MqttInfEx//informacion extra segun sensor
{
DhtExt dht;
BmpExt bmp;
//DinEx din;
};
class MqttSensor
{
public:
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 (algo con 2 estados)
SENS_DIGI_OUT,//sensor digital out
SENS_DIGI_IN_PULSANTE//pensado para pulsadores (Publicara un put)
//SENS_DIGI_IN_OUT//sensor doble de entrada y salida (dos pines que tienen que tener el mismo valor)
};
enum Tipo_flags//indica el tipo de sensor
{
FLAG_NEG=0x01,//indica que el resultado del sensor hay que negarlo (valor invertido)
FLAG_INMED=0x02//indica que es un sensor de actualizacion inmediata (interruptores ...) (TODO)
};
byte tipo;//tipo sensor
byte flags;//flags sensor
int pin;//pin de conexion scl para bmp
byte ivar;//indice a variable
MqttInfEx ie;//informacion extra
MqttSensor();
void Set(MqttSensor *s);
};
//array de sensores--------------------------------------------------------------
class MqttSensArray
{
public:
MqttSensor sens[12];//array de variables
int n;
MqttSensArray();
MqttSensor* Get(int i);
MqttSensor* Ivar2Sen(int ivar);
int Add(MqttSensor* var);
};
//array de sensores--------------------------------------------------------------
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion0();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion1();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion2();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion3();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion4();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion5();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion6();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion7();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion8();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion9();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion10();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion11();
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion12();
class MqttSensManager: public MqttOnVarChangeListenner
{
public:
MqttSensArray sens;//array de variables
MqttVarManager* vars;
PubSubClient *client_qqtt;
SimpleDHT22 cdht;//clase para leer de dht
Adafruit_BMP085 bmp;//clase bmp
bool bloqueo_sens;//bloquea todos los sensores (para poder editarlos)
int ind_interrup[13];
int n_inter;//numero de interrupciones
unsigned long tiempo_sens;
unsigned long incre_tsens;
MqttSensManager();
void Config(MqttVarManager* varTopics);
void SetTimeRefres(int seg);
void inicia();
void loop();
int OnMqtt(char* topic, char* payload);//entra trama mqtt devuelve indice a sensor cambiado
void AddSensor(MqttSensor* sens);
//
//funcion add sensor
//tempe y humedad
void AddHDT22(int pin, char* topic);
//tempe y presion varometrica
void AddBMP180(int sda,int scl, char* topic);
//entradas digitales
void AddDin(int pin, char* topic);//añade variable digital que se actualiza de manera instantanea (interruptores sensor presencia ..)
void AddDinAccion(int pin, char* topic);//añade variable que solo publica en el cambio (pulsadores, ...)
//salida digital
void AddDout(int pin, char* topic, bool defautlValor);//variable que solo publica en el cambio (pulsadores, ...)
void AddAnalogIn(int pin, char* topic, bool ValNegado);//nivel de luz, nivel de lluvia ...
//funciones auxiliares------------
MqttSensor* Get(int i);
void inicia(int i);
void procesaSens();
void procesaInterrupciones();
void procesaSensor(int i);
//auxiliares de interrupciones-----------
void ConfiguraInterrupcion(int isen);
void OnInterrupcion(int i);
virtual void OnVarChange(int ivar);
};
#ifndef pMqttSensManagerdef
#define pMqttSensManagerdef 1
static volatile bool MqttChangeInterrup=false;
static MqttSensManager* pMqttSensManager;
#endif
/*
*/
#endif

171
DomoEsp_v01/MqttUtiles.cpp Normal file
View File

@ -0,0 +1,171 @@
#include <SPI.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <EEPROM.h>
#include "MqttUtiles.h"
//**************************************************************************************************************************************************
bool MqttUtiles::pasa_incre( unsigned long *tt, unsigned long incre)
{
unsigned long t=millis();
if(t<*tt)
{
*tt=t;
return true;
}
if((*tt+incre)>=t)
return false;
*tt=t;
return true;
}
bool MqttUtiles::pasa_incre( volatile unsigned long *tt, unsigned long incre)
{
unsigned long t=millis();
if(t<*tt)
{
*tt=t;
return true;
}
if((*tt+incre)>=t)
return false;
*tt=t;
return true;
}
//**************************************************************************************************************************************************
WifiManager::WifiManager()
{
}
void WifiManager::inicia( WiFiClient *espclient,char *ssid, char* key)
{
espClient= espclient;
strcpy(nred, ssid);
strcpy(pass, key);
}
bool WifiManager::loop()
{
if((WiFi.status() == WL_CONNECTED))
{
return true;
}
#ifdef DEBUG_PS
Serial.println("Conectando wifi");
Serial.println(nred);
Serial.println(pass);
#endif
WiFi.mode(WIFI_STA);
WiFi.begin(nred, pass);
for(int i=0; i<100 && WiFi.status() != WL_CONNECTED; i++)
{
delay(500);
#ifdef DEBUG_PS
Serial.print(".");
#endif
}
#ifdef DEBUG_PS
Serial.println("");
if(WiFi.status() == WL_CONNECTED)
Serial.println("Wifi Conectado");
else
Serial.println("No se pudo conectar");
#endif
return WiFi.status() == WL_CONNECTED;
}
//**************************************************************************************************************************************************
MqttManager::MqttManager()
{
}
void MqttManager::inicia(PubSubClient *mqttClient,char *ideEsp, char *host, int port, MqttReceiver* classReceiver)
{
strcpy(idEsp,ideEsp);
Mqttlistener=classReceiver;
client_mqtt=mqttClient;
client_mqtt->setServer(host, port);
client_mqtt->setCallback(MqttManager::OnMqtt);
}
bool MqttManager::loop()
{
if(client_mqtt->loop())
return true;
#ifdef DEBUG_PS
if(WiFi.status() == WL_CONNECTED)
Serial.println("Conectando a broker");
#endif
if(client_mqtt->connect(idEsp))
{
#ifdef DEBUG_PS
if(WiFi.status() == WL_CONNECTED)
Serial.println("Conectado a broker");
#endif
subscribe_mqtt();
return true;
}
}
void MqttManager::subscribe_mqtt()
{
if(Mqttlistener==NULL)
return;
Mqttlistener->SubscribeMqtt(client_mqtt);
}
//auxiliar------------------
void MqttManager::OnMqtt(char* topic, byte* payload, unsigned int length)
{
if(Mqttlistener==NULL)
return;
int i;
char buf[32];
i=31;
if(i>length)
i=length;
memcpy(buf, payload, i);
buf[i]=0;
Mqttlistener->OnMqtt(topic, buf);
}
//**************************************************************************************************************************************************
void Ceprom_manager::fin_grabacion()
{
EEPROM.commit();
}
Ceprom_manager::Ceprom_manager()
{
nb=0;
}
void Ceprom_manager::leeb(byte *p)
{
*p=EEPROM.read(nb++);
}
void Ceprom_manager::grabab(byte p)
{
EEPROM.write(nb++, p);
}
void Ceprom_manager::graba_st(char *st)
{
for(int i=strlen(st); i>0; i--)
{
Ceprom_manager::grabab(*st);
st++;
}
}
void Ceprom_manager::cursor(int pos)
{
nb=pos;
}

128
DomoEsp_v01/MqttUtiles.h Normal file
View File

@ -0,0 +1,128 @@
#ifndef MqttUtilesrDef
#define MqttUtilesDef 1
//#include <WiFi.h>//este para esp32
#include <ESP8266WiFi.h>//este para esp8266*/
class PubSubClient;
class WiFiClient;
#ifndef DO
#define D0 16
#endif
#ifndef D1
#define D1 5
#endif
#ifndef D2
#define D2 4
#endif
#ifndef D3
#define D3 0
#endif
#ifndef D4
#define D4 2
#endif
#ifndef D5
#define D5 14
#endif
#ifndef D6
#define D6 12
#endif
#ifndef D7
#define D7 13
#endif
#ifndef D8
#define D8 15
#endif
#include "MQTTDefines.h"
//interfaces listener---------------------------------------
class MqttUtiles
{
public:
static bool pasa_incre( unsigned long *tt, unsigned long incre);
static bool pasa_incre( volatile unsigned long *tt, unsigned long incre);
};
class WifiManager
{
public:
char nred[32];
char pass[32];
WiFiClient *espClient;
WifiManager();
void inicia( WiFiClient *espClient, char *ssid, char* key);
bool loop();
};
class MqttReceiver
{
public:
virtual void OnMqtt(char* topic, char* payload)=0;
virtual void SubscribeMqtt(PubSubClient *client_mqtt){}
};
class MqttManager
{
public:
private:
char idEsp[16];
public:
PubSubClient *client_mqtt;
MqttManager();
/*
WiFiClient espClient;//conexion a wifi
PubSubClient client_qqtt(espClient);//para conexion con mqtt
*/
void inicia(PubSubClient *mqttClient,char *ideEsp, char *host, int port, MqttReceiver* classReceiver);
bool loop();
void desconecta();
//auxiliar------------------
static void OnMqtt(char* topic, byte* payload, unsigned int length);
void subscribe_mqtt();
};
static MqttReceiver* Mqttlistener;
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]);
};
};
#endif

View File

@ -0,0 +1,324 @@
//#include <ESP8266WiFi.h>//este para esp8266
#include <SPI.h>
#include "MqttDefines.h"
#include "MqttVarManager.h"
#include "MqttUtiles.h"
#include <cstring>
#include <PubSubClient.h>
MqttTopicAttay::MqttTopicAttay()
{
n=0;
nst=0;
}
char* MqttTopicAttay::Get(int i)
{
return &str[(ind[i])];
}
int MqttTopicAttay::Get(char *topic)
{
for(int i=0; i<n; i++)
{
if(!strcmp(topic,Get(i)))
return i;
}
return (int)-1;
}
int MqttTopicAttay::Add(char *topic)
{
int i=Get(topic);
if(i>(int)0)
{
return i;
}
i=n;
n=n+1;
ind[i]=nst;
nst=nst+strlen(topic)+1;
strcpy(Get(i), topic);
return i;
}
//*******************************************************************
MqttVar::MqttVar()
{
flags=0;
val.f=0;
topic=0;
}
//*******************************************************************
MqttVarArray::MqttVarArray()
{
n=0;
}
MqttVar* MqttVarArray:: Get(int i)
{
return &(data[i]);
}
MqttVar* MqttVarArray::GetVar(int itopic)
{
for(int i=0; i<n; i++)
{
if(data[i].topic==itopic)
return &(data[i]);
}
return NULL;
}
int MqttVarArray::Add(MqttVar* var)
{
data[n]=*var;
n++;
return n-1;
}
//*******************************************************************
MqttVarManager::MqttVarManager()
{
tiempo_var=0;
SetTimeRefres(30);
nListenner=0;
}
void MqttVarManager::SetTimeRefres(int seg)
{
incre_tvar=seg*1000;
}
void MqttVarManager::config(MqttVarArray *vArray, MqttTopicAttay* t)
{
if(vArray)
vars=vArray;
else
vars=&_v;
if(t)
topics=t;
else
topics=&_t;
}
int MqttVarManager::OnMqtt(char* topic, char* payload)
{
char buf[32];
#ifdef DEBUG_PS
Serial.print("OnmqttVars: ");
Serial.println(topic);
Serial.print("val: ");
Serial.println(payload);
#endif
int res=-1;
sprintf(buf, "%s",topic);
int nt=strlen(buf);
int ng=strlen("/get");
bool isGet=!strcmp("/get", &buf[nt-ng]);
buf[nt-ng]=0;
#ifdef DEBUG_PS
Serial.print("OnmqttVars:Topiccompara:");
Serial.println(buf);
#endif
byte f=MqttVar::OUT_VAR;
if(isGet)
{
f=MqttVar::PRIV_VAR;
#ifdef DEBUG_PS
Serial.println("OnmqttVars: get detectado");
#endif
}
else
{
if(strcmp("set", &buf[nt-ng+1]))
{
#ifdef DEBUG_PS
Serial.println("OnmqttVars: Ni get ni set");
#endif
return res;//no es ni get ni set
}
#ifdef DEBUG_PS
Serial.println("OnmqttVars: set detectado");
#endif
}
//comprueba variables
MqttVar* v;
for(int i=0; i<vars->n; i++)
{
v=vars->Get(i);
if((v->flags & f) && !strcmp(topics->Get(v->topic),buf))
{
#ifdef DEBUG_PS
Serial.println("OnmqttVars: Encontrada var");
#endif
if(v->flags & MqttVar::FLOAT_VAR)
{
float ff=v->val.f;
v->val.f=atof(payload);
if(ff!=v->val.f)
res=i;
}
else
{
int ii=v->val.i;
v->val.i=atoi(payload);
if(ii!=v->val.i)
res=i;
}
OnChange(i);
break;//suponemos solo una variable con el mismo topic
}
}
return res;
}
void MqttVarManager::loop()
{
if(MqttUtiles::pasa_incre(&tiempo_var, incre_tvar))
{
#ifdef DEBUG_PS
Serial.println("Procesa vars");
#endif
PublicaVars();
}
}
void MqttVarManager::PublicaVar(int ivar)
{
char buffer_t[32];
char buffer_p[24];
MqttVar* v=vars->Get(ivar);
sprintf(buffer_t, "%s/get",topics->Get(v->topic));
//Publica valor
if(v->flags & MqttVar::FLOAT_VAR)
dtostrf(v->val.f,3, 2, buffer_p);
else
sprintf(buffer_p, "%d", (int)v->val.i);
client_qqtt->publish(buffer_t, buffer_p);
}
void MqttVarManager::PublicaVars()
{
byte f=MqttVar::IN_VAR;
MqttVar* v;
for(int i=0; i<vars->n; i++)
{
v=vars->Get(i);
if(v->flags & f)
{
PublicaVar(i);
}
}
}
void MqttVarManager::inicia(PubSubClient* client_mqtt)
{
client_qqtt=client_mqtt;
}
void MqttVarManager::Suscribe()
{
//suscribe a mqtt------------
char buffer_t[32];
MqttVar* v;
for(int i=0; i<vars->n; i++)
{
v=vars->Get(i);
if(v->flags & MqttVar::OUT_VAR)//suscribe al set
{
sprintf(buffer_t, "%s/set",topics->Get(v->topic));
client_qqtt->subscribe(buffer_t);
#ifdef DEBUG_PS
Serial.print("Suscribe: ");
Serial.println(buffer_t);
#endif
}
}
#ifdef DEBUG_PS
Serial.println("Variables:");
for(int i=0; i<vars->n; i++)
{
v=vars->Get(i);
sprintf(buffer_t, "%s",topics->Get(v->topic));
Serial.println(buffer_t);
}
Serial.println("Fin Variables Suscritas");
#endif
}
int MqttVarManager::AddVar(byte flags, char*topic)
{
MqttVar v;
v.flags=flags;
v.topic=topics->Add(topic);
return vars->Add(&v);
}
MqttVar* MqttVarManager::Get(int i)
{
return vars->Get(i);
}
void MqttVarManager::OnChange(int ivar)
{
MqttVar* v=vars->Get(ivar);
byte f= MqttVar::ACCION_VAR;
if(v->flags & f)
{
PublicaVar(ivar);
}
for (int i=0; i<nListenner; i++)
{
onChangeListener[i]->OnVarChange(i);
}
}
void MqttVarManager::AddListenner(MqttOnVarChangeListenner *pOnChangeListener)
{
onChangeListener[nListenner++]=pOnChangeListener;
}
void MqttVarManager::ResetVolatileVar()
{
for(int i=0; i<vars->n; i++)
{
MqttVar* v=vars->Get(i);
if(v->flags& MqttVar::VOLATILE_VAR)
{
if(v->flags & MqttVar::FLOAT_VAR)
v->val.f=0;
else
v->val.i=0;
}
}
}
void MqttVarManager::InvierteVar(int ivar)
{
MqttVar* v=vars->Get(ivar);
if(v->flags & MqttVar::FLOAT_VAR)
{
v->val.f=100.0-v->val.f;
}
else
v->val.i=1-v->val.i;
OnChange(ivar);
}
void MqttVarManager::SetVal(int ivar,MQTTvalor val)
{
MqttVar* v=vars->Get(ivar);
v->val=val;
OnChange(ivar);
}

View File

@ -0,0 +1,122 @@
/*#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif*/
#ifndef MqttvarManagerDef
#define MqttvarManagerDef 1
#include "MqttDefines.h"
#define MAXTOPICVAR 24//maximo de caracteres de los topic de las variables
#define MAXTVARARRAY 64//maximo de variables que puede contener el amqttvarArray
class PubSubClient;
//array de topic
class MqttTopicAttay
{
public:
char str[1024];//topic de mqtt asociado
int ind[32];
int nst;
int n;
MqttTopicAttay();
char* Get(int i);
int Get(char *topic);
int Add(char *topic);
};
union MQTTvalor
{
float f;
byte i;
};
class MqttVar
{
public:
enum TipoFlags//indica el tipo de sensor
{
OUT_VAR=0x01,//variable de salida (acepta set)
IN_VAR=0x02,//variable de entrada (publica get)
PRIV_VAR=0x04,//variable privada de entrada (acepta get como si fueran set)
FLOAT_VAR=0x08,
ACCION_VAR=0x10,//variable de accion (publica en cada cambio)
VOLATILE_VAR=0X20 //marca variable que una vez revisada se cambia internamente su valor (usado en desencadenadores para variables de accion)
};
public:
//generales---------------------------------------------------------------------
byte flags;
MQTTvalor val;//valor de la variable (tiene que ser union porque puede ser double)
byte topic;//topic de mqtt asociado
MqttVar();
};
//array de variables--------------------------------------------------------------
class MqttVarArray
{
public:
MqttVar data[64];//array de variables
int n;
MqttVarArray();
MqttVar* Get(int i);
MqttVar* GetVar(int itopic);
int Add(MqttVar* var);
};
class MqttOnVarChangeListenner;
//manager de variables------------------------------------------------------
class MqttVarManager
{
MqttVarArray _v;
MqttTopicAttay _t;
MqttOnVarChangeListenner* onChangeListener[2];
int nListenner;
public:
MqttVarArray* vars;//variables mqtt
MqttTopicAttay* topics;
PubSubClient* client_qqtt;//cliente mqtt
unsigned long tiempo_var;
unsigned long incre_tvar;
MqttVarManager();
void config(MqttVarArray *vArray=NULL, MqttTopicAttay* t=NULL);
void SetTimeRefres(int seg);
void inicia(PubSubClient *client_qqtt);//inicia variables si hace falta
void Suscribe();//subscribe variables a mqtt
int OnMqtt(char* topic, char* payload);//entra trama mqtt devuelve indice a sensor cambiado
void loop();//publica datos variables
//funciones auxiliares----------------------------
void AddListenner(MqttOnVarChangeListenner *pOnChangeListener);
MqttVar* Get(int i);
int AddVar(byte flags, char*topic);
void PublicaVars();
void PublicaVar(int ivar);
void OnChange(int ivar);
void ResetVolatileVar();
void InvierteVar(int ivar);
void SetVal(int ivar,MQTTvalor val);
};
/*
*/
#endif

46
DomoEsp_v01/config_rf.h Normal file
View File

@ -0,0 +1,46 @@
//parametros configurables*************************************************
#define DEBUG_PS 1//Descomentar para debug
class ActualDomoConfig: public DomoConfig
{
public:
ActualDomoConfig()
{
velocidadPortSerie=115200;
strcpy(ssidWifi,"Idhun");//nombre wifi
strcpy(keyWifi,"Ardileorca1234.");//key wifi
strcpy(ideEsp,"Esp8266_010");//idenitificador del esp (sera único)
strcpy(hostMQTT,"192.168.2.50");//servidor mqttBroker
portMQTT=1883;//puerto del servidor mqtt Broker
refresTimeVars=30;//tiempo de refresco en segundos de las variables
refresTimeSens=15;//tiempo de refresco en segundos de los sensores
}
//configuracion de sensores---------------------------------
virtual void ConfigSens(MqttSensManager* sens)
{
/*
sens->AddHDT22(int pin, char* topic);
//tempe y presion varometrica
sens->AddBMP180(int sda,int scl, char* topic);
//entradas digitales
sens->AddDin(int pin, char* topic);//añade variable digital que se actualiza de manera instantanea (interruptores sensor presencia ..)
sens->AddDinAccion(int pin, char* topic);//añade variable que solo publica en el cambio (pulsadores, ...)
//salida digital
sens->AddDout(int pin, char* topic, bool defautlValor);//variable que solo publica en el cambio (pulsadores, ...)
Sensor analogico
sens->AddAnalogIn(int pin, char* topic, bool ValNegado);//nivel de luz, nivel de lluvia ...
*/
sens->AddHDT22(D4, "casa/cocina");
sens->AddDinAccion(D5, "casa/cocina/mov");
sens->AddAnalogIn(0, "casa/cocina/luz",true);
}
};
//configuracion que se usara--------------------------
ActualDomoConfig ConfiguracionActual;