teste de publish

devices.cpp

Committer:
brunofgc
Date:
2018-06-08
Revision:
24:4d44626e5b78
Parent:
23:d3ef6bb8412a

File content as of revision 24:4d44626e5b78:

#include "devices.h"
enum {
    estadoConfiguracao_idle = 0,
    estadoConfiguracao_creatingDevice,
    estadoConfiguracao_alarmSet,
    estadoConfiguracao_readingsSet,
    estadoConfiguracao_scheduleSet,
    estadoConfiguracao_scheduleExceptionSet
};

uint8_t numAlarms;
uint8_t numSchedules;
uint8_t numScheduleExceptions;                
uint16_t numReadings;
alarm alarms[maxAlarms] __attribute__ ((section("AHBSRAM0")));
reading readings[maxReadings] __attribute__ ((section("AHBSRAM0")));
schedule schedules[maxSchedules] __attribute__ ((section("AHBSRAM0")));
scheduleException scheduleExceptions[maxSchedulesExceptions] __attribute__ ((section("AHBSRAM0")));

void floatToBin(uint8_t dir, float *v,uint8_t *p)
{
    //Variáveis locais
    union {
        char c[4];
        float v;
    }u;
    int i;

    if(dir) {
        u.v = *v;
        for(i=0; i<4; i++) {
            p[i]=u.c[3-i];
        }
    } else {
        for(i=0; i<4; i++) {
            u.c[3-i]=p[i];
        }
        *v = u.v;
    }
}

void uint32_t_ToBin(uint8_t dir, uint32_t *v,uint8_t *p)
{
    //Variáveis locais
    union {
        char c[4];
        uint32_t v;
    }u;
    int i;

    if(dir) {
        u.v = *v;
        for(i=0; i<4; i++) {
            p[i]=u.c[3-i];
        }
    } else {
        for(i=0; i<4; i++) {
            u.c[3-i]=p[i];
        }
        *v = u.v;
    }
}

void uint16_t_ToBin(uint8_t dir, uint16_t *v,uint8_t *p)
{
    //Variáveis locais
    union {
        char c[2];
        uint32_t v;
    }u;
    int i;

    if(dir) {
        u.v = *v;
        for(i=0; i<2; i++) {
            p[i]=u.c[1-i];
        }
    } else {
        for(i=0; i<2; i++) {
            u.c[1-i]=p[i];
        }
        *v = u.v;
    }
}

/*void mostraAlarmeEmExecucao(uint32_t indice){
    printf("Alarme %u:\n",indice);
    printf("\tId <%lu>.\n",alarms[indice].id);
    printf("\tSeconds <%lu>.\n",alarms[indice].seconds);
    printf("\tAddr %u, func %u, reg %lu.\n",alarms[indice].addrModbusRead,alarms[indice].funcModbusRead,alarms[indice].regModbusRead);
    if(alarms[indice].type==modBusType_float) {
        float value;
        floatToBin(0,&value,&alarms[indice].value[0]);                
        if(alarms[indice].max){
            printf("\tFloat max <%f>.\n",value);
        }
        else{printf("\tFloat min <%f>.\n",value);}
    }
    
    if(alarms[indice].type==modBusType_uint32_t) {
        uint32_t value;
        uint32_t_ToBin(0,&value,&alarms[indice].value[0]);
        if(alarms[indice].max){
            printf("\tuint32_t max <%lu>.\n",value);
        }
        else{printf("\tuint32_t min <%lu>.\n",value);}
    }
    
    if(alarms[indice].type==modBusType_uint16_t) {
        uint16_t value;
        uint16_t_ToBin(0,&value,&alarms[indice].value[0]);
        if(alarms[indice].max){
            printf("\tuint16_t max <%lu>.\n",value);
        }
        else{printf("\tuint16_t min <%lu>.\n",value);}
    }            
    
    if(alarms[indice].type==modBusType_int32_t) {
        uint32_t value;
        uint32_t_ToBin(0,&value,&alarms[indice].value[0]);
        if(alarms[indice].max){
            printf("\tint32_t max <%ld>.\n",(int32_t)value);
        }
        else{printf("\tint32_t min <%ld>.\n",(int32_t)value);}
    }
    
    if(alarms[indice].type==modBusType_int16_t) {
        uint16_t value;
        uint16_t_ToBin(0,&value,&alarms[indice].value[0]);
        if(alarms[indice].max){
            printf("\tint16_t max <%ld>.\n",(int16_t)value);
        }
        else{printf("\tint16_t min <%ld>.\n",(int16_t)value);}
    }            
    
    if(alarms[indice].type==modBusType_bit) {
        uint8_t value;
        value=alarms[indice].value[0];                
        if(alarms[indice].max){
            printf("\tBIT max <%lu>.\n",value);
        }
        else{printf("\tBIT min <%lu>.\n",value);}
    }            
    
    printf("\tact:%lu\n",alarms[indice].idAct);    
}*/

