432 lines
7.8 KiB
C++
432 lines
7.8 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;
|
|
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);
|
|
}
|