From 08357b8eb9809c4f364f8ae1fe3bb714d7a44b7d Mon Sep 17 00:00:00 2001 From: Gerardo Date: Tue, 11 Apr 2023 22:03:37 +0200 Subject: [PATCH] correcciones publicacion --- .gitignore | 2 + DomoEsp_Potencia_v02/CppProperties.json | 8 + DomoEsp_Potencia_v02/DomoEspManager.cpp | 138 ++++ DomoEsp_Potencia_v02/DomoEspManager.h | 115 +++ .../DomoEsp_Potencia_v02.filters | 75 ++ DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.ino | 92 +++ DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.sln | 25 + .../DomoEsp_Potencia_v02.vcxproj | 142 ++++ .../DomoEsp_Potencia_v02.vcxproj.user | 4 + DomoEsp_Potencia_v02/LcdMQTTViewer.cpp | 183 +++++ DomoEsp_Potencia_v02/LcdMQTTViewer.h | 54 ++ DomoEsp_Potencia_v02/MqttDefines.h | 28 + .../MqttDesencadenadorManager.cpp | 431 ++++++++++++ .../MqttDesencadenadorManager.h | 116 ++++ DomoEsp_Potencia_v02/MqttSensManager.cpp | 618 ++++++++++++++++ DomoEsp_Potencia_v02/MqttSensManager.h | 220 ++++++ DomoEsp_Potencia_v02/MqttUtiles.cpp | 346 +++++++++ DomoEsp_Potencia_v02/MqttUtiles.h | 155 +++++ DomoEsp_Potencia_v02/MqttVarManager.cpp | 434 ++++++++++++ DomoEsp_Potencia_v02/MqttVarManager.h | 129 ++++ DomoEsp_Potencia_v02/MqttWOLManager.cpp | 36 + DomoEsp_Potencia_v02/MqttWOLManager.h | 22 + DomoEsp_Potencia_v02/config_rf.h | 657 ++++++++++++++++++ DomoEsp_Potencia_v02/sube.bat | 2 + DomoEsp_v02/.vs/DomoEsp_v02/v17/.suo | Bin 270336 -> 282112 bytes DomoEsp_v02/.vs/DomoEsp_v02/v17/Browse.VC.db | Bin 4423680 -> 4431872 bytes DomoEsp_v02/MqttDefines.h | 4 +- DomoEsp_v02/config_rf.h | 42 +- 28 files changed, 4055 insertions(+), 23 deletions(-) create mode 100644 DomoEsp_Potencia_v02/CppProperties.json create mode 100644 DomoEsp_Potencia_v02/DomoEspManager.cpp create mode 100644 DomoEsp_Potencia_v02/DomoEspManager.h create mode 100644 DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.filters create mode 100644 DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.ino create mode 100644 DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.sln create mode 100644 DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.vcxproj create mode 100644 DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.vcxproj.user create mode 100644 DomoEsp_Potencia_v02/LcdMQTTViewer.cpp create mode 100644 DomoEsp_Potencia_v02/LcdMQTTViewer.h create mode 100644 DomoEsp_Potencia_v02/MqttDefines.h create mode 100644 DomoEsp_Potencia_v02/MqttDesencadenadorManager.cpp create mode 100644 DomoEsp_Potencia_v02/MqttDesencadenadorManager.h create mode 100644 DomoEsp_Potencia_v02/MqttSensManager.cpp create mode 100644 DomoEsp_Potencia_v02/MqttSensManager.h create mode 100644 DomoEsp_Potencia_v02/MqttUtiles.cpp create mode 100644 DomoEsp_Potencia_v02/MqttUtiles.h create mode 100644 DomoEsp_Potencia_v02/MqttVarManager.cpp create mode 100644 DomoEsp_Potencia_v02/MqttVarManager.h create mode 100644 DomoEsp_Potencia_v02/MqttWOLManager.cpp create mode 100644 DomoEsp_Potencia_v02/MqttWOLManager.h create mode 100644 DomoEsp_Potencia_v02/config_rf.h create mode 100644 DomoEsp_Potencia_v02/sube.bat diff --git a/.gitignore b/.gitignore index 199b500..8ec9eaa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /DomoEsp_v02/.vs/* /DomoEsp_v02/.vs/DomoEsp_v02/v17/* +/DomoEsp_Potencia_v02/.vs/* +/DomoEsp_Potencia_v02/__vm/* diff --git a/DomoEsp_Potencia_v02/CppProperties.json b/DomoEsp_Potencia_v02/CppProperties.json new file mode 100644 index 0000000..f183473 --- /dev/null +++ b/DomoEsp_Potencia_v02/CppProperties.json @@ -0,0 +1,8 @@ +{ + "configurations": [ + { + "name": "Visual Micro", + "intelliSenseMode": "windows-msvc-x86" + } + ] +} \ No newline at end of file diff --git a/DomoEsp_Potencia_v02/DomoEspManager.cpp b/DomoEsp_Potencia_v02/DomoEspManager.cpp new file mode 100644 index 0000000..81ad722 --- /dev/null +++ b/DomoEsp_Potencia_v02/DomoEspManager.cpp @@ -0,0 +1,138 @@ + +#include "DomoEspManager.h" +DomoEspManager::DomoEspManager() +{ + vars.config(NULL, NULL); + //vars.AddListenner(&sens); + //vars.AddListenner(&des); + sens.Config(&vars); + sens.buzz=&buzz; + suscrito=false; +} + +void DomoEspManager::inicia(WakeOnLan *pwol, LiquidCrystal *lcd, PubSubClient *mqttClient, WiFiClient* espClient, DomoConfig* conf) +{ + mqttclient=mqttClient; + #ifdef DEBUG_PS + Serial.println("Inicia Wifi"); + #endif + wifi.inicia(espClient, conf->ssidWifi, conf->keyWifi, conf->ideEsp); + #ifdef DEBUG_PS + Serial.println("Inicia Mqtt"); + #endif + mqtt.inicia(mqttClient,conf->ideEsp, conf->hostMQTT, conf->portMQTT, this); +#ifdef DEBUG_PS + Serial.println("Configura Sensores"); + #endif + //pasar funcion de configuracion de añadir sensores + + + conf->ConfigGen(&sens, &vars, &lcdm, &wol, &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 Desencadenadores"); + #endif + des.inicia(&vars); + + + + #if CON_LCD + #ifdef DEBUG_PS + Serial.println("Iniciado LCD"); + #endif + //busca buzzer + int ibuzzer=-1; + for(int i=0; itipo == MqttSensor::SENS_BUZZ_OUT) + { + ibuzzer=s->ivar; + #ifdef DEBUG_PS + Serial.println("encuentrado buz"); + #endif + break; + } + } + #ifdef DEBUG_PS + Serial.println("inicia LCD"); + #endif + lcdm.inicia(&vars, lcd, conf->lcd.colum, conf->lcd.lines, ibuzzer); + #ifdef DEBUG_PS + Serial.println("iniciado LCD"); + #endif + #endif + wol.inicia(pwol); + +} + +void DomoEspManager::loop() +{ + + if(!wifi.loop()) + { + suscrito=false; + return; + } + + if(!mqtt.loop()) + { + suscrito=false; + return; + } + + if(!suscrito) + { + vars.Suscribe(); + #if CON_LCD + lcdm.suscribe(mqttclient); + #endif + wol.suscribe(mqttclient); + 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); + #if CON_LCD + lcdm.OnMqtt(topic, payload); + #endif + + #if CON_WOL + wol.OnMqtt(topic, payload); + #endif + + #ifdef DEBUG_PS + Serial.println("OnMqtt fin"); + #endif +} + +void DomoEspManager::SubscribeMqtt(PubSubClient *client_mqtt) +{ + +} diff --git a/DomoEsp_Potencia_v02/DomoEspManager.h b/DomoEsp_Potencia_v02/DomoEspManager.h new file mode 100644 index 0000000..bca0977 --- /dev/null +++ b/DomoEsp_Potencia_v02/DomoEspManager.h @@ -0,0 +1,115 @@ + +#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" +#include "MqttWOLManager.h" + + +#if CON_LCD +//configuracion del lcd-------------------------- +#include + + +#include "LcdMQTTViewer.h" + +#endif + + +class PubSubClient; +class WiFiClient; +class MqttSensManager; +class WakeOnLan; +/* + * 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[32];//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, MqttWOLManager *wol, MqttDesencadenadorManager *des)=0; + + +}; +//TODO falta funcion en configuracion para añadir sensores y variables +class DomoEspManager: public MqttReceiver +{ + public: + + + + PubSubClient *mqttclient; + //variables------------- + //MqttVarArray avar; + //MqttTopicAttay topics; + + MqttVarManager vars; + MqttSensManager sens; + + WifiManager wifi; + MqttManager mqtt; + + MqttDesencadenadorManager des; + + SonidoBuzzer buzz; + + LcdMQTTViewer lcdm; + + MqttWOLManager wol; + + bool suscrito; + + //PubSubClient client_qqtt(WifiManager::espClient); + DomoEspManager(); + //PubSubClient client_qqtt(espClient); + void inicia(WakeOnLan* pwol, 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_Potencia_v02/DomoEsp_Potencia_v02.filters b/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.filters new file mode 100644 index 0000000..e2bbce9 --- /dev/null +++ b/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.filters @@ -0,0 +1,75 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.ino b/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.ino new file mode 100644 index 0000000..ba60205 --- /dev/null +++ b/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.ino @@ -0,0 +1,92 @@ +/* + * 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 + +WiFiUDP UDP; +#include +#include +#include +//#include + + +#include "DomoEspManager.h" + +#include "MqttWOLManager.h" +#include + +#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 + +WakeOnLan* pwol=NULL; +#if CON_WOL + +WakeOnLan WOL(UDP); +//pwol=&WOL; +#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 + #if CON_WOL + pwol=&WOL; + #endif + domoManager.inicia(pwol,plcd,&clienteMqtt,&EspClient,&ConfiguracionActual); + +} + +void loop() +{ + domoManager.loop(); +} diff --git a/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.sln b/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.sln new file mode 100644 index 0000000..1e33a11 --- /dev/null +++ b/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32112.339 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DomoEsp_v02", "DomoEsp_v02.vcxproj", "{C5F80730-F44F-4478-BDAE-6634EFC2CA88}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.ActiveCfg = Debug|Win32 + {C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.Build.0 = Debug|Win32 + {C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.ActiveCfg = Release|Win32 + {C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1995B5A1-341C-4B18-B509-04838EC7A212} + EndGlobalSection +EndGlobal diff --git a/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.vcxproj b/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.vcxproj new file mode 100644 index 0000000..6a2c993 --- /dev/null +++ b/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.vcxproj @@ -0,0 +1,142 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {C5F80730-F44F-4478-BDAE-6634EFC2CA88} + DomoEsp_Potencia_v02 + DomoEsp_Potencia_v02 + + + + Application + true + MultiByte + v143 + + + Application + false + true + MultiByte + v143 + + + Application + true + MultiByte + v143 + + + Application + false + true + MultiByte + v143 + + + Application + false + true + MultiByte + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + $(ProjectDir)..\DomoEsp_Potencia_v02;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\SPI;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi\src;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266mDNS\src;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ArduinoOTA;C:\Users\Gerardo\Documents\Arduino\libraries\SimpleDHT;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\Wire;C:\Users\Gerardo\Documents\Arduino\libraries\Adafruit_BMP085_Library;C:\Users\Gerardo\Documents\Arduino\libraries\WakeOnLan\src;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\avr;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\libb64;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\spiffs;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\umm_malloc;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\variants\nodemcu;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\tools\sdk\include;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\tools\sdk\lwip2\include;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\tools\sdk\libc\xtensa-lx106-elf\include;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.4-gcc10.3-1757bed\xtensa-lx106-elf\include\c++\4.8.2;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.4-gcc10.3-1757bed\xtensa-lx106-elf\include\c++\4.8.2\xtensa-lx106-elf;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.4-gcc10.3-1757bed\xtensa-lx106-elf\include;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.4-gcc10.3-1757bed\lib\gcc\xtensa-lx106-elf\4.8.2\include;C:\Users\Gerardo\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\3.0.2\tools\sdk\include;%(AdditionalIncludeDirectories) + $(ProjectDir)__vm\.DomoEsp_Potencia_v02.vsarduino.h;%(ForcedIncludeFiles) + true + __ESP8266_esp8266__;__ESP8266_ESP8266__;_VMDEBUG=1;__ets__;ICACHE_FLASH;_GNU_SOURCE;MMU_IRAM_SIZE=0x8000;MMU_ICACHE_SIZE=0x8000;NONOSDK22x_190703=1;F_CPU=80000000L;LWIP_OPEN_SRC;TCP_MSS=536;LWIP_FEATURES=1;LWIP_IPV6=0;ARDUINO=108016;ARDUINO_ESP8266_NODEMCU_ESP12E;ARDUINO_ARCH_ESP8266;LED_BUILTIN=2;FLASHMODE_DIO;ESP8266;__cplusplus=201103L;_VMICRO_INTELLISENSE;%(PreprocessorDefinitions) + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + VisualMicroDebugger + + + + CppCode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.vcxproj.user b/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/DomoEsp_Potencia_v02/DomoEsp_Potencia_v02.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/DomoEsp_Potencia_v02/LcdMQTTViewer.cpp b/DomoEsp_Potencia_v02/LcdMQTTViewer.cpp new file mode 100644 index 0000000..f480669 --- /dev/null +++ b/DomoEsp_Potencia_v02/LcdMQTTViewer.cpp @@ -0,0 +1,183 @@ + + +#include +#include +#include +#include "MqttDefines.h" +#include "MqttUtiles.h" +#include "MqttVarManager.h" + +#include "LcdMQTTViewer.h" + +void LcdMQTTViewer::envia(char* txt, int pos, int line) +{ + char buf[MAXTOPICVAR]; + + int l = strlen(txt); + if (l > nchar) + l = nchar; + + + + for (int i = 0; i < nchar; i++) + if (i < l) + buf[i] = txt[i]; + else + buf[i] = ' '; + + buf[nchar] = 0; + lcd->setCursor(pos, line); + lcd->print(buf); +} +LcdMQTTViewer::LcdMQTTViewer() +{ + panActual = 0; + ivarBuzzer=-1; + topic[0]=0; + 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[MAXTOPICVAR]; + 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,int ibuz) +{ + ivarBuzzer=(byte)ibuz; + vars=v; + lcd =lcdEx; + nchar = digi; + lcd->begin(nchar, lines); + nlineslcd=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; +} + +int LcdMQTTViewer::OnMqtt(char* top, char* payload) +{ + if(strcmp(top,topic)) + return -1; + + int i=0; + int lin=0; + int n=0; + char buf[MAXTOPICVAR*2]; + char imelod[12]; + int nmelod=0; + bool melodia=false; + while(payload[i]) + { + if(payload[i]=='\n') + { + i++; + buf[n]=0; + envia(buf,0,lin); + lin++; + n=0; + } + else if(payload[i]=='$') + { + if(melodia) + { + imelod[nmelod]=0; + melodia=false; + MQTTvalor v; + v.i=atoi(imelod); + + if(ivarBuzzer>=0 && nmelod>0) + vars->SetVal(ivarBuzzer,v); + } + else + { + nmelod=0; + melodia=true; + } + i++; + } + else + { + if(melodia) + imelod[nmelod++]=payload[i++]; + else + buf[n++]=payload[i++]; + } + } + buf[n]=0; + envia(buf,0,lin); + lin++; + for(; linsubscribe(topic); +} diff --git a/DomoEsp_Potencia_v02/LcdMQTTViewer.h b/DomoEsp_Potencia_v02/LcdMQTTViewer.h new file mode 100644 index 0000000..d3e701d --- /dev/null +++ b/DomoEsp_Potencia_v02/LcdMQTTViewer.h @@ -0,0 +1,54 @@ +/*#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[MAXTOPICVAR];//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;//caracteres maximos por linea del lcd + int maxtInfo; + int maxpan;//maximo de pantallas configuradas + int panActual;//pantalla que esta mostrando actualmente + byte nlineslcd;//lineas maximas del lcd + byte ivarBuzzer; + unsigned long tiempo; + unsigned long incre_t; + char topic[MAXSTR];//topic de mqtt Alarma + + MqttVarManager* vars; + + LcdMQTTInfo LcdConf[MAXINFOLCD]; + + LcdMQTTViewer(); + + void inicia(MqttVarManager *vars, LiquidCrystal* lcdEx, int digi, int lines,int ibuz); + void loop();//publica datos variables + int OnMqtt(char* topic, char* payload); + void suscribe(PubSubClient *client_qqtt); + //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_Potencia_v02/MqttDefines.h b/DomoEsp_Potencia_v02/MqttDefines.h new file mode 100644 index 0000000..eb32e6f --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttDefines.h @@ -0,0 +1,28 @@ + +#ifndef MqttDefinesDef +#define MqttDefinesDef 1 +//generales +#define DEBUG_PS 1 +#define CON_WOL 0 +#define CON_LCD 0 + +#define MAXTOPICVAR 32//maximo de caracteres de los topic de las variables + +//vars-------------------- +#define MAXVAR 24//maximo de variables totales +#define MAXSTR 2024//maximo de caracteres para str + +//sens-------------------- +#define MAXSENS 8 +#define MAXINTERRUP 8 +//desencadenadores-------- +#define MAXSTRDESEN 64 +#define MAXDESEN 24 +//class------------------- +class MqttOnVarChangeListenner +{ + public: + virtual void OnVarChange(int ivar)=0; +}; + +#endif diff --git a/DomoEsp_Potencia_v02/MqttDesencadenadorManager.cpp b/DomoEsp_Potencia_v02/MqttDesencadenadorManager.cpp new file mode 100644 index 0000000..0fff170 --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttDesencadenadorManager.cpp @@ -0,0 +1,431 @@ + +#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 (float)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; + else 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 < vy; + } + + case('>'): + 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 + } + } +} +bool 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; + bool res = false; + 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; + p.oper[0] = 0; + if (!p.res || !activo) + { + activo = !p.res; + /* #ifdef DEBUG_PS + + Serial.println("Fin causa sale "); + #endif*/ + p.sigue = false; + break; + } + else + { + activo = false; + res = true; + /*#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; + p.oper[0] = 0; + + } + 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; + p.oper[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; + } + } +#ifdef DEBUG_PS + + Serial.println("MqttDesencadenador::Exe fin"); +#endif + return res; +} +//******************************************************************* +MqttDesencadenadorArray::MqttDesencadenadorArray() +{ + n = 0; +} + +MqttDesencadenador* MqttDesencadenadorArray::Get(int i) +{ + return &(data[i]); +} + +int MqttDesencadenadorArray::Add(MqttDesencadenador* var) +{ + data[n] = *var; + strcpy(data[n].expresion, var->expresion); + 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) + { +#ifdef DEBUG_PS + Serial.println("MqttDesencadenador::inicia como listenner"); +#endif + 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 + bool revisa = true; + while (revisa) + { + revisa = false; + for (int i = 0; i < des.n; i++) + { + if (des.Get(i)->Exe(vars)) + revisa = true; + } + //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_Potencia_v02/MqttDesencadenadorManager.h b/DomoEsp_Potencia_v02/MqttDesencadenadorManager.h new file mode 100644 index 0000000..6f499ca --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttDesencadenadorManager.h @@ -0,0 +1,116 @@ + +#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[MAXSTRDESEN];//"{1}=1 -> !{2} " + bool activo;//se desactivan automaticamente cuando se cumple la condicion y se vuelve activar cuando deja de cumplirse + + MqttDesencadenador(); + + bool Exe(MqttVarManager *vars); + + //auxiliar---------------- + void procesaVar(MqttExeParam *p);//recoge expresion de variable o float + void procesaOper(MqttExeParam *p);//recoge operador + + 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);//evalua operador + + void ExeEfecto(MqttVarManager *vars, char *oper, char*x, char*y);//ejecuta efecto + + float GetValue(char *ivar, MqttVarManager *vars); +}; + +class MqttDesencadenadorArray +{ + public: + MqttDesencadenador data[MAXDESEN]; + 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_Potencia_v02/MqttSensManager.cpp b/DomoEsp_Potencia_v02/MqttSensManager.cpp new file mode 100644 index 0000000..e3998e8 --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttSensManager.cpp @@ -0,0 +1,618 @@ +//#include //este para esp8266 + + + + + + +#include "MqttSensManager.h" +#include "MqttVarManager.h" +#include "MqttUtiles.h" + +MqttSensor::MqttSensor() +{ + ivar=-1; + flags=0; +} +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) +{ + if (i < 0 || i >= n) + return NULL; + 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) +{ + return sens.Get(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); + vars->Get(s.ivar)->val.i = defautlValor; +} +void MqttSensManager::AddDoutPulsador(int pin, char* topic, bool defautlValor, int seg) +{ + MqttSensor s; + s.tipo = (int)MqttSensor::SENS_DIGI_OUT_PULSANTE; + s.pin = pin; + s.ivar = vars->AddVar((byte)(MqttVar::IN_VAR | MqttVar::OUT_VAR | MqttVar::ACCION_VAR), topic); + s.ie.pul.t = seg * 1000; + s.ie.pul.vd = defautlValor; + sens.Add(&s); + pinMode(s.pin, OUTPUT); + digitalWrite(s.pin, defautlValor); + vars->Get(s.ivar)->val.i = defautlValor; +} +void MqttSensManager::AddBuzz(int pin, char* topic) +{ + MqttSensor s; + s.tipo=(int)MqttSensor::SENS_BUZZ_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); +} +void MqttSensManager::AddMelodia(char* m) +{ + if(buzz) + { + buzz->Add(m); + } +} +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::AddDinRetardOff(int pin, int seg,char* topic) +{ + MqttSensor s; + s.tipo=(int)MqttSensor::SENS_DIGI_IN; + s.pin=pin; + s.flags=MqttSensor::FLAG_RETARD_OFF; + s.ie.retard.r=seg*1000; + s.ivar=vars->AddVar((byte)(MqttVar::IN_VAR|MqttVar::ACCION_VAR),topic); + s.ie.retard.val=vars->Get(s.ivar)->val.i; + int isen=sens.Add(&s); + pinMode(s.pin, INPUT); + + ConfiguraInterrupcion(isen); +} +void MqttSensManager::AddDinRetardOn(int pin, int seg,char* topic) +{ + MqttSensor s; + s.tipo=(int)MqttSensor::SENS_DIGI_IN; + s.pin=pin; + s.flags=MqttSensor::FLAG_RETARD_ON; + s.ie.retard.r=seg*1000; + s.ivar=vars->AddVar((byte)(MqttVar::IN_VAR|MqttVar::ACCION_VAR),topic); + s.ie.retard.val=vars->Get(s.ivar)->val.i; + 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); + MQTTvalor val; + 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; + } + val.f = t; + vars->SetVal(s->ivar, val); + //v->val.f=t; + val.f = h; + vars->SetVal(s->ie.dht.ivarH, val); + //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); + val.f = s->ie.bmp.p->readTemperature(); + vars->SetVal(s->ivar, val); + val.f = s->ie.bmp.p->readPressure(); + vars->SetVal(s->ie.bmp.ivarP, val); + val.f = s->ie.bmp.p->readAltitude(); + vars->SetVal(s->ie.bmp.ivarA, val); + /* + 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) + val.f =100.*((float)(1024- analogRead(s->pin)))/1024; + else + val.f =100.*((float)(analogRead(s->pin)))/1024; + vars->SetVal(s->ivar, val); + break; + } + /* case((int)MqttSensor::SENS_DIGI_IN): + { + 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) +{ + MqttSensor *s = sens.Ivar2Sen(ivar); + if(s==NULL) + return; + MqttVar *v=vars->Get(ivar); + #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; + } + case((int)MqttSensor::SENS_DIGI_OUT_PULSANTE): + { + if ((v->val.i>0) != s->ie.pul.vd) + { +#ifdef DEBUG_PS + Serial.println("Sens::OnVarChangeSensor Dout Pulsante cambiado"); +#endif + if (s->flags & MqttSensor::FLAG_NEG) + digitalWrite(s->pin, (1 - v->val.i)); + else + digitalWrite(s->pin, v->val.i); + delay(s->ie.pul.t); + v->val.i = 1 - v->val.i; + if (s->flags & MqttSensor::FLAG_NEG) + digitalWrite(s->pin, (1 - v->val.i)); + else + digitalWrite(s->pin, v->val.i); + vars->OnChange(ivar, true); + } + break; + } + case((int)MqttSensor::SENS_BUZZ_OUT): + { + #ifdef DEBUG_PS + Serial.println("Sens::OnVarChangeSensor buz cambiado"); + #endif + if(v->val.i>0 && buzz) + { + buzz->Toca( s->pin, v->val.i-1); + v->val.i=0; + vars->OnChange(ivar, true); + } + + break; + } + default: + break; + } + #ifdef DEBUG_PS + Serial.println("OnVarChangeSensor fin"); + #endif +} + +void MqttSensManager::procesaInterrupciones() +{ + if(MqttChangeInterrup) + { + noInterrupts(); + MqttChangeInterrup=false; + interrupts(); + for(int i=0; iGet(s->ivar); + byte val=digitalRead(s->pin); + if(s->flags & MqttSensor::FLAG_RETARD_OFF && v->val.i!=val && val==0) + { + #ifdef DEBUG_PS + Serial.println("Se aplica retardo al off"); + #endif + s->ie.retard.val=val; + s->ie.retard.t=millis(); + } + else if(s->flags & MqttSensor::FLAG_RETARD_ON && v->val.i!=val && val!=0) + { + #ifdef DEBUG_PS + Serial.println("Se aplica retardo al on"); + #endif + s->ie.retard.val=val; + s->ie.retard.t=millis(); + } + else + { + ProcesaSenInterrupciones(ind_interrup[i]); + } + } + } + } + + + //comprueba sensores retrasados + for(int i=0; iflags & (MqttSensor::FLAG_RETARD_OFF | MqttSensor::FLAG_RETARD_ON))) + continue; + MqttVar *v=vars->Get(s->ivar); + if(v->val.i==s->ie.retard.val) + continue; + if(!MqttUtiles::pasa_incre(&s->ie.retard.t, s->ie.retard.r)) + continue; + #ifdef DEBUG_PS + Serial.println("Se detecta cambio en sensor retardado"); + #endif + ProcesaSenInterrupciones(ind_interrup[i]); + } +} +void MqttSensManager::ProcesaSenInterrupciones(int isen) +{ + MqttSensor* s=sens.Get(isen); + MqttVar *v=vars->Get(s->ivar); + byte val=digitalRead(s->pin); + switch((int)s->tipo) + { + case((int)MqttSensor::SENS_DIGI_IN): + { + //lee y llama a cambio si es necesario + + if(val!=v->val.i) + { + v->val.i=val; + vars->OnChange(s->ivar, true); + } + 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, true); + } + + //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; + MqttChange_ind_interrup[i]=true; + } + void MqttSensManager::ConfiguraInterrupcion(int isen) + { + #ifdef DEBUG_PS + + Serial.println("Configurando interrupcion"); + #endif + MqttChange_ind_interrup[n_inter]=false; + 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_Potencia_v02/MqttSensManager.h b/DomoEsp_Potencia_v02/MqttSensManager.h new file mode 100644 index 0000000..b2810f9 --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttSensManager.h @@ -0,0 +1,220 @@ + +#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 SonidoBuzzer; +//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; +}; +struct SensRetardado +{ + unsigned long t;//ultimo tiempo en el que se recivio el cambio + unsigned long r;//retardo + byte val;//valor actual a cambiar +}; +struct InfoPulsante +{ + unsigned long t;//puntero a variable humedad + bool vd;//valor por defecto; +}; +union MqttInfEx//informacion extra segun sensor +{ + DhtExt dht; + BmpExt bmp; + SensRetardado retard; + InfoPulsante pul; + //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 + SENS_BUZZ_OUT,//sensor digital out con buzzer conectado + SENS_DIGI_OUT_PULSANTE,//pensado para hacer efecto pulsador + //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) + FLAG_RETARD_OFF=0X04,//indica que el sensor tiene un off con efecto retardado configurable + FLAG_RETARD_ON=0X08//indica que el sensor tiene un on con efecto retardado configurable + + }; + + + 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 + SonidoBuzzer *buzz; + 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, ...) + void AddDinRetardOff(int pin, int seg, char* topic);//añade variable con retardo al apagado (especial sensores de presencia) + void AddDinRetardOn(int pin, int seg, char* topic);//añade variable con retardo al apagado (especial sensores de presencia) + + void AddDoutPulsador(int pin, char* topic, bool defautlValor, int seg); + + //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 ... + void AddBuzz(int pin, char* topic); + void AddMelodia(char* m); + //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); + void ProcesaSenInterrupciones(int isen); + + + virtual void OnVarChange(int ivar); + +}; +#ifndef pMqttSensManagerdef +#define pMqttSensManagerdef 1 +static volatile bool MqttChange_ind_interrup[MAXINTERRUP]; +static volatile bool MqttChangeInterrup=false; +static MqttSensManager* pMqttSensManager; +#endif + +/* +*/ +#endif diff --git a/DomoEsp_Potencia_v02/MqttUtiles.cpp b/DomoEsp_Potencia_v02/MqttUtiles.cpp new file mode 100644 index 0000000..dc639b5 --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttUtiles.cpp @@ -0,0 +1,346 @@ +#include + + + +#include +#include + +#include +#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, char *idArdu) +{ + espClient= espclient; + strcpy(nred, ssid); + strcpy(pass, key); + strcpy(idArduino,idArdu); + conecta(); + + //return WiFi.status() == WL_CONNECTED; +} +bool WifiManager::conecta() +{ + #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 + if(WiFi.status() != WL_CONNECTED) + return false; + + //ota---------------------------------- + // Port defaults to 8266 + // ArduinoOTA.setPort(8266); + + // Hostname defaults to esp8266-[ChipID] + ArduinoOTA.setHostname(idArduino); + + // No authentication by default + // ArduinoOTA.setPassword("admin"); + + // Password can be set with it's md5 value as well + // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 + // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3"); + + ArduinoOTA.onStart([]() { + String type; + if (ArduinoOTA.getCommand() == U_FLASH) { + type = "sketch"; + } else { // U_FS + type = "filesystem"; + } + #ifdef DEBUG_PS + // NOTE: if updating FS this would be the place to unmount FS using FS.end() + Serial.println("Start updating " + type); + #endif + }); + ArduinoOTA.onEnd([]() { + Serial.println("\nEnd"); + }); + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + #ifdef DEBUG_PS + Serial.printf("Progress: %u%%\r", (progress / (total / 100))); + #endif + }); + ArduinoOTA.onError([](ota_error_t error) { + #ifdef DEBUG_PS + Serial.printf("Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) { + Serial.println("Auth Failed"); + } else if (error == OTA_BEGIN_ERROR) { + Serial.println("Begin Failed"); + } else if (error == OTA_CONNECT_ERROR) { + Serial.println("Connect Failed"); + } else if (error == OTA_RECEIVE_ERROR) { + Serial.println("Receive Failed"); + } else if (error == OTA_END_ERROR) { + Serial.println("End Failed"); + } + #endif + }); + ArduinoOTA.begin(); + #ifdef DEBUG_PS + Serial.println("Ready"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + #endif + return true; +} +bool WifiManager::loop() +{ + if((WiFi.status() == WL_CONNECTED)) + { + ArduinoOTA.handle(); + return true; + } + #ifdef DEBUG_PS + Serial.println("Fallo de conexion, se reinicia arduino"); + #endif + ESP.reset(); + return false; +} +//************************************************************************************************************************************************** +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; + + } + #ifdef DEBUG_PS + Serial.println("Fallo de conexion, se reinicia arduino"); + #endif + ESP.reset(); + return false; +} +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[MAXTOPICVAR]; + i= MAXTOPICVAR-1; + 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; +} +//************************************************************************************************************************************************** +MelodiaBuzzer::MelodiaBuzzer() +{ + melodia[0]=0; +} +int MelodiaBuzzer::st2nota(char st) +{ + switch(st) + { + case 'd': + return 262; + case 'r': + return 294; + case 'm': + return 330; + case 'f': + return 349; + case 's': + return 392; + case 'l': + return 440; + case 'i': + return 494; + case 'D': + return 277; + case 'R': + return 311; + case 'M': + return 345; + case 'F': + return 350; + case 'S': + return 415; + case 'L': + return 466; + case 'I': + return 554,36; + default: + return 0; + } +} +int MelodiaBuzzer::str2t(char* st, int *t) +{ + char buf[8]; + int n=0; + int i; + while(st[i]<='9' && st[i]>='0') + { + buf[n++]=st[i++]; + } + buf[n]=0; + (*t)=atoi(buf); + return i; +} +void MelodiaBuzzer::Toca(int pin) +{ + int i=0; + int h=0, t=0; + + while (melodia[i]) + { + h=st2nota(melodia[i]); + i++; + t=0; + i+=str2t(&melodia[i], &t); + if(h>0) + tone(pin, h); + else + noTone(pin); + delay(t); + } +} +//************************************************* +SonidoBuzzer::SonidoBuzzer() +{ + n=0; +} + +void SonidoBuzzer::Toca(int pin, int imel) +{ + if (imel<0 || imel>=n) + return; + mel[imel].Toca(pin); +} + +int SonidoBuzzer::Add(char* melo) +{ + strcpy(mel[n].melodia, melo); + return n++; +} diff --git a/DomoEsp_Potencia_v02/MqttUtiles.h b/DomoEsp_Potencia_v02/MqttUtiles.h new file mode 100644 index 0000000..da0541f --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttUtiles.h @@ -0,0 +1,155 @@ +#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]; + char idArduino[32]; + WiFiClient *espClient; + + WifiManager(); + bool conecta(); + void inicia( WiFiClient *espClient, char *ssid, char* key, char *idArduino); + 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[32]; + 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]); + }; +}; + +class MelodiaBuzzer +{ + public: + //melodia se compone de notas (primera letra y tiempo de duracion) silecio es # + char melodia[64]; + MelodiaBuzzer(); + int st2nota(char st); + int str2t(char* st, int *t); + + void Toca(int pin); +}; + +class SonidoBuzzer +{ + public: + MelodiaBuzzer mel[4]; + int n; + SonidoBuzzer(); + void Toca(int pin, int melodia); + int Add(char* melodia); +}; +#endif diff --git a/DomoEsp_Potencia_v02/MqttVarManager.cpp b/DomoEsp_Potencia_v02/MqttVarManager.cpp new file mode 100644 index 0000000..1285ceb --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttVarManager.cpp @@ -0,0 +1,434 @@ +//#include //este para esp8266 +#include +#include "MqttDefines.h" +#include "MqttVarManager.h" +#include "MqttUtiles.h" +#include +#include + +MqttTopicAttay::MqttTopicAttay() +{ + n=0; + nst=0; + def[0] = 0; +} + +char* MqttTopicAttay::Get(int i) +{ + if (i < 0 || i >= n) + return def; + return &str[(ind[i])]; +} + +int MqttTopicAttay::Get(char *topic) +{ + for(int i=0; i(int)0) + { + return i; + } + i=n; + if (n >= MAXVAR) + return-1; + n=n+1; + ind[i]=nst; + nst=nst+strlen(topic)+1; + if (nst > MAXSTR) + { + n--; + return-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) +{ + if (i < 0 || i >= n) + { +#ifdef DEBUG_PS + Serial.print("qttVarArray:: Get var no encontrada: "); + Serial.print(i); + Serial.print(" n: "); + Serial.println(i); + +#endif + return NULL; + } + return &(data[i]); +} + +MqttVar* MqttVarArray::GetVar(int itopic) +{ + for(int i=0; i= MAXVAR) + { +#ifdef DEBUG_PS + Serial.print("MqttVarArray::Add max var alcanzado: "); + Serial.println(n); +#endif + return -1; + } + + data[n]=*var; + n++; + return n-1; +} +//******************************************************************* + +MqttVarManager::MqttVarManager() +{ + + tiempo_var=0; + SetTimeRefres(30); + nListenner=0; + 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; + val.f=atof(payload); + + } + else + { + int ii=v->val.i; + val.i=atoi(payload); + } + SetVal(i, val); + break;//suponemos solo una variable con el mismo topic + } + } + + //if(res>=0) + // OnChange(res, isSet); + 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[MAXTOPICVAR]; + char buffer_p[MAXTOPICVAR]; + MqttVar* v=vars->Get(ivar); + if (v->flags & MqttVar::INTERNAL_VAR) + return; + else if(v->flags & MqttVar::CHANGE_VAR) + { + + sprintf(buffer_t, "%s/set",topics->Get(v->topic)); + #ifdef DEBUG_PS + Serial.print("Publica /set var: "); + Serial.println(buffer_t); + #endif + } + else//in var + { + + sprintf(buffer_t, "%s/get",topics->Get(v->topic)); + #ifdef DEBUG_PS + Serial.print("Publica get var: "); + Serial.println(buffer_t); + #endif + } + //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[MAXTOPICVAR]; + 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::AddPrivadaVarFloat(char* topic) +{ + return AddVar((byte)(MqttVar::PRIV_VAR | MqttVar::FLOAT_VAR | MqttVar::CHANGE_VAR | MqttVar::ACCION_VAR), topic); +} +int MqttVarManager::AddPrivadaVarInt(char* topic) +{ + return AddVar((byte)(MqttVar::PRIV_VAR | MqttVar::CHANGE_VAR | MqttVar::ACCION_VAR), topic); +} +int MqttVarManager::AddInternalVarFloat( char* topic) +{ + return AddVar((byte)(MqttVar::PRIV_VAR|MqttVar::FLOAT_VAR| MqttVar::CHANGE_VAR|MqttVar::ACCION_VAR | MqttVar::INTERNAL_VAR),topic); +} +int MqttVarManager::AddInternalVarInt( char* topic) +{ + return AddVar((byte)(MqttVar::PRIV_VAR| MqttVar::CHANGE_VAR|MqttVar::ACCION_VAR | MqttVar::INTERNAL_VAR),topic); +} +int MqttVarManager::AddVirtualOutVarInt( char* topic) +{ + return AddVar((byte)(MqttVar::IN_VAR|MqttVar::OUT_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, bool publica) +{ + #ifdef DEBUG_PS + Serial.println("MqttVarManager::OnChange"); + #endif + + if(publica) + { + 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, true); +} +void MqttVarManager::SetVal(int ivar,MQTTvalor val) +{ + #ifdef DEBUG_PS + + Serial.print("MqttVarManager::SetVal int i: "); + Serial.print( val.i); + Serial.print(" f: "); + Serial.println( val.f); + #endif + MqttVar* v=vars->Get(ivar); + bool cambia = false; + if (v->flags & MqttVar::FLOAT_VAR) + cambia = val.f != v->val.f; + else + cambia = val.i != v->val.i; + + v->val=val; + if(cambia) + OnChange(ivar, true); +} diff --git a/DomoEsp_Potencia_v02/MqttVarManager.h b/DomoEsp_Potencia_v02/MqttVarManager.h new file mode 100644 index 0000000..c3da479 --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttVarManager.h @@ -0,0 +1,129 @@ +/*#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 +{ + char def[1]; + 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) (publica cada x tiempo) + 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 onchange si se le llama como publicar) + 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 + INTERNAL_VAR = 0x80//no publica + }; + + 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 AddVirtualOutVarInt( char*topic); + int AddInternalVarFloat( char*topic); + int AddInternalVarInt( char*topic); + int AddPrivadaVarFloat(char* topic); + int AddPrivadaVarInt(char* topic); + void PublicaVars(); + void PublicaVar(int ivar); + void OnChange(int ivar, bool publica); + + void ResetVolatileVar(); + void InvierteVar(int ivar); + void SetVal(int ivar,MQTTvalor val); +}; + +/* +*/ +#endif diff --git a/DomoEsp_Potencia_v02/MqttWOLManager.cpp b/DomoEsp_Potencia_v02/MqttWOLManager.cpp new file mode 100644 index 0000000..1077eee --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttWOLManager.cpp @@ -0,0 +1,36 @@ + +#include +#include +#include "MqttWOLManager.h" + +MqttWOLManager::MqttWOLManager() +{ + topic[0]=0; +} +void MqttWOLManager::inicia(WakeOnLan *pwol) +{ + wol=pwol; +} +void MqttWOLManager::loop() +{ + +} +int MqttWOLManager::OnMqtt(char* top, char* payload) +{ + if(strcmp(top,topic)) + return -1; + + wol->sendMagicPacket(payload); // Send Wake On Lan packet with the above MAC address. Default to port 9. + #ifdef DEBUG_PS + Serial.print("Enviado wol a: "); + Serial.println(payload); + #endif + // WOL.sendMagicPacket(MACAddress, 7); // Change the port number + return 1; +} +void MqttWOLManager::suscribe(PubSubClient *client_qqtt) +{ + if(!topic[0]) + return; + client_qqtt->subscribe(topic); +} diff --git a/DomoEsp_Potencia_v02/MqttWOLManager.h b/DomoEsp_Potencia_v02/MqttWOLManager.h new file mode 100644 index 0000000..8b7c10d --- /dev/null +++ b/DomoEsp_Potencia_v02/MqttWOLManager.h @@ -0,0 +1,22 @@ + +#ifndef MqttWOLManagerdef +#define MqttWOLManagerdef 1 +#include "MqttDefines.h" +class WakeOnLan; + +class MqttWOLManager +{ + WakeOnLan* wol; + public: + char topic[MAXSTR];//topic para llamada wol + + MqttWOLManager(); + + + void inicia(WakeOnLan* pwol); + void loop();//publica datos variables + int OnMqtt(char* topic, char* payload); + void suscribe(PubSubClient *client_qqtt); + +}; +#endif diff --git a/DomoEsp_Potencia_v02/config_rf.h b/DomoEsp_Potencia_v02/config_rf.h new file mode 100644 index 0000000..3da04b4 --- /dev/null +++ b/DomoEsp_Potencia_v02/config_rf.h @@ -0,0 +1,657 @@ +//parametros configurables************************************************* +#define DEBUG_PS 1//Descomentar para debug +#define CON_LCD 0 +#define CON_WOL 0 + //va por 16 + class CocinapRUBDomoConfig: public DomoConfig +{ + public: + CocinapRUBDomoConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + strcpy(ideEsp,"Esp8266_P");//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=5;//tiempo de refresco en segundos de los sensores + } + //configuracion de sensores--------------------------------- + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttWOLManager* wol, MqttDesencadenadorManager *des) + { + sens->AddHDT22(D4, "casa/cocina");//01 + sens->AddDinRetardOff(D5, 60,"casa/p/mov");//2 + int mov=2; + sens->AddAnalogIn(0, "casa/p/luz",true);//3 + int luz=3; + sens->AddDin( D1, "casa/p/inter");//4 + int interr=4; + sens->AddDout(D2, "casa/p/lam", false);//5 + int lam=5; + int lauto= vars->AddVirtualOutVarInt( "casa/p/luzAuto");//variable privada + char st[64]; + + //Efecto Pulsadores + sprintf(st,"{%d}>0 -> !{%d} ",interr,lam);//accion interruptor + des->AddDes(st); + sprintf(st,"{%d}<1 -> !{%d} ",interr,lam);//accion interruptor + des->AddDes(st); + + sprintf(st,"{%d}<1&{%d}>0&{%d}=1 -> {%d}=0 ",mov,lauto,lam,lam);//apaga luz si no hay nadie + des->AddDes(st); + sprintf(st,"{%d}>20&{%d}>0&{%d}>0 -> {%d}=1 ",luz,mov,lauto,lam);//enciende luz si hay presencia y esta oscuro + des->AddDes(st); + + } +}; +class ActDomoConfig: public DomoConfig +{ + public: + ActDomoConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + + strcpy(ideEsp,"Esp8266_pruebas");//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=5;//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, MqttWOLManager* wol, 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->AddBuzz(int pin, char* topic); + */ + + sens->AddDinRetardOn(D1,5,"casa/p/pul"); + sens->AddDout(D5,"casa/p/led", true); + //sens->AddHDT22(D4, "casa/desp"); + //sens->AddBuzz(D0, "casa/p/buz"); + //sens->AddMelodia("m200#100d200#0"); + //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 lent= vars->AddInternalVarInt( "casa/Salon/LEnt"); + + int pul1= vars->AddInternalVarInt( "casa/Salon/pul1"); + int pul2= vars->AddInternalVarInt( "casa/Salon/pul2"); + int pul3= vars->AddInternalVarInt( "casa/Salon/pul3"); + int pulIall= vars->AddInternalVarInt( "casa/Salon/intAll"); + int pulAll= vars->AddInternalVarInt( "casa/Salon/pulAll"); + //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[64]; + //Efecto Interruptor----- + sprintf(st,"{%d}<1 -> !{%d} ",0,1);//terminar en espacios y separar operadores (no puede estar 2 operadores juntos) + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",0,1);//terminar en espacios + des->AddDes(st); + /* + sprintf(st,"{%d}>0 -> {%d}=1 & {%d}=1 & {%d}=1 ",pulIall,lamb,lchim, lent);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}<1 -> {%d}=0 & {%d}=0 & {%d}=0 ",pulIall,lamb,lchim, lent);//terminar en espacios + des->AddDes(st); + //Efecto Pulsadores + sprintf(st,"{%d}>0 -> !{%d} ",pulAll,pulIall);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul1,lamb);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul2,lchim);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul3,lent);//terminar en espacios + des->AddDes(st); + /* */ + } +}; +class SalonHome: public DomoConfig +{ + public: + SalonHome() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + + strcpy(ideEsp,"Esp8266_SalomHome");//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=5;//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, MqttWOLManager* wol, 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->AddBuzz(int pin, char* topic); + */ + sens->AddDoutPulsador(D4, "casa/Salon/ordeTele", true, 1); + sens->AddDoutPulsador(D2, "casa/Salon/router", true, 1); + + + sens->AddDout(D3,"casa/Salon/auxiliar", true); + int aux=2; + sens->AddDout(D1,"casa/Salon/equipoMusica", true); + int equipo=3; + sens->AddDin( D5,"casa/Salon/pulEquipoM"); + int pequipo=4; + sens->AddDin( D6, "casa/Salon/pulAux"); + int paux=5; + //variables---------------------------------------------------- + + //desencadenaores---------- + char st[64]; + //Efecto Interruptor----- + + sprintf(st,"{%d}>0 -> !{%d} ",pequipo,equipo);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",paux,aux);//terminar en espacios + des->AddDes(st); + + } +}; +class PulSalonPruebConfig: public DomoConfig +{ + public: + PulSalonPruebConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + + strcpy(ideEsp,"Esp8266_pulSalonPrueb");//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=5;//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, MqttWOLManager* wol, MqttDesencadenadorManager *des) + { + //sensores-------------------------------------------------------- + + //sens->AddHDT22(D4, "casa/desp"); + // sens->AddDout(D1, "casa/p/LEnt", true); + sens->AddDout(D7, "casa/p/LEnt", true); + sens->AddDin( D1,"casa/p/pul1"); + sens->AddDin( D2, "casa/p/pul2"); + sens->AddDin( D3, "casa/p/pul3"); + sens->AddDin( D4,"casa/p/pulAll"); + } +}; +class AutomatismosDomoConfig: public DomoConfig +{ + public: + AutomatismosDomoConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + + strcpy(ideEsp,"Esp8266_autom");//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=5;//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, MqttWOLManager* wol, 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 lent= vars->AddInternalVarInt( "casa/Salon/LEnt"); + + int pul1= vars->AddInternalVarInt( "casa/Salon/pul1"); + int pul2= vars->AddInternalVarInt( "casa/Salon/pul2"); + int pul3= vars->AddInternalVarInt( "casa/Salon/pul3"); + int pulIall= vars->AddInternalVarInt( "casa/Salon/intAll"); + int pulAll= vars->AddInternalVarInt( "casa/Salon/pulAll"); + //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[64]; + //Efecto Interruptor----- + sprintf(st,"{%d}>0 -> {%d}=1 & {%d}=1 & {%d}=1 ",pulIall,lamb,lchim, lent);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}<1 -> {%d}=0 & {%d}=0 & {%d}=0 ",pulIall,lamb,lchim, lent);//terminar en espacios + des->AddDes(st); + //Efecto Pulsadores + sprintf(st,"{%d}>0 -> !{%d} ",pulAll,pulIall);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul1,lamb);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul2,lchim);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul3,lent);//terminar en espacios + des->AddDes(st); + + } +}; + +class PulSalonConfig: public DomoConfig +{ + public: + PulSalonConfig() + { + //CON LCD Y WOL + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + + strcpy(ideEsp,"Esp8266_pulSalon");//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=5;//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, MqttWOLManager* wol, 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->AddDinRetardOff( D1, 0,"casa/Salon/pul1"); + sens->AddDinRetardOff( D2, 0, "casa/Salon/pul2"); + sens->AddDinRetardOff( D5, 0, "casa/Salon/pul3"); + sens->AddDinRetardOff( D6, 0,"casa/Salon/pulAll"); + } +}; +class DespachoDomoConfig: public DomoConfig +{ + public: + DespachoDomoConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + + strcpy(ideEsp,"Esp8266_Despacho");//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=5;//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,MqttWOLManager* wol, MqttDesencadenadorManager *des) + { + //sensores-------------------------------------------------------- + sens->AddHDT22(D4, "casa/desp"); + sens->AddAnalogIn(0, "casa/desp/luz",true); + sens->AddBuzz(D7, "casa/des/buz"); + + sens->AddMelodia("m200#100d200#0");//titu + sens->AddMelodia("d200#100d200#100d200#100f200#100l300#0"); + + //variables---------------------------------------------------- + int temCoci= vars->AddInternalVarFloat( "casa/cocina/t");//variable privada + int hcocina= vars->AddInternalVarFloat( "casa/cocina/h");//variable privada + int temExt= vars->AddInternalVarFloat( "casa/ext/t");//variable privada + int hExt= vars->AddInternalVarFloat( "casa/ext/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(hcocina,"H coci: %s",1,1); + lcd->add(temExt,"T Ext: %s",0,2); + lcd->add(hExt,"H Ext: %s",1,2); + strcpy(lcd->topic,"casa/desp/msg"); + strcpy(wol->topic,"casa/wol"); + } +}; +class CocinaDomoConfig: public DomoConfig +{ + public: + CocinaDomoConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + strcpy(ideEsp,"Esp8266_cocina");//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=5;//tiempo de refresco en segundos de los sensores + } + //configuracion de sensores--------------------------------- + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttWOLManager* wol, MqttDesencadenadorManager *des) + { + sens->AddHDT22(D4, "casa/cocina");//01 + sens->AddDinRetardOff(D5, 60,"casa/cocina/mov");//2 + int mov=2; + sens->AddAnalogIn(0, "casa/cocina/luz",true);//3 + int luz=3; + sens->AddDin( D1, "casa/cocina/inter");//4 + sens->AddDout(D2, "casa/cocina/lam", false);//5 + int lam=5; + int lauto= vars->AddVirtualOutVarInt( "casa/cocina/luzAuto"); + char st[64]; + + //Efecto Pulsadores + + sprintf(st,"{%d}>0 -> !{%d} ",4,lam);//accion interruptor + des->AddDes(st); + + sprintf(st,"{%d}<1 -> !{%d} ",4,lam);//accion interruptor + des->AddDes(st); + + sprintf(st,"{%d}<1&{%d}>0&{%d}=1 -> {%d}=0 ",mov,lauto,lam,lam);//apaga luz si no hay nadie + des->AddDes(st); + sprintf(st,"{%d}<20&{%d}>0&{%d}>0 -> {%d}=1 ",luz,mov,lauto,lam);//enciende luz si hay presencia y esta oscuro + des->AddDes(st); + + } +}; +class SalonDomoConfig: public DomoConfig +{ + public: + SalonDomoConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + strcpy(ideEsp,"Esp8266_salon");//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=5;//tiempo de refresco en segundos de los sensores + } + //configuracion de sensores--------------------------------- + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttWOLManager* wol, MqttDesencadenadorManager *des) + { + sens->AddHDT22(D4, "casa/Salon");//01 + sens->AddDinRetardOff(D5, 60,"casa/Salon/mov");//2 + sens->AddAnalogIn(0, "casa/Salon/luz",true);//3 + + //variables---------------------------------------------------- + //variables para pulsadores--------------------------- + int lamb= vars->AddPrivadaVarInt( "casa/Salon/LAmb"); + int lchim= vars->AddPrivadaVarInt( "casa/Salon/LChime"); + int lent= vars->AddPrivadaVarInt( "casa/Salon/LEnt"); + + int pul1= vars->AddInternalVarInt( "casa/Salon/pul1"); + int pul2= vars->AddInternalVarInt( "casa/Salon/pul2"); + int pul3= vars->AddInternalVarInt( "casa/Salon/pul3"); + int pulIall= vars->AddInternalVarInt( "casa/Salon/intAll"); + int pulAll= vars->AddInternalVarInt( "casa/Salon/pulAll"); +/* + int cociMov= vars->AddInternalVarInt( "casa/cocina/mov"); + int cociLuz= vars->AddInternalVarInt( "casa/cocina/luz"); + int cociLam= vars->AddInternalVarInt( "casa/cocina/lam"); + int cociAuto= vars->AddInternalVarInt("casa/cocina/luzAuto"); + */ + //variables para pulsadores cocina---------------------------- + + //desencadenaores---------- + char st[64]; + //Efecto Interruptor----- + sprintf(st,"{%d}>0 -> {%d}=1 & {%d}=1 & {%d}=1 ",pulIall,lamb,lchim, lent);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}<1 -> {%d}=0 & {%d}=0 & {%d}=0 ",pulIall,lamb,lchim, lent);//terminar en espacios + des->AddDes(st); + //Efecto Pulsadores + sprintf(st,"{%d}>0 -> !{%d} ",pulAll,pulIall);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul1,lamb);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul2,lchim);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul3,lent);//terminar en espacios + des->AddDes(st); +/* + //variablaes cocina + sprintf(st,"{%d}<1&{%d}>0&{%d}=1 -> {%d}=0 ",cociMov,cociAuto,cociLam,cociLam);//apaga luz si no hay nadie + des->AddDes(st); + sprintf(st,"{%d}<20&{%d}>0&{%d}>0 -> {%d}=1 ",cociLuz,cociMov,cociAuto,cociLam);//enciende luz si hay presencia y esta oscuro + des->AddDes(st); + */ + + } +}; +class ExteriorDomoConfig: public DomoConfig +{ + public: + ExteriorDomoConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + strcpy(ideEsp,"Esp8266_Ext");//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=5;//tiempo de refresco en segundos de los sensores + } + //configuracion de sensores--------------------------------- + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttWOLManager* wol, MqttDesencadenadorManager *des) + { + sens->AddHDT22(D2, "casa/ext"); + sens->AddAnalogIn(0, "casa/ext/lluvia",true); + } +}; + +class SalonPruebaConfig: public DomoConfig +{ + public: + SalonPruebaConfig() + { + velocidadPortSerie=115200; + strcpy(ssidWifi,"Idhun");//nombre wifi + strcpy(keyWifi,"Ardileorca1234.");//key wifi + strcpy(ideEsp,"Esp8266_salonPruebas");//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=5;//tiempo de refresco en segundos de los sensores + } + //configuracion de sensores--------------------------------- + virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttWOLManager* wol, MqttDesencadenadorManager *des) + { + //sens->AddHDT22(D4, "casa/Prueba");//01 + //sens->AddDinRetardOff(D5, 60,"casa/Prueba/mov");//2 + //sens->AddAnalogIn(0, "casa/Prueba/luz",true);//3 + + //variables---------------------------------------------------- + //variables para pulsadores--------------------------- + int lamb= vars->AddPrivadaVarInt( "casa/Prueba/LAmb"); + int lchim= vars->AddPrivadaVarInt( "casa/Prueba/LChime"); + int lent= vars->AddPrivadaVarInt( "casa/Prueba/LEnt"); + + int pul1= vars->AddInternalVarInt( "casa/Prueba/pul1"); + int pul2= vars->AddInternalVarInt( "casa/Prueba/pul2"); + int pul3= vars->AddInternalVarInt( "casa/Prueba/pul3"); + int pulIall= vars->AddInternalVarInt( "casa/Prueba/intAll"); + int pulAll= vars->AddInternalVarInt( "casa/Prueba/pulAll"); + + //variables para pulsadores cocina---------------------------- + + //desencadenaores---------- + char st[64]; + //Efecto Interruptor----- + sprintf(st,"{%d}>0 -> {%d}=1 & {%d}=1 & {%d}=1 ",pulIall,lamb,lchim, lent);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}<1 -> {%d}=0 & {%d}=0 & {%d}=0 ",pulIall,lamb,lchim, lent);//terminar en espacios + des->AddDes(st); + //Efecto Pulsadores + sprintf(st,"{%d}>0 -> !{%d} ",pulAll,pulIall);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul1,lamb);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul2,lchim);//terminar en espacios + des->AddDes(st); + sprintf(st,"{%d}>0 -> !{%d} ",pul3,lent);//terminar en espacios + des->AddDes(st); + } +}; + +//configuracion que se usara-------------------------- +SalonDomoConfig ConfiguracionActual; diff --git a/DomoEsp_Potencia_v02/sube.bat b/DomoEsp_Potencia_v02/sube.bat new file mode 100644 index 0000000..0a4e144 --- /dev/null +++ b/DomoEsp_Potencia_v02/sube.bat @@ -0,0 +1,2 @@ +"c:\Program Files (x86)\Arduino\arduino.exe" --board arduino:avr:nano:cpu=atmega168 --port /dev/ttyACM0 --upload /path/to/sketch/sketch.ino +pause \ No newline at end of file diff --git a/DomoEsp_v02/.vs/DomoEsp_v02/v17/.suo b/DomoEsp_v02/.vs/DomoEsp_v02/v17/.suo index eb79e99dc2a7f1c9367522654b0c948c18959f53..e19223f6466c449d782598f00ddcc498202ce1ba 100644 GIT binary patch delta 10007 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 G)V~3omvpZH delta 7326 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 diff --git a/DomoEsp_v02/.vs/DomoEsp_v02/v17/Browse.VC.db b/DomoEsp_v02/.vs/DomoEsp_v02/v17/Browse.VC.db index bfd9de9960239ee7d0e6bec735de0e6461f96ac2..cd6911d78374a930a4c42d189327b12ba52d6c82 100644 GIT binary patch delta 25999 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 diff --git a/DomoEsp_v02/MqttDefines.h b/DomoEsp_v02/MqttDefines.h index bf75808..eb32e6f 100644 --- a/DomoEsp_v02/MqttDefines.h +++ b/DomoEsp_v02/MqttDefines.h @@ -3,8 +3,8 @@ #define MqttDefinesDef 1 //generales #define DEBUG_PS 1 -#define CON_WOL 1 -#define CON_LCD 1 +#define CON_WOL 0 +#define CON_LCD 0 #define MAXTOPICVAR 32//maximo de caracteres de los topic de las variables diff --git a/DomoEsp_v02/config_rf.h b/DomoEsp_v02/config_rf.h index 105f242..80b562a 100644 --- a/DomoEsp_v02/config_rf.h +++ b/DomoEsp_v02/config_rf.h @@ -1,7 +1,7 @@ //parametros configurables************************************************* #define DEBUG_PS 1//Descomentar para debug -#define CON_LCD 1 -#define CON_WOL 1 +#define CON_LCD 0 +#define CON_WOL 0 //va por 16 class CocinapRUBDomoConfig: public DomoConfig { @@ -15,7 +15,7 @@ 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 + refresTimeSens=5;//tiempo de refresco en segundos de los sensores } //configuracion de sensores--------------------------------- virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttWOLManager* wol, MqttDesencadenadorManager *des) @@ -59,7 +59,7 @@ class ActDomoConfig: public DomoConfig 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 + refresTimeSens=5;//tiempo de refresco en segundos de los sensores //config lcd-------------------- lcd.colum=16;//columnas lcd @@ -165,7 +165,7 @@ class SalonHome: public DomoConfig 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 + refresTimeSens=5;//tiempo de refresco en segundos de los sensores //config lcd-------------------- lcd.colum=16;//columnas lcd @@ -236,7 +236,7 @@ class PulSalonPruebConfig: public DomoConfig 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 + refresTimeSens=5;//tiempo de refresco en segundos de los sensores //config lcd-------------------- lcd.colum=16;//columnas lcd @@ -258,10 +258,10 @@ class PulSalonPruebConfig: public DomoConfig //sens->AddHDT22(D4, "casa/desp"); // sens->AddDout(D1, "casa/p/LEnt", true); sens->AddDout(D7, "casa/p/LEnt", true); - sens->AddDin( D1,"casa/p/pul1"); - sens->AddDin( D2, "casa/p/pul2"); - sens->AddDin( D3, "casa/p/pul3"); - sens->AddDin( D4,"casa/p/pulAll"); + // sens->AddDin( D1,"casa/p/pul1"); + //sens->AddDin( D2, "casa/p/pul2"); + //sens->AddDin( D3, "casa/p/pul3"); + //sens->AddDin( D4,"casa/p/pulAll"); } }; class AutomatismosDomoConfig: public DomoConfig @@ -278,7 +278,7 @@ class AutomatismosDomoConfig: public DomoConfig 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 + refresTimeSens=5;//tiempo de refresco en segundos de los sensores //config lcd-------------------- lcd.colum=16;//columnas lcd @@ -374,7 +374,7 @@ class PulSalonConfig: public DomoConfig 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 + refresTimeSens=5;//tiempo de refresco en segundos de los sensores //config lcd-------------------- lcd.colum=16;//columnas lcd @@ -407,10 +407,10 @@ class PulSalonConfig: public DomoConfig //sens->AddHDT22(D4, "casa/desp"); // sens->AddDout(D1, "casa/Salon/LEnt", true); sens->AddDout(D7, "casa/Salon/LEnt", true); - sens->AddDinRetardOff( D1, 1,"casa/Salon/pul1"); - sens->AddDinRetardOff( D2, 1, "casa/Salon/pul2"); - sens->AddDinRetardOff( D5, 1, "casa/Salon/pul3"); - sens->AddDinRetardOff( D6, 1,"casa/Salon/pulAll"); + //sens->AddDinRetardOff( D1, 1,"casa/Salon/pul1"); + //sens->AddDinRetardOff( D2, 1, "casa/Salon/pul2"); + //sens->AddDinRetardOff( D5, 1, "casa/Salon/pul3"); + //sens->AddDinRetardOff( D6, 1,"casa/Salon/pulAll"); } }; class DespachoDomoConfig: public DomoConfig @@ -427,7 +427,7 @@ class DespachoDomoConfig: public DomoConfig 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 + refresTimeSens=5;//tiempo de refresco en segundos de los sensores //config lcd-------------------- lcd.colum=16;//columnas lcd @@ -480,7 +480,7 @@ class CocinaDomoConfig: public DomoConfig 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 + refresTimeSens=5;//tiempo de refresco en segundos de los sensores } //configuracion de sensores--------------------------------- virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttWOLManager* wol, MqttDesencadenadorManager *des) @@ -523,7 +523,7 @@ class SalonDomoConfig: public DomoConfig 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 + refresTimeSens=5;//tiempo de refresco en segundos de los sensores } //configuracion de sensores--------------------------------- virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttWOLManager* wol, MqttDesencadenadorManager *des) @@ -589,7 +589,7 @@ class ExteriorDomoConfig: public DomoConfig 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 + refresTimeSens=5;//tiempo de refresco en segundos de los sensores } //configuracion de sensores--------------------------------- virtual void ConfigGen(MqttSensManager* sens, MqttVarManager* vars, LcdMQTTViewer *lcd, MqttWOLManager* wol, MqttDesencadenadorManager *des) @@ -603,4 +603,4 @@ class ExteriorDomoConfig: public DomoConfig //configuracion que se usara-------------------------- -DespachoDomoConfig ConfiguracionActual; +SalonHome ConfiguracionActual;