From 6bacb65e2c0b2cba9d6939e297f9e58077c4ba2c Mon Sep 17 00:00:00 2001 From: Gerardo Date: Tue, 18 Jan 2022 22:12:47 +0100 Subject: [PATCH] =?UTF-8?q?Se=20a=C3=B1ade=20version=20anterior?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DomoEsp_v01_ | 1 - DomoEsp_v01_/DomoEspManager.cpp | 41 ++ DomoEsp_v01_/DomoEspManager.h | 62 ++ DomoEsp_v01_/DomoEsp_v01_.ino | 119 ++++ DomoEsp_v01_/MqttSensManager.cpp | 347 +++++++++++ DomoEsp_v01_/MqttSensManager.h | 178 ++++++ DomoEsp_v01_/MqttUtiles.cpp | 111 ++++ DomoEsp_v01_/MqttUtiles.h | 92 +++ DomoEsp_v01_/MqttVarManager.cpp | 220 +++++++ DomoEsp_v01_/MqttVarManager.h | 174 ++++++ DomoEsp_v01_/config_rf.h | 42 ++ DomoEsp_v01_/sens_domo_mqtt.cpp | 907 ++++++++++++++++++++++++++++ DomoEsp_v01_/sens_domo_mqtt.cpp.bak | 907 ++++++++++++++++++++++++++++ DomoEsp_v01_/sens_domo_mqtt.h | 219 +++++++ 14 files changed, 3419 insertions(+), 1 deletion(-) delete mode 160000 DomoEsp_v01_ create mode 100644 DomoEsp_v01_/DomoEspManager.cpp create mode 100644 DomoEsp_v01_/DomoEspManager.h create mode 100644 DomoEsp_v01_/DomoEsp_v01_.ino create mode 100644 DomoEsp_v01_/MqttSensManager.cpp create mode 100644 DomoEsp_v01_/MqttSensManager.h create mode 100644 DomoEsp_v01_/MqttUtiles.cpp create mode 100644 DomoEsp_v01_/MqttUtiles.h create mode 100644 DomoEsp_v01_/MqttVarManager.cpp create mode 100644 DomoEsp_v01_/MqttVarManager.h create mode 100644 DomoEsp_v01_/config_rf.h create mode 100644 DomoEsp_v01_/sens_domo_mqtt.cpp create mode 100644 DomoEsp_v01_/sens_domo_mqtt.cpp.bak create mode 100644 DomoEsp_v01_/sens_domo_mqtt.h diff --git a/DomoEsp_v01_ b/DomoEsp_v01_ deleted file mode 160000 index 310874d..0000000 --- a/DomoEsp_v01_ +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 310874dac84bf8a72171da4714ccac40f5b9f9ad diff --git a/DomoEsp_v01_/DomoEspManager.cpp b/DomoEsp_v01_/DomoEspManager.cpp new file mode 100644 index 0000000..a52ccae --- /dev/null +++ b/DomoEsp_v01_/DomoEspManager.cpp @@ -0,0 +1,41 @@ + +#include "DomoEspManager.h" +DomoEspManager::DomoEspManager() +{ + vars.config(&avar, &topics); + sens.Config(&vars); +} + +void DomoEspManager::inicia(PubSubClient *mqttClient, WiFiClient* espClient, DomoConfig* conf) +{ + wifi.inicia(espClient, conf->ssidWifi, conf->keyWifi); + mqtt.inicia(mqttClient,conf->ideEsp, conf->hostMQTT, conf->portMQTT, this); + + //pasar funcion de configuracion de añadir sensores + conf->ConfigSens(&sens); + + vars.inicia(mqttClient); + sens.inicia(); + + +} + +void DomoEspManager::loop() +{ + if(!wifi.loop()) + return; + if(!mqtt.loop()) + return; + sens.loop(); + vars.loop(); +} + +void DomoEspManager::OnMqtt(char* topic, char* payload) +{ + vars.OnMqtt(topic, payload); +} + +void DomoEspManager::SubscribeMqtt(PubSubClient *client_mqtt) +{ + +} diff --git a/DomoEsp_v01_/DomoEspManager.h b/DomoEsp_v01_/DomoEspManager.h new file mode 100644 index 0000000..c38fb0d --- /dev/null +++ b/DomoEsp_v01_/DomoEspManager.h @@ -0,0 +1,62 @@ + +#ifndef DomoEspManagerDef +#define DomoEspManagerDef 1 + +//#include //este para esp8266 +//#include +#include +/* +#include +#include +#include +*/ +#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; + + 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; + //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 diff --git a/DomoEsp_v01_/DomoEsp_v01_.ino b/DomoEsp_v01_/DomoEsp_v01_.ino new file mode 100644 index 0000000..ac1dfb3 --- /dev/null +++ b/DomoEsp_v01_/DomoEsp_v01_.ino @@ -0,0 +1,119 @@ + + +/* + * 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-------------------------- + + +//************************************************** + + + +//************************************************************************************************************************************************** +//************************************************************************************************************************************************** + + +//************************************************************************************************************************************************** +/*#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 +//************************************************************************************************************************************************** +//************************************************************************************************************************************************** +//************************************************************************************************************************************************** +//************************************************************************************************************************************************** +//includes + +/* +#if CONEXION_ETERNET +#include //para arduino uno con ethernet +#else +#include //este para esp8266 +//#include //este para esp32 +#endif +//#include //para arduino uno con ethernet + +*/ +#include //este para esp8266 +//#include //este para esp32 +//************************************************** +/*#include +#include +#include +#include +#include +#include "sens_domo_mqtt.h"*/ + + +/* +#include +#include +#include +#include +#include */ + + +#include "DomoEspManager.h" +#include "config_rf.h" + +//DomoEspManager domoManager; +WifiManager wifi; +MqttManager mqtt; +MqttVarArray avars; +MqttVarManager vars; +MqttSensArray asens; +MqttSensManager sens; +WiFiClient EspClient; +PubSubClient clienteMqtt(EspClient); +void setup() +{ + //domoManager.inicia(&clienteMqtt,&EspClient,&ConfiguracionActual); +} + +void loop() +{ + //domoManager.loop(); +} diff --git a/DomoEsp_v01_/MqttSensManager.cpp b/DomoEsp_v01_/MqttSensManager.cpp new file mode 100644 index 0000000..a9d7920 --- /dev/null +++ b/DomoEsp_v01_/MqttSensManager.cpp @@ -0,0 +1,347 @@ +//#include //este para esp8266 + + + +/* +#include +#include +#include +*/ +#include "MqttSensManager.h" +#include "MqttVarManager.h" +#include "MqttUtiles.h" + +MqttSensor::MqttSensor() +{ + +} +//******************************************************************* +MqttSensArray::MqttSensArray() +{ + n=0; +} + +MqttSensor* MqttSensArray:: Get(int i) +{ + return &(sens[i]); +} + + +int MqttSensArray::Add(MqttSensor* var) +{ + sens[n]=*var; + n++; + return n-1; +} +//******************************************************************* +MqttSensManager::MqttSensManager() +{ + + n_inter=0; + bloqueo_sens=false; + tiempo_sens=0; + incre_tsens=15*1000;//por defecto 15 segundos + n_inter=0; + pMqttSensManager=this; +} + +void MqttSensManager::Config(MqttVarManager* var) +{ + vars=var; +} + +MqttSensor* MqttSensManager::Get(int i) +{ + +} +int MqttSensManager::Add(MqttSensor* var) +{ + +} + +void MqttSensManager::inicia() +{ + +} +void MqttSensManager::inicia(int i) +{ + +} +void MqttSensManager::loop() +{ + + + if(bloqueo_sens) + return; + procesaInterrupciones(); + + if(MqttUtiles::pasa_incre(&tiempo_sens, incre_tsens)) + { + procesaSens(); + } +} + +void MqttSensManager::AddSensor(MqttSensor* sens) +{ + +} +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); + sens.Add(&s); + pinMode(s.pin, INPUT); + ConfiguraInterrupcion(n_inter++); + +} +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); + sens.Add(&s); + pinMode(s.pin, INPUT); + ConfiguraInterrupcion(n_inter++); +} +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; iie.din.change) + { + noInterrupts(); + s->ie.din.change=false; + interrupts(); + //lee variable + MqttVar *v=vars->Get(s->ivar); + switch((int)s->tipo) + { + case((int)MqttSensor::SENS_DIGI_IN): + { + //lee y llama a cambio si es necesario + byte val=digitalRead(s->pin); + 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 + byte val=digitalRead(s->pin); + v->val.i=val; + vars->OnChange(s->ivar); + + break; + } + default: + break; + } + } + } +} + +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; + } + 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(); + } + default: + { + break; + } + } +} + + //funciones auxiliares de interrupcion------------------------------- + void MqttSensManager::OnInterrupcion(int i) + { + MqttSensor* s=sens.Get(ind_interrup[i]); + s->ie.din.change=true; + } + void MqttSensManager::ConfiguraInterrupcion(int i) + { + int pin=sens.Get(ind_interrup[i])->pin; + switch(i) + { + 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() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(0); + } + + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion1() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(1); + } + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion2() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(2); + } + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion3() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(3); + } + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion4() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(4); + } + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion5() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(5); + } + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion6() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(6); + } + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion7() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(7); + } + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion8() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(8); + } + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion9() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(9); + } +ICACHE_RAM_ATTR void MqttSensManagerInterrupcion10() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(10); + } + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion11() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(11); + } + ICACHE_RAM_ATTR void MqttSensManagerInterrupcion12() + { + MqttSensManager::pMqttSensManager->OnInterrupcion(12); + } diff --git a/DomoEsp_v01_/MqttSensManager.h b/DomoEsp_v01_/MqttSensManager.h new file mode 100644 index 0000000..9b1b1ae --- /dev/null +++ b/DomoEsp_v01_/MqttSensManager.h @@ -0,0 +1,178 @@ + +#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 +#include +#include +#include + +class PubSubClient; +class MqttVarManager; +struct DhtExt +{ + byte ivarH;//puntero a variable humedad + SimpleDHT22 *p; +}; +struct BmpExt +{ + byte ivarP; + byte ivarA; + int pinScl; + Adafruit_BMP085 *p; +}; +struct DinEx +{ + volatile bool change; +}; +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(); + +}; + +//array de sensores-------------------------------------------------------------- +class MqttSensArray +{ + public: + MqttSensor sens[12];//array de variables + int n; + + + MqttSensArray(); + + MqttSensor* Get(int i); + + 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: + static MqttSensManager* pMqttSensManager; + 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); + int Add(MqttSensor* var); + + 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 + void AddHDT22(int pin, char* topic); + void AddBMP180(int sda,int scl, char* topic); + void AddDin(int pin, char* topic);//añade variable digital que se actualiza de manera instantanea + void AddDinAccion(int pin, char* topic);//variable que solo publica en el cambio + + //funciones auxiliares------------ + + MqttSensor* Get(int i); + + void inicia(int i); + + void procesaSens(); + void procesaInterrupciones(); + void procesaSensor(int i); + + //auxiliares de interrupciones----------- + void ConfiguraInterrupcion(int i); + void OnInterrupcion(int i); + +}; + + +/* +*/ +#endif diff --git a/DomoEsp_v01_/MqttUtiles.cpp b/DomoEsp_v01_/MqttUtiles.cpp new file mode 100644 index 0000000..723c2bb --- /dev/null +++ b/DomoEsp_v01_/MqttUtiles.cpp @@ -0,0 +1,111 @@ +#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; + WiFi.mode(WIFI_STA); + WiFi.begin(nred, pass); + + for(int i=0; i<5 && WiFi.status() != WL_CONNECTED; i++) + { + delay(500); + } + + return WiFi.status() == WL_CONNECTED; +} +//************************************************************************************************************************************************** +MqttManager::MqttManager() +{ + +} + +void MqttManager::inicia(PubSubClient *mqttClient,char *ideEsp, char *host, int port, MqttReceiver* classReceiver) +{ + strcpy(idEsp,ideEsp); + MqttManager::listener=classReceiver; + client_mqtt=mqttClient; + client_mqtt->setServer(host, port); + client_mqtt->setCallback(MqttManager::OnMqtt); +} + +bool MqttManager::loop() +{ + if(client_mqtt->loop()) + return true; + + if(client_mqtt->connect(idEsp)) + { + subscribe_mqtt(); + return true; + + } +} +void MqttManager::subscribe_mqtt() +{ + if(MqttManager::listener==NULL) + return; + MqttManager::listener->SubscribeMqtt(client_mqtt); +} +//auxiliar------------------ +void MqttManager::OnMqtt(char* topic, byte* payload, unsigned int length) +{ + if(MqttManager::listener==NULL) + return; + int i; + char buf[32]; + i=31; + if(i>length) + i=length; + memcpy(buf, payload, i); + buf[i]=0; + MqttManager::listener->OnMqtt(topic, buf); + +} diff --git a/DomoEsp_v01_/MqttUtiles.h b/DomoEsp_v01_/MqttUtiles.h new file mode 100644 index 0000000..f977b37 --- /dev/null +++ b/DomoEsp_v01_/MqttUtiles.h @@ -0,0 +1,92 @@ +#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 + + +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: + static MqttReceiver* listener; + 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(); +}; +#endif diff --git a/DomoEsp_v01_/MqttVarManager.cpp b/DomoEsp_v01_/MqttVarManager.cpp new file mode 100644 index 0000000..d919936 --- /dev/null +++ b/DomoEsp_v01_/MqttVarManager.cpp @@ -0,0 +1,220 @@ +//#include //este para esp8266 +#include +#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=0) + return i; + i=n; + n=n+1; + ind[i]=nst; + + nst=nst+strlen(topic)+1; + strcpy(Get(i), topic); +} + +//******************************************************************* + +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 + } + } + + return res; +} + +void MqttVarManager::loop() +{ + if(MqttUtiles::pasa_incre(&tiempo_var, incre_tvar)) + { + PublicaVars(); + } +} + +void MqttVarManager::PublicaVars() +{ + char buffer_t[32]; + char buffer_p[24]; + byte f=MqttVar::IN_VAR; + MqttVar* v; + for(int i=0; in; i++) + { + v=vars->Get(i); + if(v->flags & MqttVar::ACCION_VAR) + continue;//las de accion solo en el onchange + if(v->flags & f) + { + 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::inicia(PubSubClient* client_mqtt) +{ + client_qqtt=client_mqtt; + //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/set",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); +} +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) + { + char buffer_t[32]; + char buffer_p[24]; + //if(v->flags & MqttVar::IN_VAR) + sprintf(buffer_t, "%s/get",topics->Get(v->topic)); + //else + //sprintf(buffer_t, "%s/put",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); + } +} diff --git a/DomoEsp_v01_/MqttVarManager.h b/DomoEsp_v01_/MqttVarManager.h new file mode 100644 index 0000000..bda7e90 --- /dev/null +++ b/DomoEsp_v01_/MqttVarManager.h @@ -0,0 +1,174 @@ +/*#if ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif*/ +#ifndef MqttvarManagerDef +#define MqttvarManagerDef 1 + +#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) + + }; + + 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); + + +}; + +//manager de variables------------------------------------------------------ +class MqttVarManager +{ + 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, MqttTopicAttay* t); + + void inicia(PubSubClient* client_qqtt);//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---------------------------- + MqttVar* Get(int i); + + int AddVar(byte flags, char*topic); + void PublicaVars(); + + void OnChange(int ivar); +}; +/* +//clase de relacciones/operaciones************************************************ +class MqttOper +{ + public: + byte x;//indice a variable 1 + byte y;//indice a variable 2 + byte oper; + + MqttOper(); + + bool Test(MqttVarArray* vars); + +}; + +//array de relacciones-------------------------------------------------------------- +class MqttOperArray +{ + public: + MqttOper data[32]; + int n; + + + MqttVarArray(); + + MqttOper* Get(int i); + bool test(int *i); + + int Add(MqttRelaccion* 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(MqttOperArray *i); + +}; + +class MqttAccion +{ + public: + 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 ...) + + MqttAccion(); + + bool test(MqttOperArray *i); + +}; + + +//falta acciones y efectos +//acciones tienen valor, tipo y ivar(indice a variable) +class MqttDesencadenadorManager +{ + public: + MqttDesencadenadorManager(); +}; + +/* +*/ +#endif diff --git a/DomoEsp_v01_/config_rf.h b/DomoEsp_v01_/config_rf.h new file mode 100644 index 0000000..29384d6 --- /dev/null +++ b/DomoEsp_v01_/config_rf.h @@ -0,0 +1,42 @@ +//parametros configurables************************************************* + +class ActualDomoConfig: public DomoConfig +{ + public: + ActualDomoConfig() + { + strcpy(ssidWifi,"192.168.2.50"); + strcpy(keyWifi,"Ardileorca1234."); + + strcpy(ideEsp,"Esp8266_002"); + strcpy(hostMQTT,"192.168.2.50"); + + portMQTT=1883; + } + + virtual void ConfigSens(MqttSensManager* sens) + { + + } +}; + + +#define ID_ESP "Esp8266_002"//indica id de esp (ha de ser unico por instalacion) +const char *topic_id="casa/Desp/"; +const int seg_espera=30;//intervalo entre muestras de sensores +//parametros wifi--------------------------------------- +const char* ssid = "Idhun";//nombre wifi +const char* password = "Ardileorca1234.";//key wifi +//paremetros mqtt--------------------------------------- +const char* mqtt_server = "192.168.2.50";//servidor mqtt +//const char* mqtt_server = "192.168.1.61";//servidor mqtt +//const char* mqtt_server = "192.168.1.20";//servidor mqtt +const int mqtt_puerto= 1883;//puerto servidor mqtt + +const bool fuerza_graba=true; + + + + + +ActualDomoConfig ConfiguracionActual; diff --git a/DomoEsp_v01_/sens_domo_mqtt.cpp b/DomoEsp_v01_/sens_domo_mqtt.cpp new file mode 100644 index 0000000..59e425e --- /dev/null +++ b/DomoEsp_v01_/sens_domo_mqtt.cpp @@ -0,0 +1,907 @@ +#include "sens_domo_mqtt.h" +//funciones generales +//************************************************************************************************************************************************** +//funcion para decidir cuando enviar info de sensores por mqtt +bool 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; +} +//************************************************************************************************************************************************** +//funcion para decidir cuando enviar info de sensores por mqtt +bool 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; +} +//************************************************************************************************************************************************** +void conecta_serie(int veloc) +{ + if(DEBUG_PS) + { + Serial.begin(veloc); + delay(10); + } +} +/************************************************************************************************************************************************** +void envia_serie(char* s) +{ + if(DEBUG_PS) + Serial.print(s); +} +//************************************************************************************************************************************************** +void envia_serieln(char* s) +{ + if(DEBUG_PS) + Serial.println(s); +}*/ +//************************************************************************************************************************************************** +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; +} +//************************************************************** +Csens_mqtt::Csens_mqtt() +{ + tipo=SENS_NO_ASIG;//tipo sensor + val=0; + pin=-1;//pin de conexion + topic[0]=0; + //----------------------------- + //especificas + val_old=0; + t=0; + retard=0; + id=0; + pun=NULL; +} +//************************************************************** +Csens_mqtt::~Csens_mqtt() +{ +} +//************************************************************** +bool Csens_mqtt::envia_mqtt(PubSubClient *client_qqtt, char *top, bool envia) +{ + if(pin<0) + return false; + char buffer_t[32]; + char buf[24]; + //SimpleDHT22 dht22; + //Adafruit_BMP085 bmp;//para la presion + //RCSwitch rf = RCSwitch();//para rfin + switch(tipo) + { + case(SENS_NO_ASIG): + return true; + + case(SENS_DHT22)://pilla temperatura y humedad + { + + float temperature = 0; + float humidity = 0; + int err = SimpleDHTErrSuccess; + for(int i=0; i<4; i++) + { + err = ((SimpleDHT22*)pun)->read2(pin, &temperature, &humidity, NULL); + if (err != SimpleDHTErrSuccess) + { + delay(20); + continue; + } + break; + } + if(err!=SimpleDHTErrSuccess) + { + temperature=255; + humidity=255; + if(envia) + envia_serieln("envio dht con error"); + } + if(!envia || (temperature==255 && humidity==255)) + return true; + //construlle topic-------------- + sprintf(buffer_t, "%s%s/t",top, topic); + dtostrf(temperature,3, 2, buf); + //envia_serie(buffer_t); + //envia_serieln(buf); + client_qqtt->publish(buffer_t, buf); + sprintf(buffer_t, "%s%s/h",top, topic); + + dtostrf(humidity,3, 2, buf); + client_qqtt->publish(buffer_t, buf); + return true; + } + case(SENS_BMP180): + { + float temperature = ((Adafruit_BMP085*)pun)->readTemperature(); + int presb = ((Adafruit_BMP085*)pun)->readPressure();//pascales + float altb = ((Adafruit_BMP085*)pun)->readAltitude(); + + //envia tempe------------------------------- + sprintf(buffer_t, "%s%s/t",top, topic); + dtostrf(temperature,3, 2, buf); + client_qqtt->publish(buffer_t, buf); + //envia presion barometrica----------------- + sprintf(buffer_t, "%s%s/p",top, topic); + sprintf(buf,"%d",presb); + client_qqtt->publish(buffer_t, buf); + //envia altura barometrica------------------- + sprintf(buffer_t, "%s%s/a",top, topic); + dtostrf(altb,3, 2, buf); + client_qqtt->publish(buffer_t, buf); + return true; + } + case(SENS_ANALOG_IN): + { + float aux; + /* envia_serie("val: "); + envia_serie(val); + envia_serie(" pin: "); + envia_serieln(pin);*/ + if(val) + aux=100.*((float)(1024- analogRead(pin)))/1024; + else + aux=100.*((float)(analogRead(pin)))/1024; + dtostrf(aux,3, 2, buf); + sprintf(buffer_t, "%s%s",top,topic ); + //envia_serie(buffer_t); + //envia_serieln(buf); + + client_qqtt->publish(buffer_t, buf); + return true; + } + case(SENS_DIGI_IN_OUT): + { + if (envia) + { + sprintf(buffer_t, "%s%s", top, topic); + sprintf(buf, "%d", (int)val); + client_qqtt->publish(buffer_t, buf); + } + else + { + sprintf(buffer_t, "%s%s/set",top, topic); + sprintf(buf,"%d",(int) val); + client_qqtt->publish(buffer_t, buf); + } + return true; + } + case(SENS_DIGI_IN): + { + + sprintf(buffer_t, "%s%s",top, topic); + sprintf(buf,"%d",(int) val); + client_qqtt->publish(buffer_t, buf); + //envia_serie(buffer_t); + //envia_serieln(buffer); + return true; + } + case(SENS_DIGI_OUT): + { + sprintf(buffer_t, "%s%s/get",top, topic); + sprintf(buf,"%d",(int) val); + client_qqtt->publish(buffer_t, buf); + return true; + } + case(SENS_RF_DATA_IN): + { + sprintf(buffer_t, "%s%s",top, topic); + sprintf(buf,"%d",(int) val); + client_qqtt->publish(buffer_t, buf); + return true; + } + + default: + return false; + } +} +//************************************************************** +bool Csens_mqtt::get(char *conf) +{ + sprintf(conf, "<%d;%d;%d;%s;%d;%d;%d;%d;>", + (int)tipo, (int)val, pin, topic, (int)val_old, t, retard/1000, id); + envia_serieln(conf); + return true; +} +//************************************************************** +bool Csens_mqtt::set(char *conf) +{ + /* + //la trama empieza por < y acaba por> y se pone la info de las variables de la clase: + byte tipo;//tipo sensor + byte val;//se usa para guradar valor en algunos sensores y flags en otros + int pin;//pin de conexion + char topic[8];//topic de mqtt que se anadira + //----------------------------- + //especificas + byte val_old; + volatile unsigned long t; + unsigned long retard; + long id; + + separadas por ; + */ + envia_serieln("entra en set"); + int i=0, j, k; + char res[17]; + if(conf[i]=='<') + { + i++; + } + else + return false; + k=0; + j=0; + while(conf[i]!='>') + { + if(!conf[i]) + { + envia_serieln("sale por fin"); + return false; + } + if(conf[i]==';') + { + res[j]=0; + j=0; + switch(k) + { + case(0): + tipo= atoi(res); + break; + case(1): + val=atoi(res); + break; + case(2): + pin=atoi(res); + break; + case(3): + strcpy(topic,res); + // tipo=(byte)atoi(res); + break; + case(4): + val_old=atoi(res); + break; + case(5): + t=atoi(res);//atoll + break; + case(6): + retard=1000*atoi(res);//atoll + break; + case(7): + id=atol(res); + break; + } + k++; + } + else + { + res[j]=conf[i]; + j++; + if(j>=16) + { + envia_serieln("sin memo en set"); + return false; + } + } + i++; + } + envia_serieln(k); + return k>7; + //sprintf(conf, "<%d;%d;%d;%s;%d;%ld;%ld;%ld",(int)tipo, (int)val, pin, topic, (int)val_old, t, retard, id); + //return true; +} +//************************************************************** +void Csens_domo_mqtt::para_sens() +{ + int i; + for(i=0; i=300) + { + envia_serie("Error en sensor "); + envia_serie(i); + envia_serieln("BMP no se puede inicializar"); + // return false;//puede que este bien + } + bmppillado=true; + return true; + } + case(Csens_mqtt::SENS_RF_IN): + { + if(rf_in_pillado) + return false; + rf_in_pillado=true; + rf.enableReceive(sen[i].pin); + //rf.setPulseLength(150); + return true; + } + case(Csens_mqtt::SENS_RF_OUT): + { + if(rf_out_pillado) + return false; + rf_out_pillado=true; + rf.enableTransmit(sen[i].pin); + return true; + } + case(Csens_mqtt::SENS_RF_DATA_IN): + { + if(n_rf_in>=MAX_RF_IN_SENS_MQTT) + { + envia_serie("Error en sensor "); + envia_serie(i); + envia_serieln("rf_in sin espacio para mas"); + return false; + } + envia_serie("rf_data retard: "); + envia_serieln(sen[i].retard); + ind_rf_in[n_rf_in]=i; + n_rf_in++; + return true; + } + case(Csens_mqtt::SENS_ANALOG_IN): + { + return true;//no necesita nada + } + case(Csens_mqtt::SENS_DIGI_IN): + { + if(n_inter>=MAX_INTERRUP_SENS_MQTT) + { + envia_serie("Error en sensor "); + envia_serie(i); + envia_serieln("digi_in sin espacio para las interrupciones"); + return false; + } + ind_interrup[n_inter]=i; + envia_serie("inicia din "); + pinMode(sen[i].pin, INPUT); + //digitalWrite(sen[i].pin, sen[i].val); + atachea(n_inter++); + envia_serie("iniciado din "); + return true; + } + case(Csens_mqtt::SENS_DIGI_OUT): + { + pinMode(sen[i].pin, OUTPUT); + digitalWrite(sen[i].pin, sen[i].val); + return true; + } + case(Csens_mqtt::SENS_DIGI_IN_OUT): + { + if (n_inter >= MAX_INTERRUP_SENS_MQTT) + { + envia_serie("Error en sensor "); + envia_serie(i); + envia_serieln("digi_in_out sin espacio para las interrupciones"); + return false; + } + pinMode(sen[i].pin, OUTPUT); + digitalWrite(sen[i].pin, sen[i].val); + + ind_interrup[n_inter] = i; + envia_serie("inicia digi_in_out "); + pinMode(sen[i].id, INPUT); + atachea(n_inter++); + envia_serie("iniciado din "); + return true; + } + default: + break; + } + return false; +} +//************************************************************** +Csens_domo_mqtt::Csens_domo_mqtt() +{ + rf=RCSwitch(); + n=0; + flags=0; + bmppillado= rf_in_pillado= rf_out_pillado = false; + n_inter=0; + t_rev_interrup=1000; + t_inter=0; + n_rf_in=0; + pclase_sens_domo_mq=(void*)this; +} +//************************************************************** +bool Csens_domo_mqtt::conf() +{ + Ceprom_manager ep; + char buf[64]; + int nb, nn; + n=0; + //lee version----------------------------- + buf[0]=0; + ep.leeb((byte*)buf); + if((byte)buf[0]!=(byte)VERSION_SENS_MQTT) + { + envia_serieln("Version no reconocida"); + return false;//sin configuracion + } + for (nn=0; nn=64) + { + ep.leeb((byte*)&buf[++nb]); + } + if(buf[nb]!='>') + break; + buf[++nb]=0; + //envia_serie("conf lee "); + //envia_serieln(buf); + if(sen[n].set(buf)) + n++; + else + { + envia_serie("Error al leer sensor "); + envia_serieln(buf); + } + + } + envia_serie("lee "); + envia_serie(n); + envia_serieln(" sensores"); + return n>0; +} +//************************************************************** +void Csens_domo_mqtt::envia_comunes() +{ + for(int i=0;isubscribe(buffer_t); + break; + } + default: + break; + } + } +} +//************************************************************** + bool Csens_domo_mqtt::on_mqtt(char* topic, char* payload) + { + char buffer_t[32]; + int j; + //descompone topic + + //busca sensor------------------ + for(int i=0;ion_interrupcion(0); + } + + ICACHE_RAM_ATTR void interrupcion1() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(1); + } + ICACHE_RAM_ATTR void interrupcion2() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(2); + } + ICACHE_RAM_ATTR void interrupcion3() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(3); + } + ICACHE_RAM_ATTR void interrupcion4() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(4); + } + ICACHE_RAM_ATTR void interrupcion5() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(5); + } + ICACHE_RAM_ATTR void interrupcion6() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(6); + } + ICACHE_RAM_ATTR void interrupcion7() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(7); + } + ICACHE_RAM_ATTR void interrupcion8() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(8); + } + ICACHE_RAM_ATTR void interrupcion9() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(9); + } +ICACHE_RAM_ATTR void interrupcion10() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(10); + } + ICACHE_RAM_ATTR void interrupcion11() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(11); + } + ICACHE_RAM_ATTR void interrupcion12() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(12); + } + //************************************************************** +void Csens_domo_mqtt::atachea(int i) +{ + if(bloqueo_sens) + return; + //la otra parte de la chapuza que no se me ocurre otra manera + envia_serie("atachea din "); + envia_serie(i); + envia_serie(" pin "); + envia_serieln(sen[ind_interrup[i]].pin); + int pin = sen[ind_interrup[i]].pin; + if (sen[ind_interrup[i]].tipo == Csens_mqtt::SENS_DIGI_IN_OUT) + pin = sen[ind_interrup[i]].id; + switch(i) + { + case(0): + + attachInterrupt(digitalPinToInterrupt(pin), interrupcion0, CHANGE); + break; + case(1): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion1, CHANGE); + break; + case(2): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion2, CHANGE); + break; + case(3): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion3, CHANGE); + break; + case(4): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion4, CHANGE); + break; + case(5): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion5, CHANGE); + break; + case(6): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion6, CHANGE); + break; + case(7): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion7, CHANGE); + break; + case(8): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion8, CHANGE); + break; + case(9): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion9, CHANGE); + break; + case(10): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion10, CHANGE); + break; + case(11): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion11, CHANGE); + break; + case(12): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion12, CHANGE); + break; + } + +} +//*************************************************************** +void Csens_domo_mqtt::on_interrupcion(int i) +{ + envia_serie("On interrup "); + + int j=ind_interrup[i]; + envia_serieln(j); + if (sen[j].retard == 0) + { + sen[j].val_old = 1; + sen[j].t = millis(); + } + else + { + sen[j].val = 1; + sen[j].t = millis(); + } +} +//************************************************************** +void Csens_domo_mqtt::revisa_interrupciones() +{ + int j, i; + //interrupciones puras------------------------------ + for(j=0; j=n_rf_in) + { + envia_serie("rf no reconocido: "); + envia_serieln(val); + return;//id no reconocido + } + //envia_serie("rf on detectado: "); + //envia_serieln(val); + //actualiza valor-------------------------------------------- + sen[i].val=1; + sen[i].t=millis(); + if(!sen[i].val_old) + { + sen[i].envia_mqtt(client_qqtt, top, true); + sen[i].val_old=1; + } +} +//************************************************************** +bool Csens_domo_mqtt::graba_conf() +{ + envia_serieln("Graba config"); + char buf[64]; + bool res=true; + Ceprom_manager ep; + buf[0]=(byte)VERSION_SENS_MQTT; + ep.grabab((byte)buf[0]); + for(int i=0; i=t) + return false; + *tt=t; + return true; +} +//************************************************************************************************************************************************** +//funcion para decidir cuando enviar info de sensores por mqtt +bool 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; +} +//************************************************************************************************************************************************** +void conecta_serie(int veloc) +{ + if(DEBUG_PS) + { + Serial.begin(veloc); + delay(10); + } +} +/************************************************************************************************************************************************** +void envia_serie(char* s) +{ + if(DEBUG_PS) + Serial.print(s); +} +//************************************************************************************************************************************************** +void envia_serieln(char* s) +{ + if(DEBUG_PS) + Serial.println(s); +}*/ +//************************************************************************************************************************************************** +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; +} +//************************************************************** +Csens_mqtt::Csens_mqtt() +{ + tipo=SENS_NO_ASIG;//tipo sensor + val=0; + pin=-1;//pin de conexion + topic[0]=0; + //----------------------------- + //especificas + val_old=0; + t=0; + retard=0; + id=0; + pun=NULL; +} +//************************************************************** +Csens_mqtt::~Csens_mqtt() +{ +} +//************************************************************** +bool Csens_mqtt::envia_mqtt(PubSubClient *client_qqtt, char *top, bool envia) +{ + if(pin<0) + return false; + char buffer_t[32]; + char buf[24]; + //SimpleDHT22 dht22; + //Adafruit_BMP085 bmp;//para la presion + //RCSwitch rf = RCSwitch();//para rfin + switch(tipo) + { + case(SENS_NO_ASIG): + return true; + + case(SENS_DHT22)://pilla temperatura y humedad + { + + float temperature = 0; + float humidity = 0; + int err = SimpleDHTErrSuccess; + for(int i=0; i<4; i++) + { + err = ((SimpleDHT22*)pun)->read2(pin, &temperature, &humidity, NULL); + if (err != SimpleDHTErrSuccess) + { + delay(20); + continue; + } + break; + } + if(err!=SimpleDHTErrSuccess) + { + temperature=255; + humidity=255; + if(envia) + envia_serieln("envio dht con error"); + } + if(!envia) + return true; + //construlle topic-------------- + sprintf(buffer_t, "%s%s/t",top, topic); + dtostrf(temperature,3, 2, buf); + //envia_serie(buffer_t); + //envia_serieln(buf); + client_qqtt->publish(buffer_t, buf); + sprintf(buffer_t, "%s%s/h",top, topic); + + dtostrf(humidity,3, 2, buf); + client_qqtt->publish(buffer_t, buf); + return true; + } + case(SENS_BMP180): + { + float temperature = ((Adafruit_BMP085*)pun)->readTemperature(); + int presb = ((Adafruit_BMP085*)pun)->readPressure();//pascales + float altb = ((Adafruit_BMP085*)pun)->readAltitude(); + + //envia tempe------------------------------- + sprintf(buffer_t, "%s%s/t",top, topic); + dtostrf(temperature,3, 2, buf); + client_qqtt->publish(buffer_t, buf); + //envia presion barometrica----------------- + sprintf(buffer_t, "%s%s/p",top, topic); + sprintf(buf,"%d",presb); + client_qqtt->publish(buffer_t, buf); + //envia altura barometrica------------------- + sprintf(buffer_t, "%s%s/a",top, topic); + dtostrf(altb,3, 2, buf); + client_qqtt->publish(buffer_t, buf); + return true; + } + case(SENS_ANALOG_IN): + { + float aux; + /* envia_serie("val: "); + envia_serie(val); + envia_serie(" pin: "); + envia_serieln(pin);*/ + if(val) + aux=100.*((float)(1024- analogRead(pin)))/1024; + else + aux=100.*((float)(analogRead(pin)))/1024; + dtostrf(aux,3, 2, buf); + sprintf(buffer_t, "%s%s",top,topic ); + //envia_serie(buffer_t); + //envia_serieln(buf); + + client_qqtt->publish(buffer_t, buf); + return true; + } + case(SENS_DIGI_IN_OUT): + { + if (envia) + { + sprintf(buffer_t, "%s%s", top, topic); + sprintf(buf, "%d", (int)val); + client_qqtt->publish(buffer_t, buf); + } + else + { + sprintf(buffer_t, "%s%s/set",top, topic); + sprintf(buf,"%d",(int) val); + client_qqtt->publish(buffer_t, buf); + } + return true; + } + case(SENS_DIGI_IN): + { + + sprintf(buffer_t, "%s%s",top, topic); + sprintf(buf,"%d",(int) val); + client_qqtt->publish(buffer_t, buf); + //envia_serie(buffer_t); + //envia_serieln(buffer); + return true; + } + case(SENS_DIGI_OUT): + { + sprintf(buffer_t, "%s%s/get",top, topic); + sprintf(buf,"%d",(int) val); + client_qqtt->publish(buffer_t, buf); + return true; + } + case(SENS_RF_DATA_IN): + { + sprintf(buffer_t, "%s%s",top, topic); + sprintf(buf,"%d",(int) val); + client_qqtt->publish(buffer_t, buf); + return true; + } + + default: + return false; + } +} +//************************************************************** +bool Csens_mqtt::get(char *conf) +{ + sprintf(conf, "<%d;%d;%d;%s;%d;%d;%d;%d;>", + (int)tipo, (int)val, pin, topic, (int)val_old, t, retard/1000, id); + envia_serieln(conf); + return true; +} +//************************************************************** +bool Csens_mqtt::set(char *conf) +{ + /* + //la trama empieza por < y acaba por> y se pone la info de las variables de la clase: + byte tipo;//tipo sensor + byte val;//se usa para guradar valor en algunos sensores y flags en otros + int pin;//pin de conexion + char topic[8];//topic de mqtt que se anadira + //----------------------------- + //especificas + byte val_old; + volatile unsigned long t; + unsigned long retard; + long id; + + separadas por ; + */ + envia_serieln("entra en set"); + int i=0, j, k; + char res[17]; + if(conf[i]=='<') + { + i++; + } + else + return false; + k=0; + j=0; + while(conf[i]!='>') + { + if(!conf[i]) + { + envia_serieln("sale por fin"); + return false; + } + if(conf[i]==';') + { + res[j]=0; + j=0; + switch(k) + { + case(0): + tipo= atoi(res); + break; + case(1): + val=atoi(res); + break; + case(2): + pin=atoi(res); + break; + case(3): + strcpy(topic,res); + // tipo=(byte)atoi(res); + break; + case(4): + val_old=atoi(res); + break; + case(5): + t=atoi(res);//atoll + break; + case(6): + retard=1000*atoi(res);//atoll + break; + case(7): + id=atol(res); + break; + } + k++; + } + else + { + res[j]=conf[i]; + j++; + if(j>=16) + { + envia_serieln("sin memo en set"); + return false; + } + } + i++; + } + envia_serieln(k); + return k>7; + //sprintf(conf, "<%d;%d;%d;%s;%d;%ld;%ld;%ld",(int)tipo, (int)val, pin, topic, (int)val_old, t, retard, id); + //return true; +} +//************************************************************** +void Csens_domo_mqtt::para_sens() +{ + int i; + for(i=0; i=300) + { + envia_serie("Error en sensor "); + envia_serie(i); + envia_serieln("BMP no se puede inicializar"); + // return false;//puede que este bien + } + bmppillado=true; + return true; + } + case(Csens_mqtt::SENS_RF_IN): + { + if(rf_in_pillado) + return false; + rf_in_pillado=true; + rf.enableReceive(sen[i].pin); + //rf.setPulseLength(150); + return true; + } + case(Csens_mqtt::SENS_RF_OUT): + { + if(rf_out_pillado) + return false; + rf_out_pillado=true; + rf.enableTransmit(sen[i].pin); + return true; + } + case(Csens_mqtt::SENS_RF_DATA_IN): + { + if(n_rf_in>=MAX_RF_IN_SENS_MQTT) + { + envia_serie("Error en sensor "); + envia_serie(i); + envia_serieln("rf_in sin espacio para mas"); + return false; + } + envia_serie("rf_data retard: "); + envia_serieln(sen[i].retard); + ind_rf_in[n_rf_in]=i; + n_rf_in++; + return true; + } + case(Csens_mqtt::SENS_ANALOG_IN): + { + return true;//no necesita nada + } + case(Csens_mqtt::SENS_DIGI_IN): + { + if(n_inter>=MAX_INTERRUP_SENS_MQTT) + { + envia_serie("Error en sensor "); + envia_serie(i); + envia_serieln("digi_in sin espacio para las interrupciones"); + return false; + } + ind_interrup[n_inter]=i; + envia_serie("inicia din "); + pinMode(sen[i].pin, INPUT); + //digitalWrite(sen[i].pin, sen[i].val); + atachea(n_inter++); + envia_serie("iniciado din "); + return true; + } + case(Csens_mqtt::SENS_DIGI_OUT): + { + pinMode(sen[i].pin, OUTPUT); + digitalWrite(sen[i].pin, sen[i].val); + return true; + } + case(Csens_mqtt::SENS_DIGI_IN_OUT): + { + if (n_inter >= MAX_INTERRUP_SENS_MQTT) + { + envia_serie("Error en sensor "); + envia_serie(i); + envia_serieln("digi_in_out sin espacio para las interrupciones"); + return false; + } + pinMode(sen[i].pin, OUTPUT); + digitalWrite(sen[i].pin, sen[i].val); + + ind_interrup[n_inter] = i; + envia_serie("inicia digi_in_out "); + pinMode(sen[i].id, INPUT); + atachea(n_inter++); + envia_serie("iniciado din "); + return true; + } + default: + break; + } + return false; +} +//************************************************************** +Csens_domo_mqtt::Csens_domo_mqtt() +{ + rf=RCSwitch(); + n=0; + flags=0; + bmppillado= rf_in_pillado= rf_out_pillado = false; + n_inter=0; + t_rev_interrup=1000; + t_inter=0; + n_rf_in=0; + pclase_sens_domo_mq=(void*)this; +} +//************************************************************** +bool Csens_domo_mqtt::conf() +{ + Ceprom_manager ep; + char buf[64]; + int nb, nn; + n=0; + //lee version----------------------------- + buf[0]=0; + ep.leeb((byte*)buf); + if((byte)buf[0]!=(byte)VERSION_SENS_MQTT) + { + envia_serieln("Version no reconocida"); + return false;//sin configuracion + } + for (nn=0; nn=64) + { + ep.leeb((byte*)&buf[++nb]); + } + if(buf[nb]!='>') + break; + buf[++nb]=0; + //envia_serie("conf lee "); + //envia_serieln(buf); + if(sen[n].set(buf)) + n++; + else + { + envia_serie("Error al leer sensor "); + envia_serieln(buf); + } + + } + envia_serie("lee "); + envia_serie(n); + envia_serieln(" sensores"); + return n>0; +} +//************************************************************** +void Csens_domo_mqtt::envia_comunes() +{ + for(int i=0;isubscribe(buffer_t); + break; + } + default: + break; + } + } +} +//************************************************************** + bool Csens_domo_mqtt::on_mqtt(char* topic, char* payload) + { + char buffer_t[32]; + int j; + //descompone topic + + //busca sensor------------------ + for(int i=0;ion_interrupcion(0); + } + + ICACHE_RAM_ATTR void interrupcion1() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(1); + } + ICACHE_RAM_ATTR void interrupcion2() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(2); + } + ICACHE_RAM_ATTR void interrupcion3() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(3); + } + ICACHE_RAM_ATTR void interrupcion4() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(4); + } + ICACHE_RAM_ATTR void interrupcion5() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(5); + } + ICACHE_RAM_ATTR void interrupcion6() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(6); + } + ICACHE_RAM_ATTR void interrupcion7() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(7); + } + ICACHE_RAM_ATTR void interrupcion8() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(8); + } + ICACHE_RAM_ATTR void interrupcion9() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(9); + } +ICACHE_RAM_ATTR void interrupcion10() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(10); + } + ICACHE_RAM_ATTR void interrupcion11() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(11); + } + ICACHE_RAM_ATTR void interrupcion12() + { + ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(12); + } + //************************************************************** +void Csens_domo_mqtt::atachea(int i) +{ + if(bloqueo_sens) + return; + //la otra parte de la chapuza que no se me ocurre otra manera + envia_serie("atachea din "); + envia_serie(i); + envia_serie(" pin "); + envia_serieln(sen[ind_interrup[i]].pin); + int pin = sen[ind_interrup[i]].pin; + if (sen[ind_interrup[i]].tipo == Csens_mqtt::SENS_DIGI_IN_OUT) + pin = sen[ind_interrup[i]].id; + switch(i) + { + case(0): + + attachInterrupt(digitalPinToInterrupt(pin), interrupcion0, CHANGE); + break; + case(1): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion1, CHANGE); + break; + case(2): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion2, CHANGE); + break; + case(3): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion3, CHANGE); + break; + case(4): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion4, CHANGE); + break; + case(5): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion5, CHANGE); + break; + case(6): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion6, CHANGE); + break; + case(7): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion7, CHANGE); + break; + case(8): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion8, CHANGE); + break; + case(9): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion9, CHANGE); + break; + case(10): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion10, CHANGE); + break; + case(11): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion11, CHANGE); + break; + case(12): + attachInterrupt(digitalPinToInterrupt(pin), interrupcion12, CHANGE); + break; + } + +} +//*************************************************************** +void Csens_domo_mqtt::on_interrupcion(int i) +{ + envia_serie("On interrup "); + + int j=ind_interrup[i]; + envia_serieln(j); + if (sen[j].retard == 0) + { + sen[j].val_old = 1; + sen[j].t = millis(); + } + else + { + sen[j].val = 1; + sen[j].t = millis(); + } +} +//************************************************************** +void Csens_domo_mqtt::revisa_interrupciones() +{ + int j, i; + //interrupciones puras------------------------------ + for(j=0; j=n_rf_in) + { + envia_serie("rf no reconocido: "); + envia_serieln(val); + return;//id no reconocido + } + //envia_serie("rf on detectado: "); + //envia_serieln(val); + //actualiza valor-------------------------------------------- + sen[i].val=1; + sen[i].t=millis(); + if(!sen[i].val_old) + { + sen[i].envia_mqtt(client_qqtt, top, true); + sen[i].val_old=1; + } +} +//************************************************************** +bool Csens_domo_mqtt::graba_conf() +{ + envia_serieln("Graba config"); + char buf[64]; + bool res=true; + Ceprom_manager ep; + buf[0]=(byte)VERSION_SENS_MQTT; + ep.grabab((byte)buf[0]); + for(int i=0; i= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif*/ +//clase sensor mqtt------------------------------------ +#define DEBUG_PS 1//si 1 se envia log a puerto serie si no 0 +#define MAX_SENS_MQTT 32 +#define MAX_INTERRUP_SENS_MQTT 12 //ojo si se cambia hay que hacer mas funciones de interrupcion +#define MAX_RF_IN_SENS_MQTT 16 +#define VERSION_SENS_MQTT 102 +#include +#include +#include +#include +#include +#include + +class PubSubClient; +class LiquidCrystal; +void conecta_serie(int veloc); +template +void envia_serie(Carg1 s) +{ + if(DEBUG_PS) + Serial.print(s); +}; + +template +void envia_serieln(Carg2 s) +{ + if(DEBUG_PS) + Serial.println(s); +}; + +bool pasa_incre( unsigned long *tt, unsigned long incre); +bool pasa_incre( volatile unsigned long *tt, unsigned long incre); + + ICACHE_RAM_ATTR void interrupcion1(); + ICACHE_RAM_ATTR void interrupcion2(); + ICACHE_RAM_ATTR void interrupcion3(); + ICACHE_RAM_ATTR void interrupcion4(); + ICACHE_RAM_ATTR void interrupcion5(); + ICACHE_RAM_ATTR void interrupcion6(); + ICACHE_RAM_ATTR void interrupcion7(); + ICACHE_RAM_ATTR void interrupcion8(); + ICACHE_RAM_ATTR void interrupcion9(); + ICACHE_RAM_ATTR void interrupcion10(); + ICACHE_RAM_ATTR void interrupcion11(); + ICACHE_RAM_ATTR void interrupcion12(); + +//************************************************************************************************************************************************** + +class Ceprom_manager +{ + public: + int nb; + + Ceprom_manager(); + + void leeb(byte *p);//lee un byte y deja en p + void grabab(byte p);//graba en eprom un byte + void graba_st(char *st); + void fin_grabacion();//hace efectivos los cambios en la eprom + void cursor(int pos=0);//mueve cursor a posicion indicada + template + 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]); + }; +}; +/* + * calse sensor individual de domotica, esta clase administra sensores particulares + * + * Sensor dht22 (sensor out) + * lectura de temperatura y humedad + * tipo: SENS_DHT22 + * val: no usado + * pin: pin digital donde se conecta el sensor + * val_old:no usado + * retard:no usado + * id:no usado + * pun: se almacena el puntero a la clase dht + * + * Sensor bmp180 + * lectura de temperatura presion y altitud varimetrica + * tipo: SENS_BMP180 + * val: no usado + * pin: pin digital donde se conecta el sensor + * val_old:no usado + * retard:no usado + * id:no usado + * pun: se almacena el puntero de la clase bmp + * + * Sensor de entrada analogico + * lectura de 0 a 100 de sensor analogico + * tipo: SENS_ANALOG_IN + * val: si es 0 es directa si es uno es indirecta (la señal de salida es directa o inversamente proporcional a el valor analogico) + * pin: pin analogico donde se conecta el sensor + * val_old:no usado + * retard:no usado + * id:no usado + * pun: no usado + * + * Sensor de entrada digital + * el sensor de entrada digital funciona por interrucciones, el valor se actualiza inmediatamente + * tipo: SENS_DIGI_IN + * val:valor actual del sensor + * pin: pin digital al que esta conectado + * val_old: guarda el valor anterior + * retard: usado para cambiar automaticamente el valor al anterior + * id:no usado + * pun: no usado + + * Sensor de entrada y salida digital (dos pines uno de entrada y otro de salida que tiene que tener el mismo valor) + * el sensor de entrada digital funciona por interrucciones, el valor se actualiza inmediatamente + * tipo: SENS_DIGI_IN_OUT + * val:valor actual del sensor + * pin: pin digital de salida (out) + * val_old:no usado + * retard:no usado + * id:pin digital de entrada (pin digital de entrada) + * pun: no usado + */ +class Csens_mqtt +{ + public: + + //generales-------------------- + byte tipo;//tipo sensor + byte val;//se usa para guradar valor en algunos sensores y flags en otros//byte + int pin;//pin de conexion scl para bmp + char topic[8];//topic de mqtt que se anadira + //----------------------------- + //especificas + byte val_old;//byte + volatile unsigned long t; + unsigned long retard; + long id; //pin sda para bmp + void *pun; + //c y d---------------------- + Csens_mqtt(); + ~Csens_mqtt(); + + bool envia_mqtt(PubSubClient *client_qqtt, char *top, bool envia);//envia estado del sensor por mqtt + //bool recive_mqtt(PubSubClient *client_qqtt, char *top);//recive estado de sensor por mqtt + //bool inicia();//inicia sensor (previamente ya seteado) + bool set(char *conf);//rellena sensor segun trama de configuracion + bool get(char *conf);//anade a la trama la configuracion correspondiente a este sensor + + enum Tipo_sens//indica el tipo de sensor + { + SENS_NO_ASIG=0,//sensor sin asignar + SENS_DHT22,//sensor temperatura y humedad + SENS_BMP180,//sensor presion + SENS_ANALOG_IN,//sensor analogico in + SENS_DIGI_IN,//sensor digital in + SENS_DIGI_OUT,//sensor digital out + SENS_DIGI_IN_OUT,//sensor doble de entrada y salida (dos pines que tienen que tener el mismo valor) + SENS_RF_OUT,//sensor transmisor de rf + SENS_RF_IN,//sensor receptor de rf + SENS_RF_DATA_IN//dato a recivir por rf + }; +}; +//clase manager de sensores mqtt----------------------- + +class Csens_domo_mqtt +{ + public: + SimpleDHT22 cdht;//clase para leer de dht + Adafruit_BMP085 bmp;//clase bmp + PubSubClient *client_qqtt; + bool bmppillado;//indica si el bmp esta asignado o no + RCSwitch rf; + bool bloqueo_sens;//bloquea todos los sensores (para poder editarlos) + byte rf_in_pillado;//indica si rf in esta asignado + bool rf_out_pillado;//indica si rf_out esta asignado + byte ind_interrup[MAX_INTERRUP_SENS_MQTT];//array de interrupciones (indices a sensor) + int n,//numero de sensores + n_inter,//numero de interrupciones + flags; + unsigned long t_inter, t_rev_interrup; + byte ind_rf_in[MAX_RF_IN_SENS_MQTT]; + int n_rf_in; + + char top[16];//topic_id_sensor + Csens_mqtt sen[MAX_SENS_MQTT]; + + Csens_domo_mqtt();//constructor + //funciones------------------------------- + bool inicia(int i);//inicia el sensor iesimo + bool conf();//configura de eprom + void envia_comunes();//envia por mqtt la info de sensores comunes + void revisa_interrupciones();//revisa sensores con interrupciones + void revisa_rf();//revisa entradas de rf + bool graba_conf();//graba configuracion en eprom + void para_sens();//desconfigura todos los sensores (a nivel de hardware) + void del(int i);//borra el sensor iesimo + void subscribe_mqtt();//pone en suspcripcion de los sensores que sean necesarios + + bool on_mqtt(char* topic, char* payload);//recibe traza mqtt + void on_interrupcion(int i);//ejecuta interrupcion iesima + void atachea(int i);//habilita interrupcion iesima + +}; +#ifndef PCLASE_SENS_DOMO +#define PCLASE_SENS_DOMO +static void *pclase_sens_domo_mq; +#endif