393 lines
7.6 KiB
C++
393 lines
7.6 KiB
C++
//#include <ESP8266WiFi.h>//este para esp8266
|
|
#include <SPI.h>
|
|
#include "MqttDefines.h"
|
|
#include "MqttVarManager.h"
|
|
#include "MqttUtiles.h"
|
|
#include <cstring>
|
|
#include <PubSubClient.h>
|
|
|
|
MqttTopicAttay::MqttTopicAttay()
|
|
{
|
|
n=0;
|
|
nst=0;
|
|
}
|
|
|
|
char* MqttTopicAttay::Get(int i)
|
|
{
|
|
return &str[(ind[i])];
|
|
}
|
|
|
|
int MqttTopicAttay::Get(char *topic)
|
|
{
|
|
for(int i=0; i<n; i++)
|
|
{
|
|
if(!strcmp(topic,Get(i)))
|
|
return i;
|
|
}
|
|
return (int)-1;
|
|
}
|
|
|
|
int MqttTopicAttay::Add(char *topic)
|
|
{
|
|
int i=Get(topic);
|
|
if(i>(int)0)
|
|
{
|
|
return i;
|
|
}
|
|
i=n;
|
|
n=n+1;
|
|
ind[i]=nst;
|
|
nst=nst+strlen(topic)+1;
|
|
strcpy(Get(i), topic);
|
|
return i;
|
|
}
|
|
|
|
//*******************************************************************
|
|
|
|
MqttVar::MqttVar()
|
|
{
|
|
flags=0;
|
|
val.f=0;
|
|
topic=0;
|
|
}
|
|
|
|
//*******************************************************************
|
|
MqttVarArray::MqttVarArray()
|
|
{
|
|
n=0;
|
|
}
|
|
|
|
MqttVar* MqttVarArray:: Get(int i)
|
|
{
|
|
return &(data[i]);
|
|
}
|
|
|
|
MqttVar* MqttVarArray::GetVar(int itopic)
|
|
{
|
|
for(int i=0; i<n; i++)
|
|
{
|
|
if(data[i].topic==itopic)
|
|
return &(data[i]);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int MqttVarArray::Add(MqttVar* var)
|
|
{
|
|
data[n]=*var;
|
|
n++;
|
|
return n-1;
|
|
}
|
|
//*******************************************************************
|
|
|
|
MqttVarManager::MqttVarManager()
|
|
{
|
|
|
|
tiempo_var=0;
|
|
SetTimeRefres(30);
|
|
nListenner=0;
|
|
for (int i=0; i<nListenner; i++)
|
|
{
|
|
onChangeListener[2]=NULL;
|
|
}
|
|
}
|
|
void MqttVarManager::SetTimeRefres(int seg)
|
|
{
|
|
incre_tvar=seg*1000;
|
|
}
|
|
void MqttVarManager::config(MqttVarArray *vArray, MqttTopicAttay* t)
|
|
{
|
|
if(vArray)
|
|
vars=vArray;
|
|
else
|
|
vars=&_v;
|
|
if(t)
|
|
topics=t;
|
|
else
|
|
topics=&_t;
|
|
}
|
|
|
|
void MqttVarManager::OnMqtt(char* topic, char* payload)
|
|
{
|
|
char buf[MAXTOPICVAR];
|
|
#ifdef DEBUG_PS
|
|
Serial.print("OnmqttVars: ");
|
|
Serial.println(topic);
|
|
Serial.print("val: ");
|
|
Serial.println(payload);
|
|
#endif
|
|
|
|
strcpy(buf, topic);
|
|
int nt=strlen(buf);
|
|
int ng=strlen("/get");
|
|
if(nt<ng)
|
|
{
|
|
#ifdef DEBUG_PS
|
|
Serial.print("se descarta por topic corto:");
|
|
Serial.println(buf);
|
|
#endif
|
|
return;
|
|
}
|
|
bool isGet=!strcmp("/get", &buf[nt-ng]);
|
|
bool isSet=!strcmp("/set", &buf[nt-ng]);
|
|
buf[nt-ng]=0;
|
|
/*#ifdef DEBUG_PS
|
|
Serial.print("OnmqttVars:Topiccompara:");
|
|
Serial.println(buf);
|
|
#endif*/
|
|
byte f=MqttVar::OUT_VAR;
|
|
if(isGet)
|
|
{
|
|
f=(byte)MqttVar::PRIV_VAR;
|
|
#ifdef DEBUG_PS
|
|
Serial.println("OnmqttVars: get detectado");
|
|
#endif
|
|
}
|
|
else if(isSet)
|
|
{
|
|
#ifdef DEBUG_PS
|
|
Serial.println("OnmqttVars: set detectado");
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#ifdef DEBUG_PS
|
|
Serial.println("OnmqttVars: Ni get ni set");
|
|
#endif
|
|
return;//no es ni get ni set
|
|
}
|
|
|
|
//comprueba variables
|
|
MqttVar* v;
|
|
int res=-1;
|
|
|
|
for(int i=0; i<vars->n; i++)
|
|
{
|
|
v=vars->Get(i);
|
|
|
|
if((v->flags & f) && !strcmp(topics->Get(v->topic),buf))
|
|
{
|
|
if(v->flags & MqttVar::FLOAT_VAR)
|
|
{
|
|
float ff=v->val.f;
|
|
v->val.f=atof(payload);
|
|
if(ff!=v->val.f)
|
|
res=i;
|
|
}
|
|
else
|
|
{
|
|
int ii=v->val.i;
|
|
v->val.i=atoi(payload);
|
|
if(ii!=v->val.i)
|
|
res=i;
|
|
}
|
|
break;//suponemos solo una variable con el mismo topic
|
|
}
|
|
}
|
|
|
|
if(res>=0)
|
|
OnChange(res, 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[32];
|
|
char buffer_p[24];
|
|
MqttVar* v=vars->Get(ivar);
|
|
if(v->flags & MqttVar::CHANGE_VAR)
|
|
{
|
|
|
|
sprintf(buffer_t, "%s/set",topics->Get(v->topic));
|
|
#ifdef DEBUG_PS
|
|
Serial.print("Publica /set var: ");
|
|
Serial.println(buffer_t);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
|
|
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; i<vars->n; i++)
|
|
{
|
|
v=vars->Get(i);
|
|
if(v->flags & f)
|
|
{
|
|
PublicaVar(i);
|
|
}
|
|
}
|
|
}
|
|
void MqttVarManager::inicia(PubSubClient* client_mqtt)
|
|
{
|
|
client_qqtt=client_mqtt;
|
|
}
|
|
|
|
void MqttVarManager::Suscribe()
|
|
{
|
|
//suscribe a mqtt------------
|
|
char buffer_t[32];
|
|
MqttVar* v;
|
|
for(int i=0; i<vars->n; i++)
|
|
{
|
|
v=vars->Get(i);
|
|
if(v->flags & MqttVar::OUT_VAR)//suscribe al set
|
|
{
|
|
sprintf(buffer_t, "%s/set",topics->Get(v->topic));
|
|
client_qqtt->subscribe(buffer_t);
|
|
}
|
|
if(v->flags & MqttVar::PRIV_VAR)//suscribe al get
|
|
{
|
|
sprintf(buffer_t, "%s/get",topics->Get(v->topic));
|
|
client_qqtt->subscribe(buffer_t);
|
|
}
|
|
}
|
|
}
|
|
int MqttVarManager::AddVar(byte flags, char*topic)
|
|
{
|
|
MqttVar v;
|
|
v.flags=flags;
|
|
v.topic=topics->Add(topic);
|
|
return vars->Add(&v);
|
|
}
|
|
int MqttVarManager::AddInternalVarFloat( char*topic)
|
|
{
|
|
return AddVar((byte)(MqttVar::PRIV_VAR|MqttVar::FLOAT_VAR| MqttVar::CHANGE_VAR|MqttVar::ACCION_VAR),topic);
|
|
}
|
|
int MqttVarManager::AddInternalVarInt( char*topic)
|
|
{
|
|
return AddVar((byte)(MqttVar::PRIV_VAR| MqttVar::CHANGE_VAR|MqttVar::ACCION_VAR),topic);
|
|
}
|
|
MqttVar* MqttVarManager::Get(int i)
|
|
{
|
|
return vars->Get(i);
|
|
}
|
|
int MqttVarManager::GetId(char* topic)
|
|
{
|
|
#ifdef DEBUG_PS
|
|
|
|
Serial.println("MqttVarManager::GetId");
|
|
#endif
|
|
int itop= topics->Get(topic);
|
|
#ifdef DEBUG_PS
|
|
|
|
Serial.println("MqttVarManager::GetId busca var");
|
|
#endif
|
|
for(int i=0;i<vars->n; 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; i<nListenner; i++)
|
|
{
|
|
if(onChangeListener[i]==NULL)
|
|
continue;
|
|
onChangeListener[i]->OnVarChange(ivar);
|
|
}
|
|
|
|
}
|
|
void MqttVarManager::AddListenner(MqttOnVarChangeListenner *pOnChangeListener)
|
|
{
|
|
onChangeListener[nListenner++]=pOnChangeListener;
|
|
}
|
|
void MqttVarManager::ResetVolatileVar()
|
|
{
|
|
for(int i=0; i<vars->n; i++)
|
|
{
|
|
MqttVar* v=vars->Get(i);
|
|
if(v->flags& MqttVar::VOLATILE_VAR)
|
|
{
|
|
if(v->flags & MqttVar::FLOAT_VAR)
|
|
v->val.f=0;
|
|
else
|
|
v->val.i=0;
|
|
}
|
|
|
|
}
|
|
}
|
|
void MqttVarManager::InvierteVar(int ivar)
|
|
{
|
|
MqttVar* v=vars->Get(ivar);
|
|
if(v->flags & MqttVar::FLOAT_VAR)
|
|
{
|
|
v->val.f=100.0-v->val.f;
|
|
}
|
|
else
|
|
v->val.i=1-v->val.i;
|
|
OnChange(ivar, 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);
|
|
v->val=val;
|
|
#ifdef DEBUG_PS
|
|
|
|
Serial.print("MqttVarManager::SetVal out i: ");
|
|
Serial.print( v->val.i);
|
|
Serial.print(" f: ");
|
|
Serial.println( v->val.f);
|
|
#endif
|
|
OnChange(ivar, true);
|
|
}
|