DomoEsp_v1/DomoEsp_v02/MqttDesencadenadorManager.cpp

424 lines
9.1 KiB
C++

#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;
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*/
}
}
}
void 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;
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;
if(!p.res || !activo)
{
activo=!p.res;
/* #ifdef DEBUG_PS
Serial.println("Fin causa sale ");
#endif*/
p.sigue=false;
break;
}
else
{
activo=false;
/*#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;
}
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;
}
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
}
//*******************************************************************
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
for(int i=0; i<des.n; i++)
{
des.Get(i)->Exe(vars);
}
//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);
}