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