//Funcao restaurada
void verifyAlarms(){
    //Inicio da verificação
    uint16_t alarmIndex;
    float leitura_float,value_float;
    double leitura_double,value_double;
    uint32_t leitura_uint32_t,value_uint32_t;
    uint16_t leitura_uint16_t,value_uint16_t;
    bool leitura_bit,value_bit;    
    bool alarmFoundAntes;
    char aux[30];
        
    //for(alarmIndex = 0;alarmIndex < alarmes;alarmIndex++){        
    for(alarmIndex = 0;alarmIndex < alarmes;alarmIndex++){        
        diversos::wdt.kick(180.0);
        /*pc.printf("\r\nTeste Alarm, id<%lu>.\r\n",alarms[alarmIndex].id);
        pc.printf("ON<%lu>.\r\n",alarms[alarmIndex].on);
        pc.printf("secAlarm<%lu>.\r\n",alarms[alarmIndex].secAlarm);
        pc.printf("alarmFound<%lu>.\r\n",alarms[alarmIndex].alarmFound);*/
        //if((alarms[alarmIndex].on)&&(alarms[alarmIndex].id<100000000)){       
        if(alarms[alarmIndex].on){
            alarmFoundAntes = alarms[alarmIndex].alarmFound;
            //if(debug){mostraAlarmeEmExecucao(alarmIndex);}            
            switch(alarms[alarmIndex].type){
                case modBusType_float:                                        
                        //Montar float!
                        floatToBin(0,&value_float,&alarms[alarmIndex].value[0]);                    
                        value_double = (double)value_float;
                        if(alarms[alarmIndex].addrModbusRead != enderecoControladoraVirtual){//Bloco de leitura da variável modBus;
                            modBusMaster1::readFloat(
                                alarms[alarmIndex].addrModbusRead,
                                alarms[alarmIndex].funcModbusRead,
                                alarms[alarmIndex].regModbusRead,
                                1,
                                &leitura_float
                            );
                        }else{
                            //leitura_float = temperaturas[alarms[alarmIndex].regModbusRead];
                            //Busca Interna                        
                            if(alarms[alarmIndex].regModbusRead<100){//Registradores das entradas de temperatura
                                //Populando floatBuffer com a temperaturas
                                if(alarms[alarmIndex].regModbusRead < num_temperatureSensors){
                                    leitura_float = temperaturas[alarms[alarmIndex].regModbusRead];                                    
                                }    
                            }
                            if((alarms[alarmIndex].regModbusRead>99)&&(alarms[alarmIndex].regModbusRead<104)){//Registradores das entradas analógicas
                                leitura_float = aiFiltrada[alarms[alarmIndex].regModbusRead - 100];                            
                            }
                         }                        
                        leitura_double = (double)leitura_float;                        
                    break;
                case modBusType_uint32_t:
                        //Montar uint32_t!
                        uint32_t_ToBin(0,&value_uint32_t,&alarms[alarmIndex].value[0]);                    
                        //value_float = (float)value_uint32_t;
                        value_double = (double)value_uint32_t;
                        if(alarms[alarmIndex].addrModbusRead != enderecoControladoraVirtual){//Bloco de leitura da variável modBus;
                            //Bloco de leitura da variável modBus;
                            modBusMaster1::readRegister32BIT(
                                alarms[alarmIndex].addrModbusRead,
                                alarms[alarmIndex].funcModbusRead,
                                alarms[alarmIndex].regModbusRead,
                                1,
                                &leitura_uint32_t
                            );
                        }else{
                            leitura_uint32_t = pulsosEDs[alarms[alarmIndex].regModbusRead];
                         }                
                        leitura_float = (float)leitura_uint32_t;
                    break;
                    
                case modBusType_uint16_t:
                        //Montar uint16_t!
                        uint16_t_ToBin(0,&value_uint16_t,&alarms[alarmIndex].value[0]);                    
                        //value_float = (float)value_uint16_t;
                        value_double = (double)value_uint16_t;
                        if(alarms[alarmIndex].addrModbusRead!=enderecoControladoraVirtual){
                            //Bloco de leitura da variável modBus;
                            modBusMaster1::readRegister16BIT(
                                alarms[alarmIndex].addrModbusRead,
                                alarms[alarmIndex].funcModbusRead,
                                alarms[alarmIndex].regModbusRead,
                                1,
                                &leitura_uint16_t
                            );     
                        }else{
                            if(alarms[alarmIndex].regModbusRead<4){
                                leitura_uint16_t = aiFiltrada[alarms[alarmIndex].regModbusRead];
                            }
                         }
                
                        //leitura_float = (float)leitura_uint16_t;                      
                        leitura_double = (double)leitura_uint16_t;                      
                    break;
                
                case modBusType_int32_t:
                        //Montar uint32_t!
                        uint32_t_ToBin(0,&value_uint32_t,&alarms[alarmIndex].value[0]);                    
                        //value_float = (float)((int32_t)value_uint32_t);
                        value_double = (double)((int32_t)value_uint32_t);
                        
                        if(alarms[alarmIndex].addrModbusRead != enderecoControladoraVirtual){//Bloco de leitura da variável modBus;
                            //Bloco de leitura da variável modBus;
                            modBusMaster1::readRegister32BIT(
                                alarms[alarmIndex].addrModbusRead,
                                alarms[alarmIndex].funcModbusRead,
                                alarms[alarmIndex].regModbusRead,
                                1,
                                &leitura_uint32_t
                            );
                        }else{
                            leitura_uint32_t = pulsosEDs[alarms[alarmIndex].regModbusRead];
                         }                                       
                
                        //leitura_float = (float)((int32_t)leitura_uint32_t);
                        leitura_double = (double)((int32_t)leitura_uint32_t);
                    break;
                    
                case modBusType_int16_t:
                        //Montar uint16_t!
                        uint16_t_ToBin(0,&value_uint16_t,&alarms[alarmIndex].value[0]);                    
                        //value_float = (float)((int16_t)value_uint16_t);
                        value_double = (double)((int16_t)value_uint16_t);
                        if(alarms[alarmIndex].addrModbusRead!=enderecoControladoraVirtual){
                            //Bloco de leitura da variável modBus;
                            modBusMaster1::readRegister16BIT(
                                alarms[alarmIndex].addrModbusRead,
                                alarms[alarmIndex].funcModbusRead,
                                alarms[alarmIndex].regModbusRead,
                                1,
                                &leitura_uint16_t
                            );     
                        }else{
                            if(alarms[alarmIndex].regModbusRead<4){
                                leitura_uint16_t = aiFiltrada[alarms[alarmIndex].regModbusRead];
                            }
                         }
                
                        //leitura_float = (float)((int16_t)leitura_uint16_t);
                        leitura_double = (double)((int16_t)leitura_uint16_t);
                    break;
                
                
                case modBusType_bit: 
                        //Montar bit!
                        //O valor de alarm para bit é o value[0]!!!
                        value_bit = (alarms[alarmIndex].value[0] > 0); //Qualquer valor maior que zero da saída 1
                        //value_float = (float)value_bit;
                        value_double = (double)value_bit;
                        if(alarms[alarmIndex].addrModbusRead != enderecoControladoraVirtual){//Bloco de leitura da variável modBus;
                            //Bloco de leitura da variável modBus;
                            modBusMaster1::readCoils(
                                alarms[alarmIndex].addrModbusRead,                        
                                alarms[alarmIndex].regModbusRead,
                                1,
                                &leitura_bit
                            );                                                   
                        }else{
                            leitura_bit = entradasDigitais[alarms[alarmIndex].regModbusRead];
                         }
                        //leitura_float = (float)leitura_bit;                    
                        leitura_double = (double)leitura_bit;                    
                    break;
                
            }
            
            //Teste de maquina de estados alarme alarmFound, max, seconds, secAlarm, alarmFound                     
            /*cenários
            found   &&  max
            0       ^   0   =   0
            0       ^   1   =   1
            1       ^   0   =   1
            1       ^   1   =   0*/
            
            if((alarms[alarmIndex].alarmFound)^(alarms[alarmIndex].max)){
                if(leitura_double > value_double){alarms[alarmIndex].secAlarm++;}
                    else{alarms[alarmIndex].secAlarm=0;}
            }else{
                if(leitura_double < value_double){alarms[alarmIndex].secAlarm++;}
                    else{alarms[alarmIndex].secAlarm=0;}
            }
            
            
            //Alterno de found pra release dependendo de como seja.
            if(alarms[alarmIndex].secAlarm >= alarms[alarmIndex].seconds){
                alarms[alarmIndex].alarmFound = !alarms[alarmIndex].alarmFound;
                alarms[alarmIndex].secAlarm = 0;
            }            
            
            //debug
                //if(debug){pc.printf("alarmIndex [%lu],leitura_double %f, value_double %f, alarmFound %u, secAlarm %lu\r\n",alarmIndex,leitura_double,value_double,alarms[alarmIndex].alarmFound,alarms[alarmIndex].secAlarm);}
            //debug
            
            //Teste de maquina de estados alarme alarmFound, max, seconds, secAlarm, alarmFound                     
            
            //Verifico se houve alarme não tratado
            if(alarms[alarmIndex].alarmFound!=alarmFoundAntes){               
               if(alarms[alarmIndex].alarmFound){
                   printf("Alarm FOUND! Id <%lu>.\n",alarms[alarmIndex].id);
                   sdCardBuf.fill("log{alarm:event:found;id:",25);
                   sprintf(aux,"%lu",alarms[alarmIndex].id);
                   sdCardBuf.fill(aux,strlen(aux));               
                   
                   sdCardBuf.fill(";timestamp:",11);
                   sprintf(aux,"%lu",time(NULL));
                   sdCardBuf.fill(aux,strlen(aux));               
                   
                   sdCardBuf.fill(";reading:",9);
                   if(alarms[alarmIndex].type == modBusType_float){
                       sprintf(aux,"%f",leitura_float);
                   }else if(alarms[alarmIndex].type == modBusType_uint32_t){
                       sprintf(aux,"%lu",leitura_uint32_t);
                   }else if(alarms[alarmIndex].type == modBusType_uint16_t){
                       sprintf(aux,"%lu",leitura_uint16_t);
                   }else if(alarms[alarmIndex].type == modBusType_int32_t){
                       sprintf(aux,"%ld",(int32_t)leitura_uint32_t);
                   }else if(alarms[alarmIndex].type == modBusType_int16_t){
                       sprintf(aux,"%ld",(int16_t)leitura_uint16_t);
                   }else if(alarms[alarmIndex].type == modBusType_bit){
                       sprintf(aux,"%u",leitura_bit);
                   }
                   sdCardBuf.fill(aux,strlen(aux));   
                                            
                   leitura_uint16_t = sdCardBuf.fill("}log",4); //Reaproveitando uma variável de 16bit               
                   sdCard::insereDadosBank(sdCardBuf.get(),leitura_uint16_t);                   
                   
                   boolExecAct=true;
                   act = alarms[alarmIndex].idAct;
               }else{
                   printf("Alarm RELEASE! id <%lu>.\n",alarms[alarmIndex].id);
                   sdCardBuf.fill("log{alarm:event:release;id:",27);
                   sprintf(aux,"%lu",alarms[alarmIndex].id);
                   sdCardBuf.fill(aux,strlen(aux));                              
                   
                   sdCardBuf.fill(";timestamp:",11);
                   sprintf(aux,"%lu",time(NULL));
                   sdCardBuf.fill(aux,strlen(aux));               
                   
                   sdCardBuf.fill(";reading:",9);
                   if(alarms[alarmIndex].type == modBusType_float){
                       sprintf(aux,"%f",leitura_float);
                   }else if(alarms[alarmIndex].type == modBusType_uint32_t){
                       sprintf(aux,"%lu",leitura_uint32_t);
                   }else if(alarms[alarmIndex].type == modBusType_uint16_t){
                       sprintf(aux,"%lu",leitura_uint16_t);
                   }else if(alarms[alarmIndex].type == modBusType_int32_t){
                       sprintf(aux,"%ld",(int32_t)leitura_uint32_t);
                   }else if(alarms[alarmIndex].type == modBusType_int16_t){
                       sprintf(aux,"%ld",(int16_t)leitura_uint16_t);
                   }else if(alarms[alarmIndex].type == modBusType_bit){
                       sprintf(aux,"%u",leitura_bit);
                   }
                   sdCardBuf.fill(aux,strlen(aux)); 
                   
                   leitura_uint16_t = sdCardBuf.fill("}log",4); //Reaproveitando uma variável de 16bit
                   //sdCard::arquivoAberto(40000);
                   sdCard::insereDadosBank(sdCardBuf.get(),leitura_uint16_t);                   
                }                        
                //atrasa o envio em 3 segundos para que possa ser gravado o registro do alarme.
                enviaDadosPorAlarme=10;            
            }
        }
    }    
}

