DomoEsp_v1/DomoEsp_v02/MqttDesencadenadorManager.cpp

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);
}