DomoEsp_v1/DomoEsp_v02/MqttVarManager.cpp

422 lines
8.2 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;
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<n; i++)
{
if(data[i].topic==itopic)
return &(data[i]);
}
return NULL;
}
int MqttVarArray::Add(MqttVar* var)
{
if (n >= 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; i<nListenner; i++)
{
onChangeListener[i]=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;
MQTTvalor val;
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;
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::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; 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[MAXTOPICVAR];
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);
}
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;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);
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);
}