void verifySchedules(){
    char stringTime[30];
    char *weekdayString;
    time_t seconds = time(NULL)+5;
    uint8_t hora;
    uint16_t minuto;
    uint8_t weekday=0;
    uint16_t anoAtual=0;
    uint16_t diaAtual=0;
    uint16_t mesAtual=0;
    uint16_t anoScheduleException=0;
    uint16_t diaScheduleException=0;
    uint16_t mesScheduleException=0;
    const char* weekdayTable[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
    uint8_t indexSchedule;
    uint8_t indexScheduleException;
    bool exceptionDetected=false;    
    
    puts("Verifing schedule.\r\n");
    
    strftime(stringTime, 30, "%a,%R,%y,%d,%m", localtime(&seconds));    
    //pc.printf("VerifySchedule <%s>.\r\n",stringTime);
    //Thu,20:48,17,2,7
    weekdayString = strtok(stringTime,",");    
    weekday = 0;
    while((weekday<10)&&(strstr(weekdayTable[weekday],weekdayString)==NULL)){
        weekday++;
    }    
    hora = atoi(strtok(NULL,":"));
    minuto = atoi(strtok(NULL,","));
    minuto = (hora*60)+minuto;
    anoAtual = atoi(strtok(NULL,","));
    diaAtual = atoi(strtok(NULL,","));
    mesAtual = atoi(strtok(NULL,""));
    
    //pc.printf("Passo 1 .\r\n");
    for(indexSchedule = 0; indexSchedule < qtdSchedules; indexSchedule++){
        //pc.printf("Passo 2.\r\n");
        diversos::wdt.kick(180.0);
        if(schedules[indexSchedule].weekday&(0x1<<weekday)){
            //pc.printf("Passo 3.\r\n");                      
            if(schedules[indexSchedule].minute == minuto){
                //pc.printf("Passo 4.\r\n");
                //Verifico se já executei e então executo a ação.
                if(!schedules[indexSchedule].actSent){
                    //pc.printf("Passo 5 .\r\n");
                    //Executa a ação;                    
                    for(indexScheduleException = 0;indexScheduleException<numScheduleExceptions;indexScheduleException++){
                        //pc.printf("Passo 6.\r\n");
                        if(schedules[indexSchedule].id == scheduleExceptions[indexScheduleException].id_schedule){
                            //pc.printf("Passo 7.\r\n");
                            seconds = scheduleExceptions[indexScheduleException].timestamp;
                            strftime(stringTime, 30, "%y,%d,%m", localtime(&seconds));
                            anoScheduleException=atoi(strtok(stringTime,","));
                            diaScheduleException=atoi(strtok(NULL,","));
                            mesScheduleException=atoi(strtok(NULL,""));
                            /*
                            pc.printf("\r\nDebug ScheduleException.\r\n");
                            pc.printf("stringTime <%s>.\r\n",stringTime);
                            pc.printf("anoScheduleException %lu.",anoScheduleException);
                            pc.printf("diaScheduleException %lu.",diaScheduleException);
                            pc.printf("mesScheduleException %lu.",mesScheduleException);
                            pc.printf("anoAtual %lu.",anoAtual);
                            pc.printf("diaAtual %lu.",diaAtual);
                            pc.printf("mesAtual %lu.",mesAtual);
                            pc.printf("\r\n");
                            */
                            if(
                                ((anoScheduleException == anoAtual) || (anoScheduleException == 70))
                                &&
                                (diaAtual == diaScheduleException)
                                &&
                                (mesAtual == mesScheduleException)
                            )
                            {
                                pc.printf("ScheduleException detected.\r\n");
                                exceptionDetected=true;
                            }
                        }
                    }
                    if(!exceptionDetected){                        
                        execAct(schedules[indexSchedule].idAct);
                        schedules[indexSchedule].actSent = true;
                    }
                }                
            }else{                
                schedules[indexSchedule].actSent = false;
             }
        }
    }    
}

/*
void verifySchedules(){
    char stringTime[15];
    char *weekdayString;
    time_t seconds = time(NULL);
    uint8_t hora;
    uint16_t minuto;
    uint8_t weekday=0;    
    const char* weekdayTable[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
    uint8_t indexSchedule;
    
    //Tue,19:09    
    strftime(stringTime, 15, "%a,%R", localtime(&seconds));    
    
    weekdayString = strtok(stringTime,",");    
    weekday = 0;
    while((weekday<10)&&(strstr(weekdayTable[weekday],weekdayString)==NULL)){
        weekday++;
    }
    weekday++;
    hora = atoi(strtok(NULL,":"));
    minuto = atoi(strtok(NULL,""));
    minuto = (hora*60)+minuto;
    //printf("\r\n\r\nMinuto %lu.\r\n\r\n",minuto);    
    for(indexSchedule = 0; indexSchedule < qtdSchedules; indexSchedule++){
        //printf("Executando item %u do for de schedules.\r\n\r\n",indexSchedule);
        if((schedules[indexSchedule].weekday == weekday)||(schedules[indexSchedule].weekday == 0)){
            //Se for um alarme para o dia de hoje ou o alarme independer de dia (Se o dia for zero)
            //printf("Hoje eh dia de executar a acão do schedule indice %u.\r\n\r\n",indexSchedule);
            if(schedules[indexSchedule].minute == minuto){
                //Verifico se já executei e então executo a ação.
                if(!schedules[indexSchedule].actSent){
                    //Executa a ação;
                    //printf("Executando a acao!\r\n\r\n");
                    execAct(schedules[indexSchedule].idAct);
                    schedules[indexSchedule].actSent = true;        
                }                
            }else{                
                schedules[indexSchedule].actSent = false;
             }
        } 
    }    
}
*/
/*
uint8_t execActSchedule(uint32_t index){            
    switch(schedules[index].actType){        
        case modBusType_float:
                float floatValueToWrite;
                //writeFloat(uint8_t,uint16_t,uint8_t,float*);
                floatToBin(0,&floatValueToWrite,&schedules[index].actValue[0]);                    
                modBusMaster1::writeFloat(
                    schedules[index].param1,
                    schedules[index].param2,
                    schedules[index].param3,
                    &floatValueToWrite
                );                    
            break;
        case modBusType_uint32_t:
                uint32_t uint32ValueToWrite;                
                uint32_t_ToBin(0,&uint32ValueToWrite,&schedules[index].actValue[0]);                    
                modBusMaster1::writeRegister32BIT(
                    schedules[index].param1,
                    schedules[index].param2,
                    schedules[index].param3,
                    &uint32ValueToWrite
                );                    
            break;
        case modBusType_uint16_t:
                uint16_t uint16ValueToWrite;                
                uint16_t_ToBin(0,&uint16ValueToWrite,&schedules[index].actValue[0]);                    
                modBusMaster1::writeRegister16BIT(
                    schedules[index].param1,
                    schedules[index].param2,
                    schedules[index].param3,
                    &uint16ValueToWrite
                ); 
            break;
        case modBusType_bit:
                bool boolValueToWrite;                
                boolValueToWrite = (schedules[index].actValue[0] != 0);                    
                modBusMaster1::writeSingleCoil(
                    schedules[index].param1,                    
                    schedules[index].param3,
                    boolValueToWrite
                ); 
            break;
        case IrCommandType:
                //Busca no arquivo
                //Abre arquivo
                char comandoIr[1024];
                char indexBusca[10]; 
                bool endOfFile = false;               
                
                //printf("\r\n===================DEBUG(Schedule)===================\r\n");
                //"Ir:0,6E01FFFFS"
                sprintf(indexBusca,"Ir:%u,",schedules[index].param3);
                //printf("indexBusca = <%s>.\r\n",indexBusca);
                if(sdCard::abreArquivo(&sdCard::devices,"r")){                
                    do{
                        fgets(comandoIr,1024,sdCard::devices.fp);                                            
                        endOfFile = feof(sdCard::devices.fp);                        
                        //printf("Linha comando Ir = <%s>.\r\nendOfFile = %u\r\n",comandoIr,endOfFile);
                    }while((strstr(comandoIr,indexBusca)==NULL)&&(endOfFile==0));                    
                    sdCard::fechaArquivo(&sdCard::devices);
                    
                    //Vê se deu tudo certo, se não encontrou, retorna false
                    if(!endOfFile){
                        //Encontrado o comando, vou desempacotar ele.
                        strtok(comandoIr,",");                        
                        //Neste ponto já tenho o meu comando pronto para ser executado dentro de comandoIr;
                        //printf("\r\n\r\n\r\nEstou enviando o comando %s de dentro do schedule.\r\n\r\n\r\n",strtok(NULL,"S"));
                        deserializaPacoteIR(strtok(NULL,"S"));
                        enviaComandoIR(schedules[index].param1,schedules[index].param2);    
                    }                    
                }else{
                    return false;
                 }
                //printf("\r\n===================DEBUG(Schedule)===================\r\n");
            break;        
    }  
    return true;  
}
*/
/*
uint8_t execActAlarm(uint32_t index){
    switch(alarms[index].actType){        
        case modBusType_float:
                float floatValueToWrite;
                //writeFloat(uint8_t,uint16_t,uint8_t,float*);
                floatToBin(0,&floatValueToWrite,&alarms[index].actValue[0]);                    
                modBusMaster1::writeFloat(
                    alarms[index].addrModbusWrite,
                    alarms[index].funcModbusWrite,
                    alarms[index].regModbusWrite,
                    &floatValueToWrite
                );                    
            break;
        case modBusType_uint32_t:
                uint32_t uint32ValueToWrite;                
                uint32_t_ToBin(0,&uint32ValueToWrite,&alarms[index].actValue[0]);                    
                modBusMaster1::writeRegister32BIT(
                    alarms[index].addrModbusWrite,
                    alarms[index].funcModbusWrite,
                    alarms[index].regModbusWrite,
                    &uint32ValueToWrite
                );                    
            break;
        case modBusType_uint16_t:
                uint16_t uint16ValueToWrite;                
                uint16_t_ToBin(0,&uint16ValueToWrite,&alarms[index].actValue[0]);                    
                modBusMaster1::writeRegister16BIT(
                    alarms[index].addrModbusWrite,
                    alarms[index].funcModbusWrite,
                    alarms[index].regModbusWrite,
                    &uint16ValueToWrite
                ); 
            break;
        case modBusType_bit:
                bool boolValueToWrite;                
                boolValueToWrite = (alarms[index].actValue[0] != 0);                    
                modBusMaster1::writeSingleCoil(
                    alarms[index].addrModbusWrite,                    
                    alarms[index].regModbusWrite,
                    boolValueToWrite
                ); 
            break;        
    }  
    return true;  
}
*/

void setReading(char *linha)
{
    uint8_t  addr=0;
    uint8_t  func=0;
    uint16_t  reg=0;
    uint8_t  numRegs=0;
    char *pChar;
    bool inputData = false;
    
    //printf("Linha <%s>.\n",linha);
    if(strstr(linha,"readingsSet")) {
        return;
    }

    numReadings++;
    
    if(strstr(linha,"float,")) {
        readings[numReadings-1].type=modBusType_float;                
        inputData = true;
    }

    if(strstr(linha,"int32_t,")) {
        readings[numReadings-1].type=modBusType_int32_t;
        inputData = true;
    }
    
    if(strstr(linha,"int16_t,")) {
        readings[numReadings-1].type=modBusType_int16_t;
        inputData = true;
    }    

    if(strstr(linha,"uint32_t,")) {
        readings[numReadings-1].type=modBusType_uint32_t;
        inputData = true;
    }
    
    if(strstr(linha,"uint16_t,")) {
        readings[numReadings-1].type=modBusType_uint16_t;
        inputData = true;
    }    
    
    if(strstr(linha,"uint8_t,")) {
        readings[numReadings-1].type=modBusType_uint8_t;
        inputData = true;
    }
    
    if(strstr(linha,"bit,")) {
        readings[numReadings-1].type=modBusType_bit;
        inputData = true;
    }
    
    if(inputData){
        pChar = strtok(linha,",");
        
        pChar = strtok(NULL,",");
        addr = atoi(pChar);        
        
        pChar = strtok(NULL,",");
        func = atoi(pChar);        
        
        pChar = strtok(NULL,",");
        reg = atoi(pChar);        
        
        pChar = strtok(NULL,",");
        numRegs = atoi(pChar);
        
        readings[numReadings-1].addr=addr;
        readings[numReadings-1].func=func;
        readings[numReadings-1].reg=reg;
        readings[numReadings-1].numRegs=numRegs;    
    }
    
}

void setAlarm(char *linha)
{    
    float floatVar;
    uint32_t aux32_t;
    uint16_t aux16_t;
    char *pChar;    

    if(strstr(linha,"alarmSet")) {
            //Inicialização de contadores de alarme
            //É necessário inicializar estes dados para quando a máquina de alarmes rodar ter um inicio correto.
            alarms[alarmes].secAlarm=0;
            alarms[alarmes].idAct=0;
            alarms[alarmes].on=0;
            alarms[alarmes].alarmFound = true;
            //Inicialização de contadores de alarme            
            alarmes++;            
            return;
    }

    if(strstr(linha,"idAlarm:")){
        strtok(linha,":");
        alarms[alarmes-1].id = atoi(strtok(NULL,"\r\n"));
        return;
    }
    
    if(strstr(linha,"seconds:")) {        
        strtok(linha,":");
        pChar = strtok(NULL,"\r\n");
        alarms[alarmes-1].seconds = atoi(pChar);
        return;
    }    
    
    if(strstr(linha,"on:")) {        
        strtok(linha,":");
        pChar = strtok(NULL,"\r\n");
        alarms[alarmes-1].on = atoi(pChar);
        return;
    }
    
    if(strstr(linha,"idAct:")) {        
        strtok(linha,":");        
        alarms[alarmes-1].idAct = atoi(strtok(NULL,""));
        return;
    }

    if(strstr(linha,"bit,")){
        alarms[alarmes-1].type=modBusType_bit;

        pChar = strtok(linha,",");        
        
        //Parametro1
        pChar = strtok(NULL,",");
        alarms[alarmes-1].addrModbusRead = atoi(pChar);    
        
        //Parametro2
        pChar = strtok(NULL,",");
        alarms[alarmes-1].funcModbusRead = atoi(pChar);
        
        //Parametro3
        pChar = strtok(NULL,",");
        alarms[alarmes-1].regModbusRead  = atoi(pChar);
        
        //Parametro4
        pChar = strtok(NULL,",");
        alarms[alarmes-1].max = (atoi(pChar) != 0); //Qualquer valor diferente de 0 é um
        
        //Parametro5
        pChar = strtok(NULL,",");
        alarms[alarmes-1].value[0]= (atoi(pChar) != 0); //Qualquer valor diferente de 0 é um
        return;
    }
    
    if(strstr(linha,"float,")) {
        alarms[alarmes-1].type=modBusType_float;        
        strtok(linha,",");
        
        //Parametro 1;
        pChar = strtok(NULL,",");
        alarms[alarmes-1].addrModbusRead = atoi(pChar);
        
        //Parametro 2;
        pChar = strtok(NULL,",");
        alarms[alarmes-1].funcModbusRead = atoi(pChar);
        
        //Parametro 3;
        pChar = strtok(NULL,",");
        alarms[alarmes-1].regModbusRead  = atoi(pChar);
        
        //Parametro 4;
        pChar = strtok(NULL,",");
        alarms[alarmes-1].max = (atoi(pChar) != 0); //Qualquer valor diferente de 0 é um
                       
        //Parametro 5;
        pChar = strtok(NULL,"\r\n");        
        //floatVar = diversos::stringToFloat(pChar,100);        
        floatVar = atof(pChar);        

        floatToBin(1,&floatVar,&alarms[alarmes-1].value[0]);
        return;
    }

    if(strstr(linha,"uint32_t,")) {
        alarms[alarmes-1].type=modBusType_uint32_t;
        //sscanf(linha,"max:uint32_t,%lu,%lu,%lu,%lu",&aux1,&aux2,&aux3,&aux4);
        strtok(linha,",");
        
        //parametro1
        pChar = strtok(NULL,",");
        alarms[alarmes-1].addrModbusRead = atoi(pChar);
        
        //parametro2
        pChar = strtok(NULL,",");
        alarms[alarmes-1].funcModbusRead = atoi(pChar);
        
        //parametro3
        pChar = strtok(NULL,",");
        alarms[alarmes-1].regModbusRead  = atoi(pChar);
    
        //Parametro 4;
        pChar = strtok(NULL,",");
        alarms[alarmes-1].max = (atoi(pChar) != 0); //Qualquer valor diferente de 0 é um
        
        //parametro5
        pChar = strtok(NULL,"\r\n");
        aux32_t = atoi(pChar);

        uint32_t_ToBin(1,&aux32_t,&alarms[alarmes-1].value[0]);
        return;
    }    
    
    
    
    if(strstr(linha,"uint16_t,")) {
        alarms[alarmes-1].type=modBusType_uint16_t;
        strtok(linha,",");
        
        //parametro1
        pChar = strtok(NULL,",");    
        alarms[alarmes-1].addrModbusRead = atoi(pChar);
        
        //parametro2
        pChar = strtok(NULL,",");
        alarms[alarmes-1].funcModbusRead = atoi(pChar);
        
        //parametro3
        pChar = strtok(NULL,",");
        alarms[alarmes-1].regModbusRead  = atoi(pChar);
        
        //Parametro 4;
        pChar = strtok(NULL,",");
        alarms[alarmes-1].max = (atoi(pChar) != 0); //Qualquer valor diferente de 0 é um
        
        //parametro5
        pChar = strtok(NULL,"\r\n");
        aux16_t = atoi(pChar);

        uint16_t_ToBin(1,&aux16_t,&alarms[alarmes-1].value[0]);
        return;
    }
    
    if(strstr(linha,"int32_t,")) {
        alarms[alarmes-1].type=modBusType_int32_t;
        //sscanf(linha,"max:uint32_t,%lu,%lu,%lu,%lu",&aux1,&aux2,&aux3,&aux4);
        strtok(linha,",");
        
        //parametro1
        pChar = strtok(NULL,",");
        alarms[alarmes-1].addrModbusRead = atoi(pChar);
        
        //parametro2
        pChar = strtok(NULL,",");
        alarms[alarmes-1].funcModbusRead = atoi(pChar);
        
        //parametro3
        pChar = strtok(NULL,",");
        alarms[alarmes-1].regModbusRead  = atol(pChar);
    
        //Parametro 4;
        pChar = strtok(NULL,",");
        alarms[alarmes-1].max = (atoi(pChar) != 0); //Qualquer valor diferente de 0 é um
        
        //parametro5
        pChar = strtok(NULL,"\r\n");
        aux32_t = atol(pChar);

        uint32_t_ToBin(1,&aux32_t,&alarms[alarmes-1].value[0]);
        return;
    }    
    
    
    
    if(strstr(linha,"int16_t,")) {
        alarms[alarmes-1].type=modBusType_int16_t;
        strtok(linha,",");
        
        //parametro1
        pChar = strtok(NULL,",");    
        alarms[alarmes-1].addrModbusRead = atoi(pChar);
        
        //parametro2
        pChar = strtok(NULL,",");
        alarms[alarmes-1].funcModbusRead = atoi(pChar);
        
        //parametro3
        pChar = strtok(NULL,",");
        alarms[alarmes-1].regModbusRead  = atoi(pChar);
        
        //Parametro 4;
        pChar = strtok(NULL,",");
        alarms[alarmes-1].max = (atoi(pChar) != 0); //Qualquer valor diferente de 0 é um
        
        //parametro5
        pChar = strtok(NULL,"\r\n");
        aux16_t = atoi(pChar);

        uint16_t_ToBin(1,&aux16_t,&alarms[alarmes-1].value[0]);
        return;
    }
}

void setSchedule(char *linha)
{    
    //float floatVar;
    //uint32_t aux32_t;
    //uint16_t aux16_t;
    char *pChar;
    
    if(strstr(linha,"scheduleSet")) {        
            //Inicialização de contadores de schedules
            //É necessário inicializar estes dados para quando a máquina de schedules rodar ter um inicio correto.                
            schedules[numSchedules].actSent = false;
            //Inicialização de contadores de schedules
            numSchedules++;
    }

    if(strstr(linha,"idSchedule:")) {
        strtok(linha,":");
        pChar = strtok(NULL,"");
        schedules[numSchedules-1].id = atoi(pChar);
    }

    if(strstr(linha,"dayTime:")) {
        strtok(linha,":");
        pChar = strtok(NULL,",");
        schedules[numSchedules-1].weekday = atoi(pChar);
        pChar = strtok(NULL,"");
        schedules[numSchedules-1].minute = atoi(pChar);
    }

    if(strstr(linha,"idAct:")) {
        strtok(linha,":");
        pChar = strtok(NULL,"");
        schedules[numSchedules-1].idAct = atoi(pChar);        
    }
    /*pc.printf("Debugando erro em scheduleSet.\r\n");
    pc.printf("Linha <%s>\r\n",linha);
    pc.printf("actSent = %lu",schedules[numSchedules-1].actSent);
    pc.printf("idSchedule = %lu",schedules[numSchedules-1].id);
    pc.printf("dayTime = %lu",schedules[numSchedules-1].weekday);
    pc.printf("idAct = %lu",schedules[numSchedules-1].idAct);    
    pc.printf("Debugando erro em scheduleSet.\r\n");*/
}

void setScheduleException(char *linha)
{    
    //float floatVar;
    //uint32_t aux32_t;
    //uint16_t aux16_t;
    char *pChar;
    if(strstr(linha,"scheduleExceptionSet")) {
            //Inicialização de contadores de schedulesExceptions
            numScheduleExceptions++;
    }

    if(strstr(linha,"idSchedule:")) {
        strtok(linha,":");
        scheduleExceptions[numScheduleExceptions-1].id_schedule = atoi(strtok(NULL,"\r\n"));
    }

    if(strstr(linha,"timestamp:")) {
        strtok(linha,":");
        pChar = strtok(NULL,",");
        scheduleExceptions[numScheduleExceptions-1].timestamp = atoi(pChar);
    }
}

/*void writeReadingsToSD(){    
    //Esta função faz a inserção de todos os dados no arquivo armazenamento.            
    uint16_t readingIndex=0;

    float *floatBuffer;
    uint32_t *uint32_tBuffer;
    uint16_t *uint16_tBuffer;
    bool *boolBuffer;
    uint32_t seconds_uint32_t;
    
    //char registro[1024];
    //uint16_t indexRegistro;
    
    seconds_uint32_t = (uint32_t) time(NULL);
    
    //Inicio da string dentro do arquivo binario
    sdCard::insereDadosBank("log{data:",9);            
    
    //O timestamp é posto nos 4 primeiros bytes (segundos)    
    sdCard::insereDadosBank(&sdCard::armazenamento,(char *)&seconds_uint32_t,4);
    
    for(readingIndex = 0;readingIndex < numReadings;readingIndex++){
        switch(readings[readingIndex].type){
            case modBusType_float:                    
                    floatBuffer = (float*) malloc(readings[readingIndex].numRegs*sizeof(float));                    
                    modBusMaster1::readFloat(
                        readings[readingIndex].addr,
                        readings[readingIndex].func,
                        readings[readingIndex].reg,
                        readings[readingIndex].numRegs,
                        floatBuffer
                    );
                    //pc.printf("Lido dentro de modBusMaster1::teste() <%f>.\n",modBusMaster1::teste());
                    sdCard::insereDadosBank((char *)floatBuffer,sizeof(float)*readings[readingIndex].numRegs);
                    free(floatBuffer);
                break;
            case modBusType_uint32_t:
                    uint32_tBuffer = (uint32_t*) malloc(readings[readingIndex].numRegs*sizeof(uint32_t));                                        
                    modBusMaster1::readRegister32BIT(
                        readings[readingIndex].addr,
                        readings[readingIndex].func,
                        readings[readingIndex].reg,
                        readings[readingIndex].numRegs,
                        uint32_tBuffer
                    );
                    //pc.printf("Lido dentro de modBusMaster1::teste() <%f>.\n",modBusMaster1::teste());
                    sdCard::insereDadosBank((char *)uint32_tBuffer,sizeof(uint32_t)*readings[readingIndex].numRegs);
                    free(uint32_tBuffer);            
                break;
                
            case modBusType_uint16_t:
                    uint16_tBuffer = (uint16_t*) malloc(readings[readingIndex].numRegs*sizeof(uint16_t));                                        
                    modBusMaster1::readRegister16BIT(
                        readings[readingIndex].addr,
                        readings[readingIndex].func,
                        readings[readingIndex].reg,
                        readings[readingIndex].numRegs,
                        uint16_tBuffer
                    );
                    //pc.printf("Lido dentro de modBusMaster1::teste() <%f>.\n",modBusMaster1::teste());
                    sdCard::insereDadosBank((char *)uint16_tBuffer,sizeof(uint16_t)*readings[readingIndex].numRegs);
                    free(uint16_tBuffer); 
                break;
            
            case modBusType_bit:
                    boolBuffer = (bool*) malloc(readings[readingIndex].numRegs*sizeof(bool));                                        
                    modBusMaster1::readCoils(
                        readings[readingIndex].addr,                        
                        readings[readingIndex].reg,
                        readings[readingIndex].numRegs,
                        boolBuffer
                    );
                    //pc.printf("Lido dentro de modBusMaster1::teste() <%f>.\n",modBusMaster1::teste());
                    sdCard::insereDadosBank((char *)boolBuffer,sizeof(bool)*readings[readingIndex].numRegs);
                    free(boolBuffer); 
                break;
            
        }
    }    
    sdCard::insereDadosBank("}log",4);
}*/

uint8_t execAct(uint32_t index){
    //Primeiro preciso decidir que tipo de act estou lidando para tanto preciso pegar a ACT inteira.
    //Busca no arquivo
    //Abre arquivo
    char actString[1024];
    char indexBusca[15];
    char alarmsSetString[256];
    char alarmsResetString[256];    
    char *pTipoComando; 
    uint8_t tipoComando=0;
    bool endOfFile = false;
    uint8_t indexAlarms=0;    
    char *pChar;
    bool commandExecOk = true;
    uint8_t i;
    
    //Variáveis comuns;
    uint8_t param1;
    uint8_t param2;
    uint16_t param3;
    uint32_t param4;
    
    //printf("\r\n===================DEBUG(execAct)===================\r\n"); 
    sprintf(indexBusca,"idAct:%lu;",index);
    pc.printf("Lido <%s>.\r\n",indexBusca);
    //printf("Buscando por indexBusca<%s>.\r\n",indexBusca);  
    if(sdCard::abreArquivo(&sdCard::devices,"r")){
        do{
            endOfFile = feof(sdCard::devices.fp);                        
            if(!endOfFile){fgets(actString,1024,sdCard::devices.fp);}            
        }while((strstr(actString,"actList")==NULL)&&(endOfFile==0));
        pc.printf("Achei o actList.\r\n");
        do{
            endOfFile = feof(sdCard::devices.fp);
            if(!endOfFile){fgets(actString,1024,sdCard::devices.fp);}
            //printf("Linha ACT = <%s>.\r\nendOfFile = %u\r\n",actString,endOfFile);
        }while((strstr(actString,indexBusca)==NULL)&&(endOfFile==0));
        sdCard::fechaArquivo(&sdCard::devices);
        
        //Vê se deu tudo certo, se não encontrou, retorna false
        if(endOfFile){
            return false;
        }
        //Tudo correndo bem.
        
        //printf("\r\nPoint 1\r\n");
        
        //Encontrado o tipo de comando reutilizando a string indexBusca;
        pChar = strtok(actString,";");
        pc.printf("1- <%s>.\r\n",pChar);
        pChar = strtok(NULL,";");
        strcpy(alarmsSetString,pChar);
        pChar = strtok(NULL,";");
        strcpy(alarmsResetString,pChar);               
        
        pTipoComando = strtok(NULL,",");        
        
        printf("\r\nPoint 2 comando <%s>\r\n",pTipoComando);
        if(strstr(pTipoComando,"float")){tipoComando = modBusType_float;}
        if(strstr(pTipoComando,"bit")){tipoComando = modBusType_bit;}
        if(strstr(pTipoComando,"uint8_t")){tipoComando = modBusType_uint8_t;}
        if(strstr(pTipoComando,"int16_t")){tipoComando = modBusType_int16_t;}
        if(strstr(pTipoComando,"int32_t")){tipoComando = modBusType_int32_t;}
        if(strstr(pTipoComando,"uint16_t")){tipoComando = modBusType_uint16_t;}
        if(strstr(pTipoComando,"uint32_t")){tipoComando = modBusType_uint32_t;}        
        if(strstr(pTipoComando,"IR")){tipoComando = IrCommandType;}
        if(strstr(pTipoComando,"PWM")){tipoComando = PWMCommandType;}        
    }else{
            return false;
     }
     
    switch(tipoComando){        
        case modBusType_float:
                float floatValueToWrite;
                uint32_t auxMod;
                param1 = atoi(strtok(NULL,","));
                param2 = atoi(strtok(NULL,","));
                param3 = atoi(strtok(NULL,","));                
                //floatValueToWrite = diversos::stringToFloat(strtok(NULL,","),100);                
                floatValueToWrite = atof(strtok(NULL,","));

                //Envio comando via Modbus                
                if(modBusMaster1::writeFloat(
                    param1,
                    param3,
                    1,
                    &floatValueToWrite
                )){commandExecOk = false;}
            break;
        case modBusType_uint32_t:
        case modBusType_int32_t:                
                param1 = atoi(strtok(NULL,","));
                param2 = atoi(strtok(NULL,","));
                param3 = atoi(strtok(NULL,","));
                param4 = atol(strtok(NULL,","));                
                
                if(modBusMaster1::writeRegister32BIT(
                    param1,
                    param3,
                    1,
                    &param4
                )){commandExecOk = false;}
            break;
        case modBusType_uint16_t:
        case modBusType_int16_t:
                uint16_t param4_uint16_t;
                param1 = atoi(strtok(NULL,","));
                param2 = atoi(strtok(NULL,","));
                param3 = atoi(strtok(NULL,","));
                param4_uint16_t = atoi(strtok(NULL,","));                
                
                if(modBusMaster1::writeRegister16BIT(
                    param1,
                    param3,
                    1,
                    &param4_uint16_t
                )){commandExecOk = false;}
            break;
        case modBusType_bit:                
                param1 = atoi(strtok(NULL,","));
                param2 = atoi(strtok(NULL,","));
                param3 = atoi(strtok(NULL,","));
                param4 = atoi(strtok(NULL,","));
                
                if(param1 != 254){
                    //Envia comando via Modbus
                    if(modBusMaster1::writeSingleCoil(
                        param1,                    
                        param3,
                        (bool)param4
                    )){commandExecOk = false;}
                }else{
                    //Executa comando interno;
                    switch(param3){
                        case 0:
                                SD1.write(param4*1.0f);
                            break;
                        case 1:
                                SD2.write(param4*1.0f);
                            break;
                        case 2:
                                SD3.write(param4*1.0f);
                            break;
                        case 3:
                                SD4.write(param4*1.0f);
                            break;
                        case 4:
                                SD5.write(param4*1.0f);
                            break;
                        case 5:
                                SD6.write(param4*1.0f);
                            break;
                        case 6:
                                SD7 = param4;
                            break;                            
                        case 7:
                                SD8 = param4;
                            break;                            
                    }   
                 }
            break;
        case IrCommandType:
                //Busca no arquivo
                //Abre arquivo                
                //printf("\r\nIniciando execucao de comando IR\r\n");
                param1 = atoi(strtok(NULL,","));
                param2 = atoi(strtok(NULL,","));          
                //printf("\r\nparam 1 %lu, param2 %lu\r\n",param1,param2);
                pTipoComando = strtok(NULL,"S");//Reaproveitando variável pTipoComando
                //printf("\r\nPacote IR <%s>.\r\n",pTipoComando);    
                deserializaPacoteIR(pTipoComando);
                //printf("Deserializado.\r\nInicio do envio.\r\n");
                if(param1){
                    enviaComandoIR(param1,param2);
                }else{
                    for(i=33;i<41;i++){
                        enviaComandoIR(i,param2);
                        if(i!=40){osDelay(100);}    
                    } 
                 }
                //printf("Fim do envio.\r\n");
            break;
        
        case PWMCommandType:
                //float floatValuePWM;
                //uint32_t auxPeriod;
                param1 = atoi(strtok(NULL,","));
                param2 = atoi(strtok(NULL,","));
                param3 = atoi(strtok(NULL,","));                
                //floatValueToWrite = diversos::stringToFloat(strtok(NULL,","),100);                
                floatValueToWrite = atof(strtok(NULL,","));
                
                //Executa comando interno;
                auxMod = floatValueToWrite/10;
                floatValueToWrite = floatValueToWrite-(auxMod*10);
                SD1.period_us(auxMod);
                pwmPeriod = auxMod;
                switch(param3){
                    case 0:                                
                            SD1.write(floatValueToWrite);
                        break;
                    case 1:
                            SD2.write(floatValueToWrite);
                        break;
                    case 2:
                            SD3.write(floatValueToWrite);
                        break;
                    case 3:
                            SD4.write(floatValueToWrite);
                        break;
                    case 4:
                            SD5.write(floatValueToWrite);
                        break;
                    case 5:
                            SD6.write(floatValueToWrite);
                        break;                                                 
                }                
            break;
        
        default:
                //printf("comando nao encontrado\r\n");
            break;        
    }
    //Coletando dados do alarmSet e alarmReset    
    
    pChar = strtok(alarmsSetString,",");
    while(pChar!=NULL){
        pc.printf("Lido Alarm Set %lu - <%lu>.\r\n",indexAlarms,atoi(pChar));
        if(atoi(pChar)){
            alarmOnOff(atoi(pChar),1);
        }
        pChar = strtok(NULL,",");
    }
    
    pChar = strtok(alarmsResetString,",");
    while(pChar!=NULL){
        pc.printf("Lido Alarm Reset %lu - <%lu>.\r\n",indexAlarms,atoi(pChar));
        if(atoi(pChar)){
            alarmOnOff(atoi(pChar),0);
        }
        pChar = strtok(NULL,",");
    }
    
    //printf("\r\n===================DEBUG(execAct)===================\r\n");    
    return commandExecOk;  
}

void alarmOnOff(uint32_t idAlarm,bool state){
    uint16_t alarmIndex;
    char indexBusca[30];    
    char alarmString[40];
    uint32_t seekPosition;
    bool endOfFile;
    char charState;
    
    for(alarmIndex = 0; alarmIndex < alarmes; alarmIndex++){
        if(alarms[alarmIndex].id == idAlarm){
            alarms[alarmIndex].on = state;
        }    
    }    
    
    if(!sdCard::abreArquivo(&sdCard::devices,"rb+")){return;}    
    
    sprintf(indexBusca,"idAlarm:%lu\r",idAlarm);    
    do{
        endOfFile = feof(sdCard::devices.fp);                        
        if(!endOfFile){fgets(alarmString,40,sdCard::devices.fp);}
    }while((strstr(alarmString,indexBusca)==NULL)&&(endOfFile==0));
    
    
    do{
        endOfFile = feof(sdCard::devices.fp);                        
        if(!endOfFile){fgets(alarmString,40,sdCard::devices.fp);}
    }while((strstr(alarmString,"on:")==NULL)&&(endOfFile==0));
                            
    
    if(endOfFile){
        sdCard::fechaArquivo(&sdCard::devices);
        return;
    }
    
    seekPosition = ftell(sdCard::devices.fp)-3;
    fseek(sdCard::devices.fp,seekPosition,SEEK_SET);
    if(state){charState='1';}else{charState='0';}    
    fputc(charState,sdCard::devices.fp);
    //fprintf(sdCard::devices.fp,"%u",state);
    fflush(sdCard::devices.fp);
    sdCard::fechaArquivo(&sdCard::devices);            
}

void writeReadingsToSD(){ 
    //Buffering before insertData   
    //Esta função faz a inserção de todos os dados no arquivo armazenamento.            
    uint16_t readingIndex=0;    
    /*
    union {
        char c[4];
        float v;
    }uFloat;
    */
    float *floatBuffer;
    uint32_t *uint32_tBuffer;
    uint16_t *uint16_tBuffer;    
    bool *boolBuffer;    
    uint32_t seconds_uint32_t;
    char seconds_char[5];    
    
    seconds_uint32_t = (uint32_t) time(NULL);
    seconds_char[0]=(seconds_uint32_t >> 0) & 0xFF;
    seconds_char[1]=(seconds_uint32_t >> 8) & 0xFF;
    seconds_char[2]=(seconds_uint32_t >> 16) & 0xFF;
    seconds_char[3]=(seconds_uint32_t >> 24) & 0xFF;
    seconds_char[4]=0;
    
    
    //Inicio da string dentro do arquivo binario
    sdCardBuf.del();
    sdCardBuf.fill("log{data:",9);            
    
    //O timestamp é posto nos 4 primeiros bytes (segundos)    
    sdCardBuf.fill(seconds_char,5);
    
    for(readingIndex = 0;readingIndex < numReadings;readingIndex++){
        diversos::wdt.kick(180.0);
        switch(readings[readingIndex].type){
            case modBusType_float:                    
                    if(readings[readingIndex].addr != enderecoControladoraVirtual){
                        //Busca fora do drome via Modbus
                        floatBuffer = (float*) malloc(((readings[readingIndex].numRegs*sizeof(float))+1)); //Alocando mais um byte para status
                        ((char *)floatBuffer)[(readings[readingIndex].numRegs*sizeof(float))] = modBusMaster1::readFloat(
                            readings[readingIndex].addr,
                            readings[readingIndex].func,
                            readings[readingIndex].reg,
                            readings[readingIndex].numRegs,
                            floatBuffer
                        );    
                    }else{
                        //Busca Interna
                        floatBuffer = (float*) malloc(sizeof(float));
                        if((readings[readingIndex].reg<100)&&(readings[readingIndex].reg < num_temperatureSensors)){//Registradores das entradas de temperatura
                            //Populando floatBuffer com a temperaturas                            
                            floatBuffer[0] = temperaturas[readings[readingIndex].reg];                            
                        }
                        if((readings[readingIndex].reg>=100)&&(readings[readingIndex].reg<104)){
                            //Registradores das entradas analógicas                            
                            floatBuffer[0] = aiFiltrada[readings[readingIndex].reg - 100];                            
                        }
                        readings[readingIndex].numRegs = 1;
                     }
                    
                    //pc.printf("Lido dentro de modBusMaster1::teste() <%f>.\n",modBusMaster1::teste());
                    sdCardBuf.fill((char *)floatBuffer,((sizeof(float)*readings[readingIndex].numRegs)+1));//Ao fim appendo o byte de status
                    free(floatBuffer);
                break;
            case modBusType_uint32_t:
            case modBusType_int32_t:                    
                    if(readings[readingIndex].addr != enderecoControladoraVirtual){
                        uint32_tBuffer = (uint32_t*) malloc((readings[readingIndex].numRegs*sizeof(uint32_t))+1); //Alocando mais um byte para status
                        ((char *)uint32_tBuffer)[(readings[readingIndex].numRegs*sizeof(uint32_t))] = modBusMaster1::readRegister32BIT(//Ponho o status no ultimo byte
                            readings[readingIndex].addr,
                            readings[readingIndex].func,
                            readings[readingIndex].reg,
                            readings[readingIndex].numRegs,
                            uint32_tBuffer
                        );
                        //pc.printf("Lido dentro de modBusMaster1::teste() <%f>.\n",modBusMaster1::teste());
                    }else{
                        uint32_tBuffer = (uint32_t*) malloc(sizeof(uint32_t)+1); //Alocando mais um byte para status
                        uint32_tBuffer[0] = pulsosEDs[readings[readingIndex].reg];
                        readings[readingIndex].numRegs = 1;
                        pulsosEDs[readings[readingIndex].reg] = 0;
                     }
                    sdCardBuf.fill((char *)uint32_tBuffer,((sizeof(uint32_t)*readings[readingIndex].numRegs)+1));//Ao fim appendo o byte de status
                    free(uint32_tBuffer);            
                break;
                
            case modBusType_uint16_t:
            case modBusType_int16_t:
                    if(readings[readingIndex].addr!=enderecoControladoraVirtual){
                        uint16_tBuffer = (uint16_t*) malloc(((readings[readingIndex].numRegs*sizeof(uint16_t))+1));//Alocando mais um byte para status
                        ((char *)uint16_tBuffer)[(readings[readingIndex].numRegs*sizeof(uint16_t))] = modBusMaster1::readRegister16BIT(//
                            readings[readingIndex].addr,
                            readings[readingIndex].func,
                            readings[readingIndex].reg,
                            readings[readingIndex].numRegs,
                            uint16_tBuffer
                        );
                        //pc.printf("Lido dentro de modBusMaster1::teste() <%f>.\n",modBusMaster1::teste());
                        sdCardBuf.fill((char *)uint16_tBuffer,((sizeof(uint16_t)*readings[readingIndex].numRegs)+1));//Ao fim appendo o byte de status
                        free(uint16_tBuffer); 
                    }else{                        
                        if((readings[readingIndex].reg>0)&&((readings[readingIndex].reg + readings[readingIndex].numRegs)<=4)){                                                        
                            sdCardBuf.fill((char *)&aiFiltrada[readings[readingIndex].reg-1],sizeof(uint16_t)*readings[readingIndex].numRegs);
                            seconds_char[4]=0;
                            sdCardBuf.fill((char *)&seconds_char[4],1);
                        }
                     }
                break;
            
            case modBusType_bit:
                    boolBuffer = (bool*) malloc(sizeof(bool)+1);//Alocando mais um byte para status
                    if(readings[readingIndex].addr != enderecoControladoraVirtual){                        
                        ((char *)boolBuffer)[(readings[readingIndex].numRegs*sizeof(bool))] = modBusMaster1::readCoils(
                            readings[readingIndex].addr,                        
                            readings[readingIndex].reg,
                            readings[readingIndex].numRegs,
                            boolBuffer
                        );
                    }else{                        
                        boolBuffer[0] = entradasDigitais[readings[readingIndex].reg];
                        ((char *)boolBuffer)[1]=0;
                     }
                    //pc.printf("Lido dentro de modBusMaster1::teste() <%f>.\n",modBusMaster1::teste());
                    sdCardBuf.fill((char *)boolBuffer,((sizeof(bool)*readings[readingIndex].numRegs)+1));//Ao fim appendo o byte de status
                    free(boolBuffer); 
                break;
            
        }
    }    
    readingIndex = sdCardBuf.fill("}log",4); //Reaproveitando a variável de 16bit readingIndex
    sdCard::arquivoAberto(40000);
    //Insiro os dados se for possível.
    sdCard::insereDadosBank(sdCardBuf.get(),readingIndex);
}










int criaDevices(FILE *devicesCfg)
{
    char linha[maxCaractereLeLinha];
    int linhas = 0;
    devices = 0;

    while(fgets(linha,maxCaractereLeLinha,devicesCfg)) {
        if(strstr(linha,"deviceCreate\\")) {
            devices++;
        }
        linhas++;
    }

    printf("Contei %u linha(s), %u device(s).\n",linhas,devices);    
        
    alarmes=0;
    numSchedules=0;
    numScheduleExceptions=0;
    numReadings=0;
    rewind(devicesCfg);    
    return 1;
}


int configuraDevices(FILE *devicesCfg)
{
    
    //uint16_t leituras = 0;
    char linha[maxCaractereLeLinha];
    uint8_t estadoConfiguracao=estadoConfiguracao_idle;
    alarmes = 0;
    bool condicaoDeSaida = false;

    while(fgets(linha,maxCaractereLeLinha,devicesCfg)&&(!condicaoDeSaida)){
        if(strstr(linha,"deviceCreate\\")) {            
            //printf("Configurando dispositivo de indice %u.\n",dispositivoEmConfiguracao);
            estadoConfiguracao = estadoConfiguracao_creatingDevice;
        }

        if(strstr(linha,"alarmSet")) {
            //printf("Criando alarme no dispositivo de indice %u.\n",dispositivoEmConfiguracao);
            //alarmes++;
            estadoConfiguracao = estadoConfiguracao_alarmSet;
        }

        if(strstr(linha,"readingsEnd")) {
            //printf("Criando leituras no dispositivo de indice %u.\n",dispositivoEmConfiguracao);
            estadoConfiguracao = estadoConfiguracao_idle;
        }

        if(estadoConfiguracao == estadoConfiguracao_readingsSet){
            leituras++;
        }


        if(strstr(linha,"readingsSet")) {
            //printf("Criando leituras no dispositivo de indice %u.\n",dispositivoEmConfiguracao);            
            estadoConfiguracao = estadoConfiguracao_readingsSet;
        }

        if(strstr(linha,"scheduleExceptionSet")) {
            //printf("Criando leituras no dispositivo de indice %u.\n",dispositivoEmConfiguracao);
            qtdScheduleExceptions++;
            estadoConfiguracao = estadoConfiguracao_scheduleExceptionSet;
        }        
        
        if(strstr(linha,"scheduleSet")) {
            //printf("Criando leituras no dispositivo de indice %u.\n",dispositivoEmConfiguracao);
            qtdSchedules++;
            estadoConfiguracao = estadoConfiguracao_scheduleSet;
        }        

        if(strstr(linha,">")) {
            //printf("Fechando dispositivo de indice %u.\n",dispositivoEmConfiguracao);
            condicaoDeSaida = true;
            estadoConfiguracao = estadoConfiguracao_idle;
        }

        switch(estadoConfiguracao) {
            case estadoConfiguracao_creatingDevice:
                /*if(strstr(linha,"id:")) {
                    sscanf(linha,"id:%u",&id);                    
                }*/
                break;
            case estadoConfiguracao_alarmSet:
                //Inclue linha nos alarmes do dispositivo em configuração
                setAlarm(linha);
                break;
            case estadoConfiguracao_readingsSet:
                //Inclue linha nas leituras do dispositivo em configuração
                setReading(linha);
                break;
            case estadoConfiguracao_scheduleSet:
                //Inclue linha nos agendamentos do dispositivo em configuração
                setSchedule(linha);
                break;
            case estadoConfiguracao_scheduleExceptionSet:
                //Inclue linha nas excessões dos agendamentos do dispositivo em configuração
                setScheduleException(linha);
                break;                
        }
    }    
    return 1;
}



void testaTudoDevices()
{
    int j;
    
    printf("O dispositivo tem %u alarmes sendo eles:\n",alarmes);

    for(j=0; j<alarmes; j++) {
        printf("Alarme %u:\n",j);
        printf("\tId <%lu>.\n",alarms[j].id);
        printf("\tSeconds <%lu>.\n",alarms[j].seconds);
        printf("\tAddr %u, func %u, reg %lu.\n",alarms[j].addrModbusRead,alarms[j].funcModbusRead,alarms[j].regModbusRead);
        if(alarms[j].type==modBusType_float) {
            float value;
            floatToBin(0,&value,&alarms[j].value[0]);                
            if(alarms[j].max){
                printf("\tFloat max <%f>.\n",value);
            }
            else{printf("\tFloat min <%f>.\n",value);}
        }
        
        if(alarms[j].type==modBusType_uint32_t) {
            uint32_t value;
            uint32_t_ToBin(0,&value,&alarms[j].value[0]);
            if(alarms[j].max){
                printf("\tuint32_t max <%lu>.\n",value);
            }
            else{printf("\tuint32_t min <%lu>.\n",value);}
        }
        
        if(alarms[j].type==modBusType_uint16_t) {
            uint16_t value;
            uint16_t_ToBin(0,&value,&alarms[j].value[0]);
            if(alarms[j].max){
                printf("\tuint16_t max <%lu>.\n",value);
            }
            else{printf("\tuint16_t min <%lu>.\n",value);}
        }            
        
        if(alarms[j].type==modBusType_int32_t) {
            uint32_t value;
            uint32_t_ToBin(0,&value,&alarms[j].value[0]);
            if(alarms[j].max){
                printf("\tint32_t max <%ld>.\n",(int32_t)value);
            }
            else{printf("\tint32_t min <%ld>.\n",(int32_t)value);}
        }
        
        if(alarms[j].type==modBusType_int16_t) {
            uint16_t value;
            uint16_t_ToBin(0,&value,&alarms[j].value[0]);
            if(alarms[j].max){
                printf("\tint16_t max <%ld>.\n",(int16_t)value);
            }
            else{printf("\tint16_t min <%ld>.\n",(int16_t)value);}
        }            
        
        if(alarms[j].type==modBusType_bit) {
            uint8_t value;
            value=alarms[j].value[0];                
            if(alarms[j].max){
                printf("\tBIT max <%lu>.\n",value);
            }
            else{printf("\tBIT min <%lu>.\n",value);}
        }            
        
        printf("\tact:%lu\n",alarms[j].idAct);
    }
    
    printf("O dispositivo tem %u schedules sendo eles:\n",numSchedules);        
    for(j=0; j<numSchedules; j++) {
        printf("Schedule %u:\n",j);
        printf("\tId <%lu>.\n",schedules[j].id);
        printf("\tweekday <%lu>.\n",schedules[j].weekday);
        printf("\tminute <%lu>.\n",schedules[j].minute);
        printf("\tidAct <%lu>.\n",schedules[j].idAct);
    }
    
    printf("O dispositivo tem %u scheduleExceptions sendo eles:\n",numScheduleExceptions);        
    for(j=0; j<numScheduleExceptions; j++) {
        printf("scheduleException %u:\n",j);
        printf("\tid_schedule <%lu>.\n",scheduleExceptions[j].id_schedule);
        printf("\ttimestamp <%lu>.\n",scheduleExceptions[j].timestamp);            
    }

    printf("O dispositivo tem %u leituras sendo elas:\n",numReadings);
    for(j=0; j<numReadings; j++) {
        printf("Leitura %u:",j);
        switch(readings[j].type) {
            case modBusType_float:
                    printf("Tipo float ");
                break;
            case modBusType_uint32_t:
                    printf("Tipo uint32_t ");
                break;
            case modBusType_uint16_t:
                    printf("Tipo uint16_t ");
                break;
            case modBusType_int32_t:
                    printf("Tipo int32_t ");
                break;
            case modBusType_int16_t:
                    printf("Tipo int16_t ");
                break;
            case modBusType_uint8_t:
                    printf("Tipo uint8_t ");
                break;
            case modBusType_bit:
                    printf("Tipo bool ");
                break;
        }
        printf("addr %u, func %u, reg %u, numRegs %u.\n",readings[j].addr,readings[j].func,readings[j].reg,readings[j].numRegs);
    }
}