#include "sens_domo_mqtt.h" //funciones generales //************************************************************************************************************************************************** //funcion para decidir cuando enviar info de sensores por mqtt bool pasa_incre( unsigned long *tt, unsigned long incre) { unsigned long t=millis(); if(t<*tt) { *tt=t; return true; } if((*tt+incre)>=t) return false; *tt=t; return true; } //************************************************************************************************************************************************** //funcion para decidir cuando enviar info de sensores por mqtt bool pasa_incre( volatile unsigned long *tt, unsigned long incre) { unsigned long t=millis(); if(t<*tt) { *tt=t; return true; } if((*tt+incre)>=t) return false; *tt=t; return true; } //************************************************************************************************************************************************** void conecta_serie(int veloc) { if(DEBUG_PS) { Serial.begin(veloc); delay(10); } } /************************************************************************************************************************************************** void envia_serie(char* s) { if(DEBUG_PS) Serial.print(s); } //************************************************************************************************************************************************** void envia_serieln(char* s) { if(DEBUG_PS) Serial.println(s); }*/ //************************************************************************************************************************************************** void Ceprom_manager::fin_grabacion() { EEPROM.commit(); } //************************************************************** Ceprom_manager::Ceprom_manager() { nb=0; } //************************************************************** void Ceprom_manager::leeb(byte *p) { *p=EEPROM.read(nb++); } //************************************************************** void Ceprom_manager::grabab(byte p) { EEPROM.write(nb++, p); } //************************************************************** void Ceprom_manager::graba_st(char *st) { for(int i=strlen(st); i>0; i--) { Ceprom_manager::grabab(*st); st++; } } //************************************************************** void Ceprom_manager::cursor(int pos) { nb=pos; } //************************************************************** Csens_mqtt::Csens_mqtt() { tipo=SENS_NO_ASIG;//tipo sensor val=0; pin=-1;//pin de conexion topic[0]=0; //----------------------------- //especificas val_old=0; t=0; retard=0; id=0; pun=NULL; } //************************************************************** Csens_mqtt::~Csens_mqtt() { } //************************************************************** bool Csens_mqtt::envia_mqtt(PubSubClient *client_qqtt, char *top, bool envia) { if(pin<0) return false; char buffer_t[32]; char buf[24]; //SimpleDHT22 dht22; //Adafruit_BMP085 bmp;//para la presion //RCSwitch rf = RCSwitch();//para rfin switch(tipo) { case(SENS_NO_ASIG): return true; case(SENS_DHT22)://pilla temperatura y humedad { float temperature = 0; float humidity = 0; int err = SimpleDHTErrSuccess; for(int i=0; i<4; i++) { err = ((SimpleDHT22*)pun)->read2(pin, &temperature, &humidity, NULL); if (err != SimpleDHTErrSuccess) { delay(20); continue; } break; } if(err!=SimpleDHTErrSuccess) { temperature=255; humidity=255; if(envia) envia_serieln("envio dht con error"); } if(!envia || (temperature==255 && humidity==255)) return true; //construlle topic-------------- sprintf(buffer_t, "%s%s/t",top, topic); dtostrf(temperature,3, 2, buf); //envia_serie(buffer_t); //envia_serieln(buf); client_qqtt->publish(buffer_t, buf); sprintf(buffer_t, "%s%s/h",top, topic); dtostrf(humidity,3, 2, buf); client_qqtt->publish(buffer_t, buf); return true; } case(SENS_BMP180): { float temperature = ((Adafruit_BMP085*)pun)->readTemperature(); int presb = ((Adafruit_BMP085*)pun)->readPressure();//pascales float altb = ((Adafruit_BMP085*)pun)->readAltitude(); //envia tempe------------------------------- sprintf(buffer_t, "%s%s/t",top, topic); dtostrf(temperature,3, 2, buf); client_qqtt->publish(buffer_t, buf); //envia presion barometrica----------------- sprintf(buffer_t, "%s%s/p",top, topic); sprintf(buf,"%d",presb); client_qqtt->publish(buffer_t, buf); //envia altura barometrica------------------- sprintf(buffer_t, "%s%s/a",top, topic); dtostrf(altb,3, 2, buf); client_qqtt->publish(buffer_t, buf); return true; } case(SENS_ANALOG_IN): { float aux; /* envia_serie("val: "); envia_serie(val); envia_serie(" pin: "); envia_serieln(pin);*/ if(val) aux=100.*((float)(1024- analogRead(pin)))/1024; else aux=100.*((float)(analogRead(pin)))/1024; dtostrf(aux,3, 2, buf); sprintf(buffer_t, "%s%s",top,topic ); //envia_serie(buffer_t); //envia_serieln(buf); client_qqtt->publish(buffer_t, buf); return true; } case(SENS_DIGI_IN_OUT): { if (envia) { sprintf(buffer_t, "%s%s", top, topic); sprintf(buf, "%d", (int)val); client_qqtt->publish(buffer_t, buf); } else { sprintf(buffer_t, "%s%s/set",top, topic); sprintf(buf,"%d",(int) val); client_qqtt->publish(buffer_t, buf); } return true; } case(SENS_DIGI_IN): { sprintf(buffer_t, "%s%s",top, topic); sprintf(buf,"%d",(int) val); client_qqtt->publish(buffer_t, buf); //envia_serie(buffer_t); //envia_serieln(buffer); return true; } case(SENS_DIGI_OUT): { sprintf(buffer_t, "%s%s/get",top, topic); sprintf(buf,"%d",(int) val); client_qqtt->publish(buffer_t, buf); return true; } case(SENS_RF_DATA_IN): { sprintf(buffer_t, "%s%s",top, topic); sprintf(buf,"%d",(int) val); client_qqtt->publish(buffer_t, buf); return true; } default: return false; } } //************************************************************** bool Csens_mqtt::get(char *conf) { sprintf(conf, "<%d;%d;%d;%s;%d;%d;%d;%d;>", (int)tipo, (int)val, pin, topic, (int)val_old, t, retard/1000, id); envia_serieln(conf); return true; } //************************************************************** bool Csens_mqtt::set(char *conf) { /* //la trama empieza por < y acaba por> y se pone la info de las variables de la clase: byte tipo;//tipo sensor byte val;//se usa para guradar valor en algunos sensores y flags en otros int pin;//pin de conexion char topic[8];//topic de mqtt que se anadira //----------------------------- //especificas byte val_old; volatile unsigned long t; unsigned long retard; long id; separadas por ; */ envia_serieln("entra en set"); int i=0, j, k; char res[17]; if(conf[i]=='<') { i++; } else return false; k=0; j=0; while(conf[i]!='>') { if(!conf[i]) { envia_serieln("sale por fin"); return false; } if(conf[i]==';') { res[j]=0; j=0; switch(k) { case(0): tipo= atoi(res); break; case(1): val=atoi(res); break; case(2): pin=atoi(res); break; case(3): strcpy(topic,res); // tipo=(byte)atoi(res); break; case(4): val_old=atoi(res); break; case(5): t=atoi(res);//atoll break; case(6): retard=1000*atoi(res);//atoll break; case(7): id=atol(res); break; } k++; } else { res[j]=conf[i]; j++; if(j>=16) { envia_serieln("sin memo en set"); return false; } } i++; } envia_serieln(k); return k>7; //sprintf(conf, "<%d;%d;%d;%s;%d;%ld;%ld;%ld",(int)tipo, (int)val, pin, topic, (int)val_old, t, retard, id); //return true; } //************************************************************** void Csens_domo_mqtt::para_sens() { int i; for(i=0; i=300) { envia_serie("Error en sensor "); envia_serie(i); envia_serieln("BMP no se puede inicializar"); // return false;//puede que este bien } bmppillado=true; return true; } case(Csens_mqtt::SENS_RF_IN): { if(rf_in_pillado) return false; rf_in_pillado=true; rf.enableReceive(sen[i].pin); //rf.setPulseLength(150); return true; } case(Csens_mqtt::SENS_RF_OUT): { if(rf_out_pillado) return false; rf_out_pillado=true; rf.enableTransmit(sen[i].pin); return true; } case(Csens_mqtt::SENS_RF_DATA_IN): { if(n_rf_in>=MAX_RF_IN_SENS_MQTT) { envia_serie("Error en sensor "); envia_serie(i); envia_serieln("rf_in sin espacio para mas"); return false; } envia_serie("rf_data retard: "); envia_serieln(sen[i].retard); ind_rf_in[n_rf_in]=i; n_rf_in++; return true; } case(Csens_mqtt::SENS_ANALOG_IN): { return true;//no necesita nada } case(Csens_mqtt::SENS_DIGI_IN): { if(n_inter>=MAX_INTERRUP_SENS_MQTT) { envia_serie("Error en sensor "); envia_serie(i); envia_serieln("digi_in sin espacio para las interrupciones"); return false; } ind_interrup[n_inter]=i; envia_serie("inicia din "); pinMode(sen[i].pin, INPUT); //digitalWrite(sen[i].pin, sen[i].val); atachea(n_inter++); envia_serie("iniciado din "); return true; } case(Csens_mqtt::SENS_DIGI_OUT): { pinMode(sen[i].pin, OUTPUT); digitalWrite(sen[i].pin, sen[i].val); return true; } case(Csens_mqtt::SENS_DIGI_IN_OUT): { if (n_inter >= MAX_INTERRUP_SENS_MQTT) { envia_serie("Error en sensor "); envia_serie(i); envia_serieln("digi_in_out sin espacio para las interrupciones"); return false; } pinMode(sen[i].pin, OUTPUT); digitalWrite(sen[i].pin, sen[i].val); ind_interrup[n_inter] = i; envia_serie("inicia digi_in_out "); pinMode(sen[i].id, INPUT); atachea(n_inter++); envia_serie("iniciado din "); return true; } default: break; } return false; } //************************************************************** Csens_domo_mqtt::Csens_domo_mqtt() { rf=RCSwitch(); n=0; flags=0; bmppillado= rf_in_pillado= rf_out_pillado = false; n_inter=0; t_rev_interrup=1000; t_inter=0; n_rf_in=0; pclase_sens_domo_mq=(void*)this; } //************************************************************** bool Csens_domo_mqtt::conf() { Ceprom_manager ep; char buf[64]; int nb, nn; n=0; //lee version----------------------------- buf[0]=0; ep.leeb((byte*)buf); if((byte)buf[0]!=(byte)VERSION_SENS_MQTT) { envia_serieln("Version no reconocida"); return false;//sin configuracion } for (nn=0; nn=64) { ep.leeb((byte*)&buf[++nb]); } if(buf[nb]!='>') break; buf[++nb]=0; //envia_serie("conf lee "); //envia_serieln(buf); if(sen[n].set(buf)) n++; else { envia_serie("Error al leer sensor "); envia_serieln(buf); } } envia_serie("lee "); envia_serie(n); envia_serieln(" sensores"); return n>0; } //************************************************************** void Csens_domo_mqtt::envia_comunes() { for(int i=0;isubscribe(buffer_t); break; } default: break; } } } //************************************************************** bool Csens_domo_mqtt::on_mqtt(char* topic, char* payload) { char buffer_t[32]; int j; //descompone topic //busca sensor------------------ for(int i=0;ion_interrupcion(0); } ICACHE_RAM_ATTR void interrupcion1() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(1); } ICACHE_RAM_ATTR void interrupcion2() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(2); } ICACHE_RAM_ATTR void interrupcion3() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(3); } ICACHE_RAM_ATTR void interrupcion4() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(4); } ICACHE_RAM_ATTR void interrupcion5() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(5); } ICACHE_RAM_ATTR void interrupcion6() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(6); } ICACHE_RAM_ATTR void interrupcion7() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(7); } ICACHE_RAM_ATTR void interrupcion8() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(8); } ICACHE_RAM_ATTR void interrupcion9() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(9); } ICACHE_RAM_ATTR void interrupcion10() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(10); } ICACHE_RAM_ATTR void interrupcion11() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(11); } ICACHE_RAM_ATTR void interrupcion12() { ((Csens_domo_mqtt*) pclase_sens_domo_mq)->on_interrupcion(12); } //************************************************************** void Csens_domo_mqtt::atachea(int i) { if(bloqueo_sens) return; //la otra parte de la chapuza que no se me ocurre otra manera envia_serie("atachea din "); envia_serie(i); envia_serie(" pin "); envia_serieln(sen[ind_interrup[i]].pin); int pin = sen[ind_interrup[i]].pin; if (sen[ind_interrup[i]].tipo == Csens_mqtt::SENS_DIGI_IN_OUT) pin = sen[ind_interrup[i]].id; switch(i) { case(0): attachInterrupt(digitalPinToInterrupt(pin), interrupcion0, CHANGE); break; case(1): attachInterrupt(digitalPinToInterrupt(pin), interrupcion1, CHANGE); break; case(2): attachInterrupt(digitalPinToInterrupt(pin), interrupcion2, CHANGE); break; case(3): attachInterrupt(digitalPinToInterrupt(pin), interrupcion3, CHANGE); break; case(4): attachInterrupt(digitalPinToInterrupt(pin), interrupcion4, CHANGE); break; case(5): attachInterrupt(digitalPinToInterrupt(pin), interrupcion5, CHANGE); break; case(6): attachInterrupt(digitalPinToInterrupt(pin), interrupcion6, CHANGE); break; case(7): attachInterrupt(digitalPinToInterrupt(pin), interrupcion7, CHANGE); break; case(8): attachInterrupt(digitalPinToInterrupt(pin), interrupcion8, CHANGE); break; case(9): attachInterrupt(digitalPinToInterrupt(pin), interrupcion9, CHANGE); break; case(10): attachInterrupt(digitalPinToInterrupt(pin), interrupcion10, CHANGE); break; case(11): attachInterrupt(digitalPinToInterrupt(pin), interrupcion11, CHANGE); break; case(12): attachInterrupt(digitalPinToInterrupt(pin), interrupcion12, CHANGE); break; } } //*************************************************************** void Csens_domo_mqtt::on_interrupcion(int i) { envia_serie("On interrup "); int j=ind_interrup[i]; envia_serieln(j); if (sen[j].retard == 0) { sen[j].val_old = 1; sen[j].t = millis(); } else { sen[j].val = 1; sen[j].t = millis(); } } //************************************************************** void Csens_domo_mqtt::revisa_interrupciones() { int j, i; //interrupciones puras------------------------------ for(j=0; j=n_rf_in) { envia_serie("rf no reconocido: "); envia_serieln(val); return;//id no reconocido } //envia_serie("rf on detectado: "); //envia_serieln(val); //actualiza valor-------------------------------------------- sen[i].val=1; sen[i].t=millis(); if(!sen[i].val_old) { sen[i].envia_mqtt(client_qqtt, top, true); sen[i].val_old=1; } } //************************************************************** bool Csens_domo_mqtt::graba_conf() { envia_serieln("Graba config"); char buf[64]; bool res=true; Ceprom_manager ep; buf[0]=(byte)VERSION_SENS_MQTT; ep.grabab((byte)buf[0]); for(int i=0; i