From 9dbe05dbad88dbcce61efec63b97161148076ca9 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 21 Jan 2022 09:33:57 +0100 Subject: [PATCH] Desencadenadores estables -arreglo de errores varios --- DomoEsp_v01/DomoEspManager.cpp | 11 +- DomoEsp_v01/DomoEspManager.h | 2 +- DomoEsp_v01/DomoEsp_v01.ino | 2 + DomoEsp_v01/MqttDefines.h | 2 +- DomoEsp_v01/MqttDesencadenadorManager.cpp | 115 +++++- DomoEsp_v01/MqttDesencadenadorManager.h | 22 +- DomoEsp_v01/MqttSensManager.cpp | 15 +- DomoEsp_v01/MqttUtiles.h | 5 + DomoEsp_v01/MqttVarManager.cpp | 25 +- DomoEsp_v01/MqttVarManager.h | 1 + DomoEsp_v01/config_rf.h | 126 ++++-- DomoEsp_v02/DomoEspManager.cpp | 91 ++++ DomoEsp_v02/DomoEspManager.h | 105 +++++ DomoEsp_v02/DomoEsp_v02.ino | 76 ++++ DomoEsp_v02/LcdMQTTViewer.cpp | 103 +++++ DomoEsp_v02/LcdMQTTViewer.h | 51 +++ DomoEsp_v02/MqttDefines.h | 24 ++ DomoEsp_v02/MqttDesencadenadorManager.cpp | 415 +++++++++++++++++++ DomoEsp_v02/MqttDesencadenadorManager.h | 113 +++++ DomoEsp_v02/MqttSensManager.cpp | 480 ++++++++++++++++++++++ DomoEsp_v02/MqttSensManager.h | 195 +++++++++ DomoEsp_v02/MqttUtiles.cpp | 171 ++++++++ DomoEsp_v02/MqttUtiles.h | 133 ++++++ DomoEsp_v02/MqttVarManager.cpp | 360 ++++++++++++++++ DomoEsp_v02/MqttVarManager.h | 124 ++++++ DomoEsp_v02/config_rf.h | 206 ++++++++++ 26 files changed, 2900 insertions(+), 73 deletions(-) create mode 100644 DomoEsp_v02/DomoEspManager.cpp create mode 100644 DomoEsp_v02/DomoEspManager.h create mode 100644 DomoEsp_v02/DomoEsp_v02.ino create mode 100644 DomoEsp_v02/LcdMQTTViewer.cpp create mode 100644 DomoEsp_v02/LcdMQTTViewer.h create mode 100644 DomoEsp_v02/MqttDefines.h create mode 100644 DomoEsp_v02/MqttDesencadenadorManager.cpp create mode 100644 DomoEsp_v02/MqttDesencadenadorManager.h create mode 100644 DomoEsp_v02/MqttSensManager.cpp create mode 100644 DomoEsp_v02/MqttSensManager.h create mode 100644 DomoEsp_v02/MqttUtiles.cpp create mode 100644 DomoEsp_v02/MqttUtiles.h create mode 100644 DomoEsp_v02/MqttVarManager.cpp create mode 100644 DomoEsp_v02/MqttVarManager.h create mode 100644 DomoEsp_v02/config_rf.h diff --git a/DomoEsp_v01/DomoEspManager.cpp b/DomoEsp_v01/DomoEspManager.cpp index 12b9a3f..17fc599 100644 --- a/DomoEsp_v01/DomoEspManager.cpp +++ b/DomoEsp_v01/DomoEspManager.cpp @@ -24,11 +24,14 @@ void DomoEspManager::inicia( LiquidCrystal *lcd, PubSubClient *mqttClient, WiFiC Serial.println("Configura Sensores"); #endif //pasar funcion de configuracion de añadir sensores - conf->ConfigGen(&sens, &vars, &lcdm); + + des.inicia(&vars); + conf->ConfigGen(&sens, &vars, &lcdm, &des); #ifdef DEBUG_PS Serial.println("Inicia variables"); #endif vars.inicia(mqttClient); + #ifdef DEBUG_PS Serial.println("Inicia Sensores"); #endif @@ -36,7 +39,6 @@ void DomoEspManager::inicia( LiquidCrystal *lcd, PubSubClient *mqttClient, WiFiC #ifdef DEBUG_PS Serial.println("Iniciado esp"); #endif - des.inicia(&vars); #if CON_LCD lcdm.inicia(&vars, lcd, conf->lcd.colum, conf->lcd.lines); @@ -77,10 +79,7 @@ void DomoEspManager::loop() void DomoEspManager::OnMqtt(char* topic, char* payload) { vars.OnMqtt(topic, payload); - //des.OnMqtt(topic, payload); - #ifdef DEBUG_PS - Serial.println("DomoEspManager::OnMqtt fin"); - #endif + des.OnMqtt(topic, payload); } void DomoEspManager::SubscribeMqtt(PubSubClient *client_mqtt) diff --git a/DomoEsp_v01/DomoEspManager.h b/DomoEsp_v01/DomoEspManager.h index ab4e8e6..38bde27 100644 --- a/DomoEsp_v01/DomoEspManager.h +++ b/DomoEsp_v01/DomoEspManager.h @@ -66,7 +66,7 @@ class DomoConfig int refresTimeSens;//tiempo de refresco en segundos de los sensores - virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd)=0; + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttDesencadenadorManager *des)=0; }; diff --git a/DomoEsp_v01/DomoEsp_v01.ino b/DomoEsp_v01/DomoEsp_v01.ino index cb16357..d7667a9 100644 --- a/DomoEsp_v01/DomoEsp_v01.ino +++ b/DomoEsp_v01/DomoEsp_v01.ino @@ -57,7 +57,9 @@ LiquidCrystal *plcd=NULL; //funciones principales------------------------ void setup() { + #if CON_LCD plcd=&lcd; + #endif #ifdef DEBUG_PS Serial.begin(ConfiguracionActual.velocidadPortSerie); delay(10); diff --git a/DomoEsp_v01/MqttDefines.h b/DomoEsp_v01/MqttDefines.h index 8d1356f..eae11b6 100644 --- a/DomoEsp_v01/MqttDefines.h +++ b/DomoEsp_v01/MqttDefines.h @@ -2,7 +2,7 @@ #ifndef MqttDefinesDef #define MqttDefinesDef 1 #define DEBUG_PS 1 -#define CON_LCD 1 +#define CON_LCD 0 class MqttOnVarChangeListenner { public: diff --git a/DomoEsp_v01/MqttDesencadenadorManager.cpp b/DomoEsp_v01/MqttDesencadenadorManager.cpp index 882f1e6..a3e69c3 100644 --- a/DomoEsp_v01/MqttDesencadenadorManager.cpp +++ b/DomoEsp_v01/MqttDesencadenadorManager.cpp @@ -96,6 +96,26 @@ bool MqttCausaManager::IsTrue(int icau, MqttVarManager *vars) { return false; } +int MqttCausaManager::AddCausa(byte tipo) +{ + MqttCausa c; + c.tipo=tipo; + return caus.Add(&c); +} +int MqttCausaManager::AddEfecto(int icau,byte tipo, int ivar, MQTTvalor *val) +{ + MqttCausa* c=caus.Get(icau); + MqttOper o; + o.oper=tipo; + if(val) + o.val=*val; + o.x=ivar; + int ioper=oper.Add(&o); + if(c->n<=0) + c->ini=ioper; + c->n++; + return ioper; +} //******************************************************************* MqttEfecto::MqttEfecto() @@ -141,17 +161,19 @@ int MqttEfectoArray::Add(MqttEfecto* var) //******************************************************************* MqttDesencadenador::MqttDesencadenador() { - tipo=0; + ne=0; + ic=-1; + ie=-1; } void MqttDesencadenador::Exe(MqttVarManager *vars, MqttEfectoArray *efe, MqttCausaManager* caus) { - switch(tipo) + /*switch(tipo) { - default: + default:*/ if(caus->IsTrue(ie,vars)) efe->Get(ie)->Exe(vars); - break; - } + /* break; + }*/ } //******************************************************************* MqttDesencadenadorArray::MqttDesencadenadorArray() @@ -178,7 +200,7 @@ MqttDesencadenadorManager::MqttDesencadenadorManager() void MqttDesencadenadorManager::OnVarChange(int ivar) { - //revisa=true; + revisa=true; //marca Accion-- } @@ -207,10 +229,89 @@ void MqttDesencadenadorManager::loop() void MqttDesencadenadorManager::RevisaDesencadenadores() { + #ifdef DEBUG_PS + + Serial.println("MqttDesencadenadorManager::RevisaDesencadenadores"); + #endif for(int i=0; iExe(vars, &act, &caus); + des.Get(i)->Exe(vars, &efec, &caus); } + #ifdef DEBUG_PS + + Serial.println("ResetVolatileVar"); + #endif //desmarca Var de volatiles vars->ResetVolatileVar(); + #ifdef DEBUG_PS + + Serial.println("RevisaDesencadenadores fin"); + #endif } +//add--------------------- + int MqttDesencadenadorManager::addDesencadenador(byte tipoCausa) + { + #ifdef DEBUG_PS + + Serial.println("MqttDesencadenadorManager::addDesencadenador"); + #endif + MqttDesencadenador d; + d.ic=caus.AddCausa(tipoCausa); + return des.Add(&d); + } + int MqttDesencadenadorManager::addEfecto(int ides, byte tipo, char *topic) + { + #ifdef DEBUG_PS + + Serial.println("MqttDesencadenadorManager::addEfecto"); + #endif + MqttDesencadenador *d=des.Get(ides); + MqttEfecto e; + #ifdef DEBUG_PS + + Serial.println("addEfecto busca var"); + #endif + e.ia=vars->GetId(topic); + #ifdef DEBUG_PS + + Serial.println("addEfecto fin busca var"); + #endif + e.tipo=tipo; + int ie=efec.Add(&e); + #ifdef DEBUG_PS + + Serial.println("addEfecto fin"); + #endif + if(d->ne<=0) + d->ie=ie; + d->ne++; + #ifdef DEBUG_PS + + Serial.println("addEfecto fin fin"); + #endif + } + int MqttDesencadenadorManager::addOperCausaI(int ides, char *topic, byte tipo, byte val ) + { + #ifdef DEBUG_PS + + Serial.println("MqttDesencadenadorManager::addOperCausaI"); + #endif + MQTTvalor v; + v.i=val; + MqttDesencadenador *d=des.Get(ides); + int ivar=vars->GetId(topic); + return caus.AddEfecto(d->ic, tipo, ivar, &v ); + } + int MqttDesencadenadorManager::addOperCausaF(int ides, char *topic, int tipo, float val ) + { + #ifdef DEBUG_PS + + Serial.println("MqttDesencadenadorManager::addOperCausaF"); + #endif + MQTTvalor v; + v.i=val; + MqttDesencadenador *d=des.Get(ides); + int ivar=vars->GetId(topic); + return caus.AddEfecto(d->ic, tipo, ivar, &v ); + } + //------------------- diff --git a/DomoEsp_v01/MqttDesencadenadorManager.h b/DomoEsp_v01/MqttDesencadenadorManager.h index ce9a33a..02f5c7c 100644 --- a/DomoEsp_v01/MqttDesencadenadorManager.h +++ b/DomoEsp_v01/MqttDesencadenadorManager.h @@ -2,6 +2,7 @@ #ifndef MqttDesencadenadorManagerDef #define MqttDesencadenadorManagerDef 1 #include +#include "MqttDefines.h" #include "MqttVarManager.h" //clase de relacciones/operaciones************************************************ class MqttOper @@ -80,6 +81,8 @@ class MqttCausaManager MqttOperArray oper; MqttCausaManager(); bool IsTrue(int icau, MqttVarManager *vars); + int AddCausa(byte tipo); + int AddEfecto(int icau,byte tipo, int ivar, MQTTvalor *val); }; @@ -125,7 +128,7 @@ class MqttDesencadenador MQTTvalor val; byte ie;//indice a efecto byte ic;//indice a causa - byte tipo;//tipo de accion (and or ...) + byte ne;//numero de efectos total MqttDesencadenador(); @@ -153,24 +156,31 @@ class MqttDesencadenadorManager: public MqttOnVarChangeListenner { public: MqttVarManager *vars; - MqttEfectoArray act; + MqttEfectoArray efec; MqttCausaManager caus; MqttDesencadenadorArray des; bool revisa; MqttDesencadenadorManager(); - - - void inicia( MqttVarManager *vars);//inicia variables si hace falta + //add--------------------- + int addDesencadenador(byte tipoCausa); + int addEfecto(int ides,byte tipo, char *topic);//añade efecto al desencadenador (devuelve id efecto) + int addOperCausaI(int ides, char *topic, byte tipo, byte val ); + int addOperCausaF(int ides, char *topic, int tipo, float val ); + //------------------- + + 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(); + void RevisaDesencadenadores(); }; /* diff --git a/DomoEsp_v01/MqttSensManager.cpp b/DomoEsp_v01/MqttSensManager.cpp index f6bc363..32a7fe7 100644 --- a/DomoEsp_v01/MqttSensManager.cpp +++ b/DomoEsp_v01/MqttSensManager.cpp @@ -273,26 +273,13 @@ void MqttSensManager::procesaSensor(int i) } void MqttSensManager::OnVarChange(int ivar) { - #ifdef DEBUG_PS - Serial.print("Sens::OnVarChange: "); - Serial.println(ivar); - #endif MqttVar *v=vars->Get(ivar); - #ifdef DEBUG_PS - Serial.print(" topic: "); - Serial.println(vars->topics->Get(v->topic)); - #endif MqttSensor *s = sens.Ivar2Sen(ivar); if(s==NULL) - { - #ifdef DEBUG_PS - Serial.println("Sens::OnVarChange Sensor no encontrado"); - #endif return; - } - + switch(s->tipo) { case((int)MqttSensor::SENS_DIGI_OUT): diff --git a/DomoEsp_v01/MqttUtiles.h b/DomoEsp_v01/MqttUtiles.h index 055a842..6108a10 100644 --- a/DomoEsp_v01/MqttUtiles.h +++ b/DomoEsp_v01/MqttUtiles.h @@ -41,6 +41,11 @@ class MqttUtiles public: static bool pasa_incre( unsigned long *tt, unsigned long incre); static bool pasa_incre( volatile unsigned long *tt, unsigned long incre); + static void resetFunc() + { + ESP.wdtEnable(1); + while(1){}; + } }; diff --git a/DomoEsp_v01/MqttVarManager.cpp b/DomoEsp_v01/MqttVarManager.cpp index 9095370..4caf83d 100644 --- a/DomoEsp_v01/MqttVarManager.cpp +++ b/DomoEsp_v01/MqttVarManager.cpp @@ -176,9 +176,6 @@ void MqttVarManager::OnMqtt(char* topic, char* payload) break;//suponemos solo una variable con el mismo topic } } - #ifdef DEBUG_PS - Serial.println("OnmqttVars: fin"); - #endif return; } @@ -268,6 +265,28 @@ MqttVar* MqttVarManager::Get(int i) { return vars->Get(i); } +int MqttVarManager::GetId(char* topic) +{ + #ifdef DEBUG_PS + + Serial.println("MqttVarManager::GetId"); + #endif + int itop= topics->Get(topic); + #ifdef DEBUG_PS + + Serial.println("MqttVarManager::GetId busca var"); + #endif + for(int i=0;in; i++) + { + if(vars->Get(i)->topic==itop) + return i; + } + #ifdef DEBUG_PS + + Serial.println("MqttVarManager::GetId variable no encontrada"); + #endif + return -1; +} void MqttVarManager::OnChange(int ivar) { diff --git a/DomoEsp_v01/MqttVarManager.h b/DomoEsp_v01/MqttVarManager.h index 061155a..e12259e 100644 --- a/DomoEsp_v01/MqttVarManager.h +++ b/DomoEsp_v01/MqttVarManager.h @@ -106,6 +106,7 @@ class MqttVarManager //funciones auxiliares---------------------------- void AddListenner(MqttOnVarChangeListenner *pOnChangeListener); MqttVar* Get(int i); + int GetId(char* topic);//devuelve el id de una variable int AddVar(byte flags, char*topic); int AddInternalVarFloat( char*topic); diff --git a/DomoEsp_v01/config_rf.h b/DomoEsp_v01/config_rf.h index 48635f8..3995b21 100644 --- a/DomoEsp_v01/config_rf.h +++ b/DomoEsp_v01/config_rf.h @@ -1,6 +1,6 @@ //parametros configurables************************************************* #define DEBUG_PS 1//Descomentar para debug -#define CON_LCD 1 +#define CON_LCD 0 class ActualDomoConfig: public DomoConfig { @@ -11,6 +11,93 @@ class ActualDomoConfig: public DomoConfig strcpy(ssidWifi,"Idhun");//nombre wifi strcpy(keyWifi,"Ardileorca1234.");//key wifi + strcpy(ideEsp,"Esp8266_012");//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 + + //config lcd-------------------- + lcd.colum=16;//columnas lcd + lcd.lines=2;//lineas + //pines lcd + lcd.rs=D5; + lcd.en=D6;//eneable + lcd.d0=D3; + lcd.d1=D2; + lcd.d2=D1; + lcd.d3=D0; + + } + //configuracion de sensores, variables, lcd--------------------------------- + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttDesencadenadorManager *des) + { + //sensores-------------------------------------------------------- + /* + 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/desp"); + //sens->AddAnalogIn(0, "casa/desp/luz",true); + //variables---------------------------------------------------- + /* + int ivar= vars->AddVar(byte flags, char*topic);//variable con flags a elegir + int ivar= vars->AddInternalVarFloat( char*topic);//variable privada + int ivar= vars->AddInternalVarInt( char*topic);//variable privada + */ + int lamb= vars->AddInternalVarInt( "casa/Salon/LAmb"); + int lchim= vars->AddInternalVarInt( "casa/Salon/LChime"); + int pul1= vars->AddInternalVarInt( "casa/Salon/pul1"); + //lcd--------------------------------------------------------- + + //lcd->add(0,"T des: %s",0,0); + //lcd->add(1,"H des: %s",1,0); + //lcd->add(temCoci,"T coci: %s",0,1); + //lcd->add(temDesp,"H coci: %s",1,1); + + /* + //sin depender de variable + lcd->add(-1,"Hola",0,0); + lcd->add(-1,"como va",1,0); + + lcd->add(-1,"Mi ritmo",0,1); + lcd->add(-1,"bueno pa goza",1,1);*/ + + + //desencadenadores---------------------------------- + int id=des-> addDesencadenador(MqttCausa::AND_CAUSA);//MqttCausa::AND_CAUSA MqttCausa::OR_CAUSA + //MqttEfecto::InvierteValVar + //MqttEfecto::SetValVar + des->addEfecto(id,MqttEfecto::InvierteValVar, "casa/Salon/LAmb");//añade efecto al desencadenador (devuelve id efecto) + + //MqttOper::Igual_val_oper + //MqttOper::Menor_val_oper + //MqttOper::Mayor_val_oper + des->addOperCausaI(id, "casa/Salon/pul1", MqttOper::Igual_val_oper, (byte)1 ); + //des->addOperCausaF(int ides, char *topic, int tipo, float val ); + + } +}; +//#define DEBUG_PS 1//Descomentar para debug +//#define CON_LCD 1 +class DespachoDomoConfig: public DomoConfig +{ + public: + DespachoDomoConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + strcpy(ideEsp,"Esp8266_011");//idenitificador del esp (sera único) strcpy(hostMQTT,"192.168.2.50");//servidor mqttBroker portMQTT=1883;//puerto del servidor mqtt Broker @@ -31,53 +118,22 @@ class ActualDomoConfig: public DomoConfig } //configuracion de sensores, variables, lcd--------------------------------- - virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd) + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttDesencadenadorManager *des) { //sensores-------------------------------------------------------- - /* - 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/desp"); sens->AddAnalogIn(0, "casa/desp/luz",true); //variables---------------------------------------------------- - /* - int ivar= vars->AddVar(byte flags, char*topic);//variable con flags a elegir - int ivar= vars->AddInternalVarFloat( char*topic);//variable privada - int ivar= vars->AddInternalVarInt( char*topic);//variable privada - */ int temCoci= vars->AddInternalVarFloat( "casa/cocina/t");//variable privada int temDesp= vars->AddInternalVarFloat( "casa/cocina/h");//variable privada //lcd--------------------------------------------------------- - lcd->add(0,"T des: %s",0,0); lcd->add(1,"H des: %s",1,0); lcd->add(temCoci,"T coci: %s",0,1); - lcd->add(temDesp,"H coci: %s",1,1); - /* - lcd->add(-1,"Hola",0,0); - lcd->add(-1,"como va",1,0); - - lcd->add(-1,"Mi ritmo",0,1); - lcd->add(-1,"bueno pa goza",1,1);*/ - + lcd->add(temDesp,"H coci: %s",1,1); } }; -/* - Lcd.add("casa/Ext/dht/t", "TempEx: %s", 0, 0); - Lcd.add("casa/Ext/dht/h", "HumExt: %s", 1, 0); - Lcd.add("casa/Desp/dht/t", "TempIn: %s", 0, 1); - Lcd.add("casa/Desp/dht/h", "HumIn: %s", 1, 1); - */ class CocinaDomoConfig: public DomoConfig { public: @@ -93,7 +149,7 @@ class CocinaDomoConfig: public DomoConfig refresTimeSens=15;//tiempo de refresco en segundos de los sensores } //configuracion de sensores--------------------------------- - virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd) + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttDesencadenadorManager *des) { sens->AddHDT22(D4, "casa/cocina"); sens->AddDinAccion(D5, "casa/cocina/mov"); diff --git a/DomoEsp_v02/DomoEspManager.cpp b/DomoEsp_v02/DomoEspManager.cpp new file mode 100644 index 0000000..109098b --- /dev/null +++ b/DomoEsp_v02/DomoEspManager.cpp @@ -0,0 +1,91 @@ + +#include "DomoEspManager.h" +DomoEspManager::DomoEspManager() +{ + vars.config(NULL, NULL); + //vars.AddListenner(&sens); + //vars.AddListenner(&des); + sens.Config(&vars); + suscrito=false; + +} + +void DomoEspManager::inicia( LiquidCrystal *lcd, 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 + + des.inicia(&vars); + conf->ConfigGen(&sens, &vars, &lcdm, &des); + #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 + #if CON_LCD + + lcdm.inicia(&vars, lcd, conf->lcd.colum, conf->lcd.lines); + + #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(); + des.loop(); + #if CON_LCD + lcdm.loop(); + #endif +} + +void DomoEspManager::OnMqtt(char* topic, char* payload) +{ + vars.OnMqtt(topic, payload); + des.OnMqtt(topic, payload); + #ifdef DEBUG_PS + Serial.println("OnMqtt fin"); + #endif +} + +void DomoEspManager::SubscribeMqtt(PubSubClient *client_mqtt) +{ + +} diff --git a/DomoEsp_v02/DomoEspManager.h b/DomoEsp_v02/DomoEspManager.h new file mode 100644 index 0000000..38bde27 --- /dev/null +++ b/DomoEsp_v02/DomoEspManager.h @@ -0,0 +1,105 @@ + +#ifndef DomoEspManagerDef +#define DomoEspManagerDef 1 + +//#include //este para esp8266 +//#include +#include +#include +/* +#include +#include +#include +*/ +#include "MqttVarManager.h" +#include "MqttUtiles.h" +#include "MqttSensManager.h" +#include "MqttDesencadenadorManager.h" +#include "LcdMQTTViewer.h" + +#if CON_LCD +//configuracion del lcd-------------------------- +#include + + +#include "LcdMQTTViewer.h" + +#endif + + +class PubSubClient; +class WiFiClient; +class MqttSensManager; +/* + * clase principal + */ +class DomoLcdConfig +{ + public: + //pines + byte rs; + byte en;//eneable + byte d0; + byte d1; + byte d2; + byte d3; + + byte colum; + byte lines; +}; + +class DomoConfig +{ + public: + DomoLcdConfig lcd; + + + + 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 ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttDesencadenadorManager *des)=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; + + MqttDesencadenadorManager des; + LcdMQTTViewer lcdm; + bool suscrito; + + //PubSubClient client_qqtt(WifiManager::espClient); + DomoEspManager(); + //PubSubClient client_qqtt(espClient); + void inicia( LiquidCrystal *lcd,PubSubClient *mqttClient, WiFiClient* espClient, DomoConfig* conf); + void loop(); + + //funciones auxiliares + virtual void OnMqtt(char* topic, char* payload); + virtual void SubscribeMqtt(PubSubClient *client_mqtt); + +}; +#endif diff --git a/DomoEsp_v02/DomoEsp_v02.ino b/DomoEsp_v02/DomoEsp_v02.ino new file mode 100644 index 0000000..d7667a9 --- /dev/null +++ b/DomoEsp_v02/DomoEsp_v02.ino @@ -0,0 +1,76 @@ + + +/* + * 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 +#include //este para esp8266 +//#include //este para esp32 + +#include +#include +#include +//#include + + +#include "DomoEspManager.h" +#include "config_rf.h" + +//variables globales---------------------------- +DomoEspManager domoManager; + + +DomoEspManager domoEspManager; +WiFiClient EspClient; +PubSubClient clienteMqtt(EspClient); +LiquidCrystal *plcd=NULL; + #if CON_LCD + LiquidCrystal lcd( + ConfiguracionActual.lcd.rs, + ConfiguracionActual.lcd.en, + ConfiguracionActual.lcd.d0,ConfiguracionActual.lcd.d1,ConfiguracionActual.lcd.d2,ConfiguracionActual.lcd.d3); + + #endif +//funciones principales------------------------ +void setup() +{ + #if CON_LCD + plcd=&lcd; + #endif + #ifdef DEBUG_PS + Serial.begin(ConfiguracionActual.velocidadPortSerie); + delay(10); + Serial.println(""); + Serial.println("Iniciando"); + #endif + domoManager.inicia(plcd,&clienteMqtt,&EspClient,&ConfiguracionActual); + +} + +void loop() +{ + domoManager.loop(); +} diff --git a/DomoEsp_v02/LcdMQTTViewer.cpp b/DomoEsp_v02/LcdMQTTViewer.cpp new file mode 100644 index 0000000..4b7fc76 --- /dev/null +++ b/DomoEsp_v02/LcdMQTTViewer.cpp @@ -0,0 +1,103 @@ + + +#include +#include + +#include "MqttDefines.h" +#include "MqttUtiles.h" +#include "MqttVarManager.h" + +#include "LcdMQTTViewer.h" + +void LcdMQTTViewer::envia(char* txt, int pos, int line) +{ + lcd->setCursor(pos, line); + int l = strlen(txt); + if (l < nchar) + for (int i = l; i < nchar; i++) + txt[i] = ' '; + txt[nchar] = 0; + lcd->print(txt); +} +LcdMQTTViewer::LcdMQTTViewer() +{ + maxpan = 0; + tiempo = 0; + incre_t = 10 * 1000; + for (int i = 0; i < MAXINFOLCD; i++) + { + LcdConf[i].ivar=-1; + LcdConf[i].formatLCD[0] = 0; + LcdConf[i].pan = 255; + } +} +void LcdMQTTViewer::setTimer(int seg) +{ + incre_t = seg * 1000; +} + +void LcdMQTTViewer::envia(int pan) +{ + char val[16]; + char buf[32]; + for (int i = 0; i < maxtInfo; i++) + { + if (LcdConf[i].pan != pan) + continue; + if(LcdConf[i].ivar>=0) + { + MqttVar *v=vars->Get(LcdConf[i].ivar); + if(v==NULL) + continue; + //pilla valor + if(v->flags & MqttVar::FLOAT_VAR) + dtostrf(v->val.f,3, 2, val); + else + sprintf(val, "%d", (int)v->val.i); + sprintf(buf, LcdConf[i].formatLCD, val); + } + else + + strcpy( buf, LcdConf[i].formatLCD); + + + envia(buf,0, LcdConf[i].line); + } +} + +void LcdMQTTViewer::inicia(MqttVarManager *v, LiquidCrystal* lcdEx, int digi, int lines) +{ + vars=v; + lcd =lcdEx; + nchar = digi; + lcd->begin(nchar, lines); + for(int i=0; i= MAXINFOLCD) + return; + LcdConf[maxtInfo].ivar=ivar; + strcpy(LcdConf[maxtInfo].formatLCD, formatLCD); + LcdConf[maxtInfo].line = line; + LcdConf[maxtInfo].pan = pan; + maxtInfo++; + //recalcula numero de pantallas + if (maxpan < pan) + maxpan = pan; +} diff --git a/DomoEsp_v02/LcdMQTTViewer.h b/DomoEsp_v02/LcdMQTTViewer.h new file mode 100644 index 0000000..6107a19 --- /dev/null +++ b/DomoEsp_v02/LcdMQTTViewer.h @@ -0,0 +1,51 @@ +/*#if ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif*/ +#ifndef LcdMQTTViewerdef +#define LcdMQTTViewerdef 1 + +#include "MqttDefines.h" +class LiquidCrystal; +class PubSubClient; +class MqttVarManager; +struct LcdMQTTInfo +{ + byte ivar;//indice a variable + char formatLCD[32];//formato + byte pan;//pantalla en la que sale + byte line;//linea en la que sale + +}; + +#define MAXINFOLCD 8 +class LcdMQTTViewer +{ +public: + LiquidCrystal *lcd; + int nchar; + int maxtInfo; + int maxpan; + int panActual = 0; + unsigned long tiempo; + unsigned long incre_t; + + + MqttVarManager* vars; + + LcdMQTTInfo LcdConf[MAXINFOLCD]; + + LcdMQTTViewer(); + + void inicia(MqttVarManager *vars, LiquidCrystal* lcdEx, int digi, int lines); + void loop();//publica datos variables + +//auxiliares---------------------------------------------------------- + void add(byte ivar, char* formatLCD, int line, int pan); + void setTimer(int seg); + void envia(char* txt, int pos, int line); + void envia(int pan); + void revisa(); +}; +#endif diff --git a/DomoEsp_v02/MqttDefines.h b/DomoEsp_v02/MqttDefines.h new file mode 100644 index 0000000..9f85eaa --- /dev/null +++ b/DomoEsp_v02/MqttDefines.h @@ -0,0 +1,24 @@ + +#ifndef MqttDefinesDef +#define MqttDefinesDef 1 +//generales +#define DEBUG_PS 1 +#define CON_LCD 0 + +#define MAXTOPICVAR 32//maximo de caracteres de los topic de las variables + +//vars-------------------- +#define MAXVAR 12//maximo de variables totales +#define MAXSTR 1024//maximo de caracteres para str + +//sens-------------------- +#define MAXSENS 8 +#define MAXINTERRUP 8 +//class------------------- +class MqttOnVarChangeListenner +{ + public: + virtual void OnVarChange(int ivar)=0; +}; + +#endif diff --git a/DomoEsp_v02/MqttDesencadenadorManager.cpp b/DomoEsp_v02/MqttDesencadenadorManager.cpp new file mode 100644 index 0000000..dc80e1e --- /dev/null +++ b/DomoEsp_v02/MqttDesencadenadorManager.cpp @@ -0,0 +1,415 @@ + +#include "MqttDesencadenadorManager.h" + + +MqttDesencadenador::MqttDesencadenador() +{ +activo=true; +} +MQTTvalor MqttDesencadenador::GetVarValue(char*ivar, MqttVarManager *vars) +{ + MqttVar *v=GetVar(ivar, vars); + return v->val; +} +float MqttDesencadenador::GetValue(char*ivar, MqttVarManager *vars) +{ + MqttVar *v=GetVar(ivar, vars); + if(v->flags & MqttVar::FLOAT_VAR) + return v->val.f; + return 1.*v->val.i; +} + +int MqttDesencadenador::GetIvar(char*ivar) +{ + char buf[16]; + int n=strlen(ivar); + strcpy(buf,ivar); + buf[n-1]=0; + return atoi(buf); +} +MqttVar* MqttDesencadenador::GetVar(char*ivar, MqttVarManager *vars) +{ + return vars->Get(GetIvar(ivar)); +} +void MqttDesencadenador::ExeEfecto(MqttVarManager *vars, char *oper, char*x, char*y) +{ + #ifdef DEBUG_PS + + Serial.print("MqttDesencadenador::ExeEfecto: "); + Serial.print(oper); + Serial.print(" x: "); + Serial.print(x); + Serial.print(" y: "); + Serial.println(y); + #endif + + + switch(oper[0]) + { + case('!'): + { + vars->InvierteVar(GetIvar(x)); + return; + } + case('='): + { + MqttVar* v=GetVar(x, vars); + MQTTvalor val=GetVarValue(x, vars); + if(v->flags | MqttVar::FLOAT_VAR) + val.f=atof(y); + else + val.i=atoi(y); + vars->SetVal(GetIvar(x),val); + return; + } + } +} +bool MqttDesencadenador::Eval(MqttVarManager *vars, char *oper, char*x, char*y) +{ + #ifdef DEBUG_PS + + Serial.print("MqttDesencadenador::eval: "); + Serial.print(oper); + Serial.print(" x: "); + Serial.print(x); + Serial.print(" y: "); + Serial.println(y); + #endif + //las variables estaran terminadas en } + float vx,vy; + //pilla valores + int nx=strlen(x); + int ny=strlen(y); + if(x[nx-1]=='}') + vx=GetValue(x, vars); + else + vx=atof(x); + if(ny<=0) + vy=0; + if(y[ny-1]=='}') + vy=GetValue(y, vars); + else + vy=atof(y); + switch(oper[0]) + { + case('!'): + return vx!=1; + case('='): + return vx==vy; + case('<'): + { + if(oper[1]=='=') + return vx<=vy; + return vx'): + if(oper[1]=='=') + return vx>=vy; + return vx>vy; + } + return false; + +} +int MqttDesencadenador::GetElementosOper( char *oper) +{ + if(oper[0]=='!') + return 1; + else + return 2; +} +void MqttDesencadenador::procesaOper(MqttExeParam *p) +{ + if(expresion[p->i]<='9' && expresion[p->i]>='0'|| expresion[p->i]=='.'|| expresion[p->i]=='{' || expresion[p->i]==' ' ) + { + p->estado=0; + p->toper=true; + p->oper[p->noper]=0; + #ifdef DEBUG_PS + Serial.print("encontrado oper: "); + Serial.println( p->oper); + #endif + } + else + { + p->oper[p->noper++]=expresion[p->i]; + p->i++; + } + +} + +void MqttDesencadenador::procesaVar(MqttExeParam *p) +{ + if((expresion[p->i]<='9' && expresion[p->i]>='0')|| expresion[p->i]=='.') + { + if(p->tvar1) + p->var2[p->nvar2++]=expresion[p->i]; + else + p->var1[p->nvar1++]=expresion[p->i]; + p->i++; + + + } + else + { + p->estado=0; + if(expresion[p->i]=='}') + { + if(p->tvar1) + p->var2[p->nvar2++]=expresion[p->i]; + else + p->var1[p->nvar1++]=expresion[p->i]; + p->i++; + } + if(p->tvar1) + { + p->var2[p->nvar2]=0; + p->tvar2=true; + #ifdef DEBUG_PS + Serial.print("encontrado var2: "); + Serial.println( p->var2); + #endif + } + else + { + p->var1[p->nvar1]=0; + p->tvar1=true; + #ifdef DEBUG_PS + Serial.print("encontrado var1: "); + Serial.println( p->var1); + #endif + } + } +} +void MqttDesencadenador::Exe(MqttVarManager *vars) +{ + #ifdef DEBUG_PS + + Serial.print("MqttDesencadenador::Exe: "); + Serial.print(expresion); + Serial.print(" activo: "); + Serial.println(activo); + #endif + //por ahora limite de 2 var + MqttExeParam p; + while(expresion[p.i]!=0 && p.sigue) + { + /* + #ifdef DEBUG_PS + Serial.print("MqttDesencadenador::Exe: "); + Serial.print(expresion[i]); + Serial.print(" estado "); + Serial.println(estado); + #endif + */ + switch(p.estado) + { + + case(0)://estado selector + { + //distincion de operar + if(p.toper) + { + if(p.oper[0]=='-' && p.oper[1]=='>') + { + + p.tcausa=true; + p.toper=false; + p.noper=0; + + if(!p.res || !activo) + { + activo=!p.res; + #ifdef DEBUG_PS + + Serial.println("Fin causa sale "); + #endif + p.sigue=false; + break; + } + else + { + #ifdef DEBUG_PS + activo=false; + Serial.println("Fin causa sigue "); + #endif + } + } + else if(p.oper[0]=='&') + { + #ifdef DEBUG_PS + + Serial.println("operador and "); + #endif + p.tcausa=true; + p.toper=false; + p.noper=0; + p.esAnd=true; + + } + else if(p.oper[0]=='|') + { + #ifdef DEBUG_PS + + Serial.println("operador or "); + #endif + p.tcausa=true; + p.toper=false; + p.noper=0; + p.esAnd=false; + } + } + if(p.toper && p.tvar1 &&(GetElementosOper(p.oper)==1 || p.tvar2)) + { + + //valida causa + if(!p.tcausa) + { + //valida causa + if(p.esAnd) + p.res= p.res && Eval(vars, p.oper, p.var1, p.var2 ); + else + p.res=p.res || Eval(vars, p.oper, p.var1, p.var2 ); + + #ifdef DEBUG_PS + Serial.print("validaCausa res: "); + Serial.print(p.res); + Serial.print(" esAnd: "); + Serial.println(p.esAnd); + #endif + + } + else + { + //ejecuta efecto + ExeEfecto( vars,p.oper, p.var1, p.var2 ); + } + #ifdef DEBUG_PS + + Serial.println("Fin oper "); + #endif + p.tvar1=p.tvar2=p.toper=false; + p.nvar1=p.nvar2=p.noper=0; + p.var1[0]=0; + p.var2[0]=0; + } + if(expresion[p.i]==' ')//pasa de los espacios + { + p.i++; + break; + } + + //distincion de escalares + if((expresion[p.i]<='9' && expresion[p.i]>='0') || expresion[p.i]=='.' ) + { + p.estado=1; + if(p.tvar1) + p.nvar2=0; + else + p.nvar1=0; + } + else + { + //distincion de variables + if(expresion[p.i]=='{') + { + + p.estado=1; + p.i++; + } + else//distincion de operadores + { + p.estado=2; + } + } + + } + break; + case(1)://pillando var o escalar + procesaVar(&p); + break; + case(2)://pilla oper + procesaOper(&p); + break; + } + } + Serial.println("MqttDesencadenador::Exe fin"); +} +//******************************************************************* +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; + if(des.n>0) + vars->AddListenner(this); +} + +void MqttDesencadenadorManager::Suscribe() +{ + +} +int MqttDesencadenadorManager::OnMqtt(char* topic, char* payload) +{ + return -1; +} + +void MqttDesencadenadorManager::loop() +{ + if(revisa) + { + revisa=false; + RevisaDesencadenadores(); + } +} + +void MqttDesencadenadorManager::RevisaDesencadenadores() +{ + #ifdef DEBUG_PS + + Serial.println("MqttDesencadenadorManager::RevisaDesencadenadores"); + #endif + for(int i=0; iExe(vars); + } + + //desmarca Var de volatiles + vars->ResetVolatileVar(); + #ifdef DEBUG_PS + + Serial.println("RevisaDesencadenadores fin"); + #endif +} +void MqttDesencadenadorManager::AddDes(char *expresion) +{ + MqttDesencadenador d; + strcpy(d.expresion, expresion); + des.Add(&d); +} diff --git a/DomoEsp_v02/MqttDesencadenadorManager.h b/DomoEsp_v02/MqttDesencadenadorManager.h new file mode 100644 index 0000000..682aed3 --- /dev/null +++ b/DomoEsp_v02/MqttDesencadenadorManager.h @@ -0,0 +1,113 @@ + +#ifndef MqttDesencadenadorManagerDef +#define MqttDesencadenadorManagerDef 1 +#include +#include "MqttDefines.h" +#include "MqttVarManager.h" +//expresiones del tipo{1}&{2} +struct MqttExeParam +{ + char oper[3]; + byte noper; + char var1[8]; + byte nvar1; + char var2[8]; + byte nvar2; + + byte estado; + int i; + bool tvar1; + bool tvar2; + bool toper; + bool tcausa; + bool res; + bool sigue; + bool esAnd; + MqttExeParam() + { + + noper=0; + nvar1=0; + nvar2=0; + estado=0; + i=0; + tvar1=false; + tvar2=false; + toper=false; + tcausa=false; + res=true; + sigue=true; + esAnd=true; + var1[0]=0; + var2[0]=0; + } +}; +class MqttDesencadenador +{ + public: + char expresion[24];//{1}=1->!{2} + bool activo;//se desactivan automaticamente cuando se cumple la condicion y se vuelve activar cuando deja de cumplirse + + MqttDesencadenador(); + + void Exe(MqttVarManager *vars); + + //auxiliar---------------- + void procesaVar(MqttExeParam *p); + void procesaOper(MqttExeParam *p); + MQTTvalor GetVarValue(char*ivar, MqttVarManager *vars); + int GetIvar(char*ivar); + MqttVar* GetVar(char*ivar, MqttVarManager *vars); + int GetElementosOper( char *oper); + + bool Eval(MqttVarManager *vars, char *oper, char*x, char*y); + void ExeEfecto(MqttVarManager *vars, char *oper, char*x, char*y); + float GetValue(char *ivar, MqttVarManager *vars); +}; + +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; + byte ivars[24]; + int nv; + 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 + + //add------------ + void AddDes(char *expresion); + + + virtual void OnVarChange(int ivar); + + void RevisaDesencadenadores(); + +}; +/* + * + */ + #endif diff --git a/DomoEsp_v02/MqttSensManager.cpp b/DomoEsp_v02/MqttSensManager.cpp new file mode 100644 index 0000000..31c8648 --- /dev/null +++ b/DomoEsp_v02/MqttSensManager.cpp @@ -0,0 +1,480 @@ +//#include //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; iivar==ivar) + return res; + } + #ifdef DEBUG_PS + Serial.print("Sens::Ivar2Sen: no encontrada sensor de variable: "); + Serial.println(ivar); + #endif + 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; +} +void MqttSensManager::SetTimeRefres(int seg) +{ + incre_tsens=seg*1000; +} +void MqttSensManager::Config(MqttVarManager* var) +{ + vars=var; +} + +MqttSensor* MqttSensManager::Get(int i) +{ + +} + +void MqttSensManager::inicia() +{ + if(sens.n>0) + vars->AddListenner(this); +} +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; iGet(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) +{ + + MqttVar *v=vars->Get(ivar); + MqttSensor *s = sens.Ivar2Sen(ivar); + + if(s==NULL) + return; + #ifdef DEBUG_PS + Serial.println("MqttSensManager::OnChange "); + #endif + 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; + } + #ifdef DEBUG_PS + Serial.println("OnVarChangeSensor fin"); + #endif +} + +void MqttSensManager::procesaInterrupciones() +{ + if(!MqttChangeInterrup) + { + return; + } + noInterrupts(); + MqttChangeInterrup=false; + interrupts(); + + for(int i=0; iGet(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]); + 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); + }*/ diff --git a/DomoEsp_v02/MqttSensManager.h b/DomoEsp_v02/MqttSensManager.h new file mode 100644 index 0000000..dc08a50 --- /dev/null +++ b/DomoEsp_v02/MqttSensManager.h @@ -0,0 +1,195 @@ + +#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 + +//class PubSubClient; +class MqttVarManager; +#include +#include +#include +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[MAXSENS];//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[MAXINTERRUP]; + + 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 diff --git a/DomoEsp_v02/MqttUtiles.cpp b/DomoEsp_v02/MqttUtiles.cpp new file mode 100644 index 0000000..c92a3a0 --- /dev/null +++ b/DomoEsp_v02/MqttUtiles.cpp @@ -0,0 +1,171 @@ +#include + + + +#include +#include + +#include +#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=30; + 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; +} diff --git a/DomoEsp_v02/MqttUtiles.h b/DomoEsp_v02/MqttUtiles.h new file mode 100644 index 0000000..6108a10 --- /dev/null +++ b/DomoEsp_v02/MqttUtiles.h @@ -0,0 +1,133 @@ +#ifndef MqttUtilesrDef +#define MqttUtilesDef 1 + + +//#include //este para esp32 +#include //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); + static void resetFunc() + { + ESP.wdtEnable(1); + while(1){}; + } +}; + + +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 + void get(Cgeneg* dout)//lee entero + { + byte *b=(byte)dout; + for(int i=sizeof(Cgeneg); i>0;i--) + leeb(&b[i]); + }; + template + + void set(Cgenes* dout)//lee entero + { + byte *b=(byte*)dout; + for(int i=sizeof(Cgenes); i>0;i--) + grabab(b[i]); + }; +}; + +#endif diff --git a/DomoEsp_v02/MqttVarManager.cpp b/DomoEsp_v02/MqttVarManager.cpp new file mode 100644 index 0000000..11097a7 --- /dev/null +++ b/DomoEsp_v02/MqttVarManager.cpp @@ -0,0 +1,360 @@ +//#include //este para esp8266 +#include +#include "MqttDefines.h" +#include "MqttVarManager.h" +#include "MqttUtiles.h" +#include +#include + +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(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; in; i++) + { + v=vars->Get(i); + + if((v->flags & f) && !strcmp(topics->Get(v->topic),buf)) + { + 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; + } + break;//suponemos solo una variable con el mismo topic + } + } + + if(res>=0) + OnChange(res); + return; +} + +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); + if(v->flags & MqttVar::CHANGE_VAR) + sprintf(buffer_t, "%s/set",topics->Get(v->topic)); + else + 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; in; 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; in; 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); + } + if(v->flags & MqttVar::PRIV_VAR)//suscribe al get + { + sprintf(buffer_t, "%s/get",topics->Get(v->topic)); + client_qqtt->subscribe(buffer_t); + } + } +} +int MqttVarManager::AddVar(byte flags, char*topic) +{ + MqttVar v; + v.flags=flags; + v.topic=topics->Add(topic); + return vars->Add(&v); +} +int MqttVarManager::AddInternalVarFloat( char*topic) +{ + return AddVar((byte)(MqttVar::PRIV_VAR|MqttVar::FLOAT_VAR| MqttVar::CHANGE_VAR|MqttVar::ACCION_VAR),topic); +} +int MqttVarManager::AddInternalVarInt( char*topic) +{ + return AddVar((byte)(MqttVar::PRIV_VAR| MqttVar::CHANGE_VAR|MqttVar::ACCION_VAR),topic); +} +MqttVar* MqttVarManager::Get(int i) +{ + return vars->Get(i); +} +int MqttVarManager::GetId(char* topic) +{ + #ifdef DEBUG_PS + + Serial.println("MqttVarManager::GetId"); + #endif + int itop= topics->Get(topic); + #ifdef DEBUG_PS + + Serial.println("MqttVarManager::GetId busca var"); + #endif + for(int i=0;in; i++) + { + if(vars->Get(i)->topic==itop) + return i; + } + #ifdef DEBUG_PS + + Serial.println("MqttVarManager::GetId variable no encontrada"); + #endif + return -1; +} + +void MqttVarManager::OnChange(int ivar) +{ + #ifdef DEBUG_PS + + Serial.println("MqttVarManager::OnChange"); + #endif + MqttVar* v=vars->Get(ivar); + byte f= MqttVar::ACCION_VAR; + if(v->flags & f) + { + PublicaVar(ivar); + } + + for (int i=0; iOnVarChange(ivar); + } + +} +void MqttVarManager::AddListenner(MqttOnVarChangeListenner *pOnChangeListener) +{ + onChangeListener[nListenner++]=pOnChangeListener; +} +void MqttVarManager::ResetVolatileVar() +{ + for(int i=0; in; 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); +} diff --git a/DomoEsp_v02/MqttVarManager.h b/DomoEsp_v02/MqttVarManager.h new file mode 100644 index 0000000..ee9c8e9 --- /dev/null +++ b/DomoEsp_v02/MqttVarManager.h @@ -0,0 +1,124 @@ +/*#if ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif*/ +#ifndef MqttvarManagerDef +#define MqttvarManagerDef 1 +#include "MqttDefines.h" + + +class PubSubClient; +//array de topic +class MqttTopicAttay +{ + public: + char str[MAXSTR];//topic de mqtt asociado + int ind[MAXVAR]; + 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,//variable en coma flotante + 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) + CHANGE_VAR=0x40, //publica con set en lugar de get + + }; + + 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[MAXVAR];//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 + void 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 GetId(char* topic);//devuelve el id de una variable + + int AddVar(byte flags, char*topic); + int AddInternalVarFloat( char*topic); + int AddInternalVarInt( 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 diff --git a/DomoEsp_v02/config_rf.h b/DomoEsp_v02/config_rf.h new file mode 100644 index 0000000..05319c7 --- /dev/null +++ b/DomoEsp_v02/config_rf.h @@ -0,0 +1,206 @@ +//parametros configurables************************************************* +#define DEBUG_PS 1//Descomentar para debug +#define CON_LCD 0 + +class ActualDomoConfig: public DomoConfig +{ + public: + ActualDomoConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + + strcpy(ideEsp,"Esp8266_013");//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 + + //config lcd-------------------- + lcd.colum=16;//columnas lcd + lcd.lines=2;//lineas + //pines lcd + lcd.rs=D5; + lcd.en=D6;//eneable + lcd.d0=D3; + lcd.d1=D2; + lcd.d2=D1; + lcd.d3=D0; + + } + //configuracion de sensores, variables, lcd--------------------------------- + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttDesencadenadorManager *des) + { + //sensores-------------------------------------------------------- + /* + 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/desp"); + //sens->AddAnalogIn(0, "casa/desp/luz",true); + //variables---------------------------------------------------- + /* + int ivar= vars->AddVar(byte flags, char*topic);//variable con flags a elegir + int ivar= vars->AddInternalVarFloat( char*topic);//variable privada + int ivar= vars->AddInternalVarInt( char*topic);//variable privada + */ + int lamb= vars->AddInternalVarInt( "casa/Salon/LAmb"); + int lchim= vars->AddInternalVarInt( "casa/Salon/LChime"); + int pul1= vars->AddInternalVarInt( "casa/Salon/pul1"); + //lcd--------------------------------------------------------- + + //lcd->add(0,"T des: %s",0,0); + //lcd->add(1,"H des: %s",1,0); + //lcd->add(temCoci,"T coci: %s",0,1); + //lcd->add(temDesp,"H coci: %s",1,1); + + /* + //sin depender de variable + lcd->add(-1,"Hola",0,0); + lcd->add(-1,"como va",1,0); + + lcd->add(-1,"Mi ritmo",0,1); + lcd->add(-1,"bueno pa goza",1,1);*/ + //desencadenaores---------- + char st[32]; + sprintf(st,"{%d}>0 -> !{%d} & !{%d} ",pul1,lamb,lchim);//terminar en espacios + des->AddDes(st); + + + + } +}; +class PulSalonConfig: public DomoConfig +{ + public: + PulSalonConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + + strcpy(ideEsp,"Esp8266_012");//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 + + //config lcd-------------------- + lcd.colum=16;//columnas lcd + lcd.lines=2;//lineas + //pines lcd + lcd.rs=0; + lcd.en=0;//eneable + lcd.d0=0; + lcd.d1=0; + lcd.d2=0; + lcd.d3=0; + + } + //configuracion de sensores, variables, lcd--------------------------------- + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttDesencadenadorManager *des) + { + //sensores-------------------------------------------------------- + /* + 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/desp"); + sens->AddDout(D1, "casa/Salon/LEnt", true); + /*sens->AddDout(D7, "casa/Salon/LEnt", true); + sens->AddDinAccion( D1, "casa/Salon/pul1"); + sens->AddDinAccion( D2, "casa/Salon/pul2"); + sens->AddDinAccion( D5, "casa/Salon/pul3"); + sens->AddDinAccion( D6, "casa/Salon/pul4");*/ + } +}; +class DespachoDomoConfig: public DomoConfig +{ + public: + DespachoDomoConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + + strcpy(ideEsp,"Esp8266_011");//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 + + //config lcd-------------------- + lcd.colum=16;//columnas lcd + lcd.lines=2;//lineas + //pines lcd + lcd.rs=D5; + lcd.en=D6;//eneable + lcd.d0=D3; + lcd.d1=D2; + lcd.d2=D1; + lcd.d3=D0; + + } + //configuracion de sensores, variables, lcd--------------------------------- + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttDesencadenadorManager *des) + { + //sensores-------------------------------------------------------- + sens->AddHDT22(D4, "casa/desp"); + sens->AddAnalogIn(0, "casa/desp/luz",true); + //variables---------------------------------------------------- + int temCoci= vars->AddInternalVarFloat( "casa/cocina/t");//variable privada + int temDesp= vars->AddInternalVarFloat( "casa/cocina/h");//variable privada + + //lcd--------------------------------------------------------- + lcd->add(0,"T des: %s",0,0); + lcd->add(1,"H des: %s",1,0); + lcd->add(temCoci,"T coci: %s",0,1); + lcd->add(temDesp,"H coci: %s",1,1); + } +}; +class CocinaDomoConfig: public DomoConfig +{ + public: + CocinaDomoConfig() + { + 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 ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttDesencadenadorManager *des) + { + sens->AddHDT22(D4, "casa/cocina"); + sens->AddDinAccion(D5, "casa/cocina/mov"); + sens->AddAnalogIn(0, "casa/cocina/luz",true); + } +}; + + +//configuracion que se usara-------------------------- +PulSalonConfig ConfiguracionActual;