emma controller code in production board v1
Dependencies: ADE7758_v1 Crypto DHT11 MQTT MbedJSONValueEmma SDFileSystem TFT_ILI9341 SWSPI SetRTC TFT_fonts Touch W5500Interface mbed-rtos mbed-src SoftSerial
Fork of emma_controller_energy by
emmaCode.cpp
- Committer:
- arsenalist
- Date:
- 2015-08-20
- Revision:
- 43:612547648ed1
- Parent:
- 42:b32e51a374c7
- Child:
- 44:c1d11c491237
File content as of revision 43:612547648ed1:
#include "emmaCode.h" //init debug port Serial DBG(PA_9, PA_10); //tx, rx //init wifi port Serial _ESP(PA_2, PA_3); //tx, rx //init espduino - without ch_pd pin ESP esp(&_ESP, &DBG, ESP_BAUD); //init wifi mqtt //ESPMQTT mqtt(&esp); //init wifi rest REST rest(&esp); //init eth port SPI spi(PB_15, PB_14, PB_13); //mosi, miso, sck MQTTEthernet ipstack(&spi, PB_12, PC_6); //spi, cs, reset //MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); //init sd card SDFileSystem sd(PA_7, PA_6, PA_5, PB_3, "sd"); //mosi, miso, sck, cs //init ade7758 - without cs pin ADE7758 ADE(PB_6, PB_4, PB_5, PB_7); //mosi, miso, sck, irq //init tft lcd SPI_TFT_ILI9341 TFT(PA_7, PA_6, PA_5, PA_4, PC_5, PC_4,"TFT"); //mosi, miso, sclk, cs, reset, dc //init touch screen - without cs pin TouchScreenADS7843 TP(PB_10, PB_0, PB_1, PB_2, &TFT); //mosi, miso, sclk, irq, tft //init dht sensor DHT11 d(PD_2); //emma settings string emmaUID; string hmac; string appNAME; string mqttDOMAIN; string mqttKEY; string mqttSECRET; string mqttSERVER; string mqttPORT; string restSERVER; string restPORT; string wifiSSID; string wifiPASS; string gprsAPN; string proxySERVER; string proxyPORT; string proxyAUTH; //nodes settings class NODES { public: REST *restConn; NODES(REST *r); int type; string macAddr; string ipAddr; }; NODES::NODES(REST *r) { restConn = r; } REST restObj[NODES_MAX] = {REST(&esp),REST(&esp),REST(&esp),REST(&esp),REST(&esp)}; NODES nodes[NODES_MAX] = {NODES(&restObj[0]),NODES(&restObj[1]),NODES(&restObj[2]),NODES(&restObj[3]),NODES(&restObj[4])}; //mode box class for main menu class modeBox { public: int xTL; //TopLeft int yTL; int xBR; //BottomRight int yBR; string text; string name; }; //ade7758 variables uint32_t AWattHrValue, BWattHrValue, CWattHrValue; uint32_t AVAHrValue, BVAHrValue, CVAHrValue; uint32_t AWattHrSum = 0; uint32_t BWattHrSum = 0; uint32_t CWattHrSum = 0; float AWattHr, BWattHr, CWattHr; float AVrms, BVrms, CVrms; float AIrms, BIrms, CIrms; float AWatt, BWatt, CWatt; float XWattHr,XVrms,XWatt; //variables bool ethAvailable = false; bool wifiAvailable = false; bool gprsAvailable = false; bool ethConnected = false; bool wifiConnected = false; bool gprsConnected = false; bool useProxy = false; bool newCommand = false; bool espFreeMemory = true; //for after bootup bool espDHCPClientStart = false; bool newEnergyData = false; string globalCommand; string rxBuf; string rxLog; string rxLogA; /*start lcd and touch*/ int emmaModeSelection(void) { bool modeSelected = false; int md=0; int TPx; int TPy; Timer t; TFT.background(Black); TFT.foreground(White); TFT.set_font((unsigned char*) Arial12x12); TFT.set_orientation(1); TFT.cls(); TFT.locate(0,0); TFT.printf("Hello, I'm Emma!"); wait(2); TFT.cls(); Matrix matrix; Coordinate ScreenSample[3]; matrix.An = 580; matrix.Bn = 75980; matrix.Cn = -3410580; matrix.Dn = 57855; matrix.En = -2465; matrix.Fn = -3483515; matrix.Divider = 209144; ScreenSample[0].x = 230; ScreenSample[0].y = 167; ScreenSample[1].x = 754; ScreenSample[1].y = 163; ScreenSample[2].x = 771; ScreenSample[2].y = 562; TP.SetCalibration(&matrix, &ScreenSample[0]); //draw border TFT.line(15,15,310,15,Orange); TFT.line(310,15,310,250,Orange); TFT.line(310,250,15,250,Orange); TFT.line(15,250,15,15,Orange); //init main menu modeBox menu[6]; //wifi config mode menu[MODE_WIFI_CONFIG].xTL = 25; menu[MODE_WIFI_CONFIG].yTL = 25; menu[MODE_WIFI_CONFIG].xBR = 110; menu[MODE_WIFI_CONFIG].yBR = 90; menu[MODE_WIFI_CONFIG].text = "1.wifi config"; menu[MODE_WIFI_CONFIG].name = "wifi config"; //setting mode menu[MODE_SETTINGS].xTL = 25; menu[MODE_SETTINGS].yTL = 100; menu[MODE_SETTINGS].xBR = 110; menu[MODE_SETTINGS].yBR = 165; menu[MODE_SETTINGS].text = "2.settings "; menu[MODE_SETTINGS].name = "settings"; //register mode menu[MODE_REGISTER].xTL = 120; menu[MODE_REGISTER].yTL = 25; menu[MODE_REGISTER].xBR = 205; menu[MODE_REGISTER].yBR = 90; menu[MODE_REGISTER].text = "3.register "; menu[MODE_REGISTER].name = "register"; //operational mode menu[MODE_OPERATION].xTL = 120; menu[MODE_OPERATION].yTL = 100; menu[MODE_OPERATION].xBR = 205; menu[MODE_OPERATION].yBR = 165; menu[MODE_OPERATION].text = "4.operation "; menu[MODE_OPERATION].name = "operation"; //firmware download mode menu[MODE_FIRMWARE_DOWNLOAD].xTL = 215; menu[MODE_FIRMWARE_DOWNLOAD].yTL = 25; menu[MODE_FIRMWARE_DOWNLOAD].xBR = 300; menu[MODE_FIRMWARE_DOWNLOAD].yBR = 90; menu[MODE_FIRMWARE_DOWNLOAD].text = "5.fw dwld "; menu[MODE_FIRMWARE_DOWNLOAD].name = "fw dwld"; //reserved mode menu[5].xTL = 215; menu[5].yTL = 100; menu[5].xBR = 300; menu[5].yBR = 165; menu[5].text = "6.reserved "; menu[5].name = "reserved"; //draw main menu for(int i=0; i<6; i++) { TFT.fillrect(menu[i].xTL,menu[i].yTL,menu[i].xBR,menu[i].yBR,Orange); } //add text to main menu for(int i=0; i<6; i++) { TFT.locate(menu[i].xTL,menu[i].yTL); TFT.printf("%s",menu[i].text.c_str()); } //read emma settings emmaReadSettings(); //mqttDOMAIN is not empty -> has been registered if(!mqttDOMAIN.empty()) { TFT.locate(25,170); TFT.printf(" auto select enabled"); t.start(); } while(!modeSelected) { if(!TP._tp_irq) { if(TP.Read_Ads7843()) { TP.getDisplayPoint(); TPx = TP.display.x; TPy = TP.display.y; TP.TP_DrawPoint(TPx,TPy, Blue); for(int i=0; i<6; i++) { if((menu[i].xTL < TPx && TPx < menu[i].xBR) && (menu[i].yTL < TPy && TPy < menu[i].yBR)) { md = i; modeSelected = true; } } } } //auto select (to emmaModeOperation) after some times if(!mqttDOMAIN.empty()) { if(t.read()>20) { md = MODE_OPERATION; modeSelected = true; t.stop(); t.reset(); } } } TFT.locate(25,170); TFT.printf(" "); TFT.locate(25,170); TFT.printf("mode: %s is selected",menu[md].name.c_str()); wait(2); TFT.cls(); return md; } /*end lcd and touch*/ /*start emma read settings*/ void emmaReadSettings(void) { char s[64]; DBG.baud(19200); DBG.printf("\r\nemmaReadSettings\r\n"); //read settings emmaUID = readSetting("emmaUID"); //emmaUID = "066eff575349896767073038"; DBG.printf("emmaUID:%s\r\n",emmaUID.c_str()); //calculate hmac for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"emma-%s",emmaUID.c_str()); hmac = calculateMD5(s); DBG.printf("hmac:%s\r\n",hmac.c_str()); appNAME = readSetting("appNAME"); DBG.printf("appNAME:%s\r\n",appNAME.c_str()); mqttDOMAIN = readSetting("mqttDOMAIN"); DBG.printf("mqttDOMAIN:%s\r\n",mqttDOMAIN.c_str()); mqttKEY = readSetting("mqttKEY"); DBG.printf("mqttKEY:%s\r\n",mqttKEY.c_str()); mqttSECRET = readSetting("mqttSECRET"); DBG.printf("mqttSECRET:%s\r\n",mqttSECRET.c_str()); mqttSERVER = readSetting("mqttSERVER"); DBG.printf("mqttSERVER:%s\r\n",mqttSERVER.c_str()); mqttPORT = readSetting("mqttPORT"); DBG.printf("mqttPORT:%s\r\n",mqttPORT.c_str()); restSERVER = readSetting("restSERVER"); DBG.printf("restSERVER:%s\r\n",restSERVER.c_str()); restPORT = readSetting("restPORT"); DBG.printf("restPORT:%s\r\n",restPORT.c_str()); proxySERVER = readSetting("proxySERVER"); DBG.printf("proxySERVER:%s\r\n",proxySERVER.c_str()); proxyPORT = readSetting("proxyPORT"); DBG.printf("proxyPORT:%s\r\n",proxyPORT.c_str()); proxyAUTH = readSetting("proxyAUTH"); DBG.printf("proxyAUTH:%s\r\n",proxyAUTH.c_str()); wifiSSID = readSetting("wifiSSID"); DBG.printf("wifiSSID:%s\r\n",wifiSSID.c_str()); wifiPASS = readSetting("wifiPASS"); DBG.printf("wifiPASS:%s\r\n",wifiPASS.c_str()); } /*end emma read settings*/ /*start emma mode*/ void emmaInit(int mode) { DBG.printf("\r\nemmaInit\r\n"); DBG.printf("mode:%d\r\n",mode); //check proxy if(!proxySERVER.empty() && !proxyPORT.empty() && !proxyAUTH.empty()) { useProxy = true; } else { useProxy = false; } //testing purpose //useProxy = false; DBG.printf("proxy:%d\r\n",useProxy); //check available interface isEthAvailable(); //check whether cable is connected wifiAvailable = true; //wifi module will always on the board gprsAvailable = true; //gprs module will always on the board DBG.printf("eth:%d\r\n",ethAvailable); DBG.printf("wifi:%d\r\n",wifiAvailable); DBG.printf("gprs:%d\r\n",gprsAvailable); } void emmaModeWiFiConfig(void) { string str; TFT.locate(0,0); TFT.printf(" please wait"); if(wifiAvailable) { DBG.printf("emmaModeWiFiConfig\r\n"); //set wifi module to configuration _ESP.printf("MODE=C"); while(1) { char rcv[128] = {}; rcvReply(rcv,3000); str = rcv; if(str.find("SC_STATUS_FIND_CHANNEL") != std::string::npos) break; } TFT.locate(0,0); TFT.printf(" emmaModeWiFiConfig"); TFT.locate(0,20); TFT.printf(" connect with emma app now"); DBG.printf("entering wifi configuration mode\r\n"); while(1) { char rcv[128] = {}; rcvReply(rcv,3000); str = rcv; if(str.find("MODE=C OK") != std::string::npos) { //save wifiSSID and wifiPASS if(str.find("[") != std::string::npos && str.find("]") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("[")+1); str.erase(str.begin()+str.find("]"),str.end()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); char *parameter[2] = {"wifiSSID","wifiPASS"}; for(int i=0; i<2; i++) { if(jsonValue.hasMember(parameter[i])) { string val = jsonValue[parameter[i]].get<std::string>(); int st = writeSetting(parameter[i],val.c_str()); if(st) { DBG.printf("%s is saved\r\n",parameter[i]); TFT.locate(0,40); TFT.printf(" %s is saved",parameter[i]); wait(3); TFT.locate(0,40); TFT.printf(" "); } else { DBG.printf("%s is not saved\r\n",parameter[i]); TFT.locate(0,40); TFT.printf(" %s is not saved",parameter[i]); wait(3); TFT.locate(0,40); TFT.printf(" "); } } } //wificonfig finish TFT.locate(0,20); TFT.printf(" "); TFT.locate(0,20); TFT.printf(" wificonfig finish. please restart."); } } else if(str.find("SC_STATUS_GETTING_SSID_PSWD") != std::string::npos){ DBG.printf("app connected\r\n"); TFT.locate(0,20); TFT.printf(" "); TFT.locate(0,20); TFT.printf(" app connected"); } } } else { DBG.printf("no wifi found\r\n"); TFT.locate(0,20); TFT.printf(" no wifi found"); } } void emmaModeSettings(void) { bool clientIsConnected = false; bool serverIsListened = false; char s[32]; string str; TFT.locate(0,0); TFT.printf(" please wait"); //create settings dir mkdir("/sd/settings",0777); //get and write emmaUID string uid = getUID(); sprintf(s,"(%s)",uid.c_str()); uid = s; writeSetting("emmaUID",uid); if(ethAvailable) { DBG.printf("emmaModeSettings - eth\r\n"); wait(2); TFT.locate(0,0); TFT.printf(" "); TFT.locate(0,0); TFT.printf(" emmaModeSettings"); TCPSocketServer svr; TCPSocketConnection clientSock; if(svr.bind(SERVER_PORT) < 0) { DBG.printf("tcp server bind failed\r\n"); } else { DBG.printf("tcp server bind success\r\n"); serverIsListened = true; } DBG.printf("please connect to %s\r\n",ipstack.getEth().getIPAddress()); if(svr.listen(1) < 0) { DBG.printf("tcp server listen failed\r\n"); TFT.locate(0,20); TFT.printf(" settings error. please restart."); while(1); } else { DBG.printf("tcp server is listening...\r\n"); TFT.locate(0,20); TFT.printf(" connect with emma app now!"); } clientSock.set_blocking(false,30000); //timeout after 30sec //listening while (serverIsListened) { if(svr.accept(clientSock) < 0) { DBG.printf("failed to accept connection\r\n"); TFT.locate(0,20); TFT.printf(" "); TFT.locate(0,20); TFT.printf("failed to accept connection"); } else { DBG.printf("connection success!\r\nIP: %s\r\n",clientSock.get_address()); TFT.locate(0,20); TFT.printf(" "); TFT.locate(0,20); //TFT.printf(" connection success! IP: %s",clientSock.get_address()); TFT.printf(" connection success!"); clientIsConnected = true; while(clientIsConnected) { char buffer[1024] = {}; switch(clientSock.receive(buffer,1023)) { case 0: DBG.printf("received buffer is empty\r\n"); clientIsConnected = false; break; case -1: DBG.printf("failed to read data from client\r\n"); clientIsConnected = false; break; default: //DBG.printf("received data: %d\r\n%s\r\n",strlen(buffer),buffer); DBG.printf("\r\n"); str = buffer; if(str.find("[") != std::string::npos && str.find("]") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("[")+1); str.erase(str.begin()+str.find("]"),str.end()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); char *parameter[5] = {"gprsAPN","proxySERVER","proxyPORT","proxyAUTH","epochTime"}; for(int i=0; i<4; i++) { if(jsonValue.hasMember(parameter[i])) { string val = jsonValue[parameter[i]].get<std::string>(); int st = writeSetting(parameter[i],val.c_str()); if(st) { DBG.printf("%s: %s is saved\r\n",parameter[i],val.c_str()); TFT.locate(0,40); TFT.printf(" %s: %s is saved",parameter[i],val.c_str()); wait(1); TFT.locate(0,40); TFT.printf(" "); } else { DBG.printf("%s is not saved\r\n",parameter[i]); TFT.locate(0,40); TFT.printf(" %s is not saved",parameter[i]); wait(1); TFT.locate(0,40); TFT.printf(" "); } } } //set time if(jsonValue.hasMember(parameter[4])) { string epTime = jsonValue[parameter[4]].get<std::string>(); time_t seconds; sscanf(epTime.c_str(),"%d",&seconds); set_time(seconds); DBG.printf("time is set\r\n"); TFT.locate(0,40); TFT.printf(" time is set"); wait(1); TFT.locate(0,40); TFT.printf(" "); } } break; } } DBG.printf("close connection\r\n"); TFT.locate(0,20); TFT.printf(" "); TFT.locate(0,20); TFT.printf(" settings finish. please restart."); clientSock.close(); } } } else if(wifiAvailable) { DBG.printf("emmaModeSettings - wifi\r\n"); _ESP.printf("MODE=S"); while(1) { char rcv[128] = {}; rcvReply(rcv,3000); str = rcv; if(str.find("MODE=S_OK") != std::string::npos) break; } DBG.printf("entering settings mode\r\n"); TFT.locate(0,0); TFT.printf(" emmaModeSettings"); TFT.locate(0,20); TFT.printf(" connect with emma app now!"); while(1) { char rcv[512] = {}; rcvReply(rcv,3000); //DBG.printf("rcv:%s\r\n",rcv); str = rcv; if(str.find("MODE=S_Config") != std::string::npos) { //save gprs and proxy setting if(str.find("[") != std::string::npos && str.find("]") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("[")+1); str.erase(str.begin()+str.find("]"),str.end()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); char *parameter[5] = {"gprsAPN","proxySERVER","proxyPORT","proxyAUTH","epochTime"}; for(int i=0; i<4; i++) { if(jsonValue.hasMember(parameter[i])) { string val = jsonValue[parameter[i]].get<std::string>(); int st = writeSetting(parameter[i],val.c_str()); if(st) { DBG.printf("%s: %s is saved\r\n",parameter[i],val.c_str()); TFT.locate(0,40); TFT.printf(" %s: %s is saved",parameter[i],val.c_str()); wait(1); TFT.locate(0,40); TFT.printf(" "); } else { DBG.printf("%s is not saved\r\n",parameter[i]); TFT.locate(0,40); TFT.printf(" %s is not saved",parameter[i]); wait(1); TFT.locate(0,40); TFT.printf(" "); } } } //set time if(jsonValue.hasMember(parameter[4])) { string epTime = jsonValue[parameter[4]].get<std::string>(); time_t seconds; sscanf(epTime.c_str(),"%d",&seconds); set_time(seconds); DBG.printf("time is set\r\n"); TFT.locate(0,40); TFT.printf(" time is set"); wait(1); TFT.locate(0,40); TFT.printf(" "); } //setting finish TFT.locate(0,20); TFT.printf(" "); TFT.locate(0,20); TFT.printf(" settings finish. please restart."); } } else if(str.find("connect") != std::string::npos) { DBG.printf("connection success!\r\n"); TFT.locate(0,20); TFT.printf(" "); TFT.locate(0,20); TFT.printf(" connection success!"); } } } else { DBG.printf("no eth or wifi is available\r\n"); TFT.locate(0,0); TFT.printf(" no iface avail, please restart!"); } } void emmaModeRegister(void) { bool emmaGetRegKey = false; bool emmaRegistered = false; char connBody[256]; char s[512]; char r[256]; int connBodyLen; int connPort; int loop = 0; string connData; string connHost; string str; string regKey; Timer t; TFT.locate(0,0); TFT.printf(" please wait"); //check connected interface isEthConnected(); isWiFiConnected(); isGprsConnected(); DBG.printf("ethConnected:%d\r\n",ethConnected); DBG.printf("wifiConnected:%d\r\n",wifiConnected); if(ethConnected) { DBG.printf("emmaModeRegister - eth\r\n"); wait(2); TFT.locate(0,0); TFT.printf(" "); TFT.locate(0,0); TFT.printf(" emmaModeRegister"); //set connBody, connHost, connPort, connData connBodyLen = sprintf(connBody,"{\"uid\":\"%s\",\"hmac\":\"%s\"}",emmaUID.c_str(),hmac.c_str()); if(useProxy) { DBG.printf("use proxy\r\n"); connHost = proxySERVER; sscanf(proxyPORT.c_str(),"%d",&connPort); for(int i=0; i<sizeof(s); i++) { s[i]=0; } //sprintf(s,"GET http://%s:%s/emma/api/controller/register?uid=%s&hmac=%s HTTP/1.0\nHost: %s\r\n\r\n",restSERVER.c_str(),restPORT.c_str(),emmaUID.c_str(),hmac.c_str(),restSERVER.c_str()); //sprintf(s,"POST http://%s:%s/emma/api/controller/register HTTP/1.0\nHost: %s\nContent-Length: 76\n\n{\"uid\":\"%s\",\"hmac\":\"%s\"}\r\n\r\n",restSERVER.c_str(),restPORT.c_str(),restSERVER.c_str(),emmaUID.c_str(),hmac.c_str()); sprintf(s,"POST http://%s:%s/%s/api/controller/register HTTP/1.0\nHost: %s\nContent-Length: %d\n\n%s\r\n\r\n",restSERVER.c_str(),restPORT.c_str(),appNAME.c_str(),restSERVER.c_str(),connBodyLen,connBody); connData = s; } else { DBG.printf("no proxy\r\n"); connHost = restSERVER; //connPort = restPORT; sscanf(restPORT.c_str(),"%d",&connPort); for(int i=0; i<sizeof(s); i++) { s[i]=0; } //sprintf(s,"GET /emma/api/controller/register?uid=%s&hmac=%s HTTP/1.0\nHost: %s\r\n\r\n",emmaUID.c_str(),hmac.c_str(),restSERVER.c_str()); //sprintf(s,"POST /emma/api/controller/register HTTP/1.0\nHost: %s\nContent-Length: 76\n\n{\"uid\":\"%s\",\"hmac\":\"%s\"}\r\n\r\n",restSERVER.c_str(),emmaUID.c_str(),hmac.c_str()); sprintf(s,"POST /%s/api/controller/register HTTP/1.0\nHost: %s\nContent-Length: %d\n\n%s\r\n\r\n",appNAME.c_str(),restSERVER.c_str(),connBodyLen,connBody); connData = s; } //register while(!emmaGetRegKey) { //DBG.printf("post:%s\r\n",s); str.clear(); str = ethREST(connHost,connPort,connData); DBG.printf("rsp reg:%s\r\n",str.c_str()); //check and save mqtt setting if(str.find("[") != std::string::npos && str.find("]") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("[")+1); str.erase(str.begin()+str.find("]"),str.end()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); char *parameter[4] = {"mqttDOMAIN","mqttKEY","mqttSECRET","registrationKey"}; //save mqtt parameter writeSetting(parameter[0],"()"); //sd card need to be initialized for(int i=0; i<3; i++) { if(jsonValue.hasMember(parameter[i])) { string val = jsonValue[parameter[i]].get<std::string>(); int st = writeSetting(parameter[i],val.c_str()); if(st) { DBG.printf("%s: %s is saved\r\n",parameter[i],val.c_str()); } else { DBG.printf("%s is not saved\r\n",parameter[i]); } } } //get registrationKey if(jsonValue.hasMember(parameter[3])) { string val = jsonValue[parameter[3]].get<std::string>(); if(val.find("(") != std::string::npos && val.find(")") != std::string::npos) { val.erase(val.begin(),val.begin()+val.find("(")+1); val.erase(val.begin()+val.find(")"),val.end()); regKey = val; DBG.printf("%s: %s\r\n",parameter[3],regKey.c_str()); TFT.locate(0,20); TFT.printf(" %s: %s\r\n",parameter[3],regKey.c_str()); emmaGetRegKey = true; } } } } //calculate hmac for(int i=0; i<sizeof(r); i++) { r[i]=0; } sprintf(r,"emma-%s-%s",emmaUID.c_str(),regKey.c_str()); hmac = calculateMD5(r); DBG.printf("hmac:%s\r\n",hmac.c_str()); //set connBody and connData connBodyLen = sprintf(connBody,"{\"uid\":\"%s\",\"registrationKey\":\"%s\",\"hmac\":\"%s\"}",emmaUID.c_str(),regKey.c_str(),hmac.c_str()); if(useProxy) { DBG.printf("use proxy\r\n"); for(int i=0; i<sizeof(s); i++) { s[i]=0; } //sprintf(s,"GET http://%s:%s/emma/api/controller/verify?uid=%s®istrationKey=%s&hmac=%s HTTP/1.0\nHost: %s\r\n\r\n",restSERVER.c_str(),restPORT.c_str(),emmaUID.c_str(),regKey.c_str(),hmac.c_str(),restSERVER.c_str()); sprintf(s,"POST http://%s:%s/%s/api/controller/verify HTTP/1.0\nHost: %s\nContent-Length: %d\n\n%s\r\n\r\n",restSERVER.c_str(),restPORT.c_str(),appNAME.c_str(),restSERVER.c_str(),connBodyLen,connBody); connData = s; } else { DBG.printf("no proxy\r\n"); for(int i=0; i<sizeof(s); i++) { s[i]=0; } //sprintf(s,"GET /emma/api/controller/verify?uid=%s®istrationKey=%s&hmac=%s HTTP/1.0\nHost: %s\r\n\r\n",emmaUID.c_str(),regKey.c_str(),hmac.c_str(),restSERVER.c_str()); sprintf(s,"POST /%s/api/controller/verify HTTP/1.0\nHost: %s\nContent-Length: %d\n\n%s\r\n\r\n",appNAME.c_str(),restSERVER.c_str(),connBodyLen,connBody); connData = s; } //verify registration while(!emmaRegistered && loop < 12){ str.clear(); str = ethREST(connHost,connPort,connData); DBG.printf("rsp vrf:%s\r\n",str.c_str()); TFT.locate(0,40); TFT.printf(" "); TFT.locate(0,40); TFT.printf(" wait:%d\r\n",loop); //check verification if(str.find("[") != std::string::npos && str.find("]") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("[")+1); str.erase(str.begin()+str.find("]"),str.end()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); if(jsonValue.hasMember("user")) { string val = jsonValue["user"].get<std::string>(); DBG.printf("%s is registered\r\n",val.c_str()); TFT.locate(0,40); TFT.printf(" "); TFT.locate(0,40); TFT.printf(" %s is registered\r\n",val.c_str()); emmaRegistered = true; } } wait(5); loop++; } //check whether registration success if(emmaRegistered) { DBG.printf("registration successful\r\n"); TFT.locate(0,60); TFT.printf(" registration successful\r\n"); } else { DBG.printf("registration unsuccessful\r\n"); TFT.locate(0,60); TFT.printf(" registration unsuccessful. please restart.\r\n"); } while(1); } else if(wifiConnected) { DBG.printf("emmaModeRegister - wifi\r\n"); _ESP.printf("MODE=B"); wait(1); while(!esp.ready()); //set connHost, connPort if(useProxy) { connHost = proxySERVER; sscanf(proxyPORT.c_str(),"%d",&connPort); } else { connHost = restSERVER; //connPort = restPORT; sscanf(restPORT.c_str(),"%d",&connPort); } TFT.locate(0,0); TFT.printf(" emmaModeRegister"); //rest begin if(!rest.begin(connHost.c_str(),connPort,false)) { DBG.printf("EMMA: fail to setup rest"); TFT.locate(0,20); TFT.printf(" fail setup connection"); TFT.locate(0,40); TFT.printf(" check your wifi connection or"); TFT.locate(0,60); TFT.printf(" you should setup proxy!"); while(1); } //wifiConnected = true; //with custom firmware, wifi module should connect automatically esp.process(); if(wifiConnected) { //check proxy if(useProxy) { sprintf(r,"http://%s:%s/%s/api/controller/register",restSERVER.c_str(),restPORT.c_str(),appNAME.c_str()); //sprintf(r,"http://%s:%d/emma/api/controller/register HTTP/1.0\nHost: %s:%d\nProxy-Authorization: Basic %s\nCache-Control: no-cache\nContent-Length: %d\n\n",restSERVER,restPORT,restSERVER,restPORT,proxyAUTH.c_str(),76); //sprintf(r,"http://%s:%d/emma/api/controller/register HTTP/1.0\nAccept: */*\nAccept-Encoding: gzip,deflate\nContent-Length: %d\r\n\r\n",restSERVER,restPORT,76); //sprintf(r,"http://%s:%d/emma/coba",restSERVER,REST_SERVER_PORT); } else { sprintf(r,"/%s/api/controller/register",appNAME.c_str()); } //register while(!emmaGetRegKey) { sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\"}",emmaUID.c_str(),hmac.c_str()); //DBG.printf("s:%s\r\n",s); //string iniStr = "{\"uid\":\"005300553533510334313732\",\"hmac\":\"45fc6a4447989a9434d1f21087a78061\"}"; //DBG.printf("s:%s\r\n",iniStr.c_str()); //rest.post(r,iniStr.c_str()); rest.post(r,s); for(int i=0; i<sizeof(s); i++) { s[i]=0; } rest.getResponse(s,sizeof(s)); DBG.printf("rsp reg:%s\r\n",s); //check and save mqtt setting str = s; if(str.find("[") != std::string::npos && str.find("]") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("[")+1); str.erase(str.begin()+str.find("]"),str.end()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); char *parameter[4] = {"mqttDOMAIN","mqttKEY","mqttSECRET","registrationKey"}; //save mqtt parameter writeSetting(parameter[0],"()"); //sd card need to be initialized for(int i=0; i<3; i++) { if(jsonValue.hasMember(parameter[i])) { string val = jsonValue[parameter[i]].get<std::string>(); int st = writeSetting(parameter[i],val.c_str()); if(st) { DBG.printf("%s: %s is saved\r\n",parameter[i],val.c_str()); } else { DBG.printf("%s is not saved\r\n",parameter[i]); } } } //get registrationKey if(jsonValue.hasMember(parameter[3])) { string val = jsonValue[parameter[3]].get<std::string>(); if(val.find("(") != std::string::npos && val.find(")") != std::string::npos) { val.erase(val.begin(),val.begin()+val.find("(")+1); val.erase(val.begin()+val.find(")"),val.end()); regKey = val; DBG.printf("%s: %s\r\n",parameter[3],regKey.c_str()); TFT.locate(0,20); TFT.printf(" %s: %s\r\n",parameter[3],regKey.c_str()); emmaGetRegKey = true; } } } wait(1); } //calculate hmac for(int i=0; i<sizeof(r); i++) { r[i]=0; } sprintf(r,"emma-%s-%s",emmaUID.c_str(),regKey.c_str()); hmac = calculateMD5(r); DBG.printf("hmac:%s\r\n",hmac.c_str()); //check proxy if(useProxy) { sprintf(r,"http://%s:%s/%s/api/controller/verify",restSERVER.c_str(),restPORT.c_str(),appNAME.c_str()); } else { sprintf(r,"/%s/api/controller/verify",appNAME.c_str()); } //verify registration while(!emmaRegistered && loop < 12){ sprintf(s,"{\"uid\":\"%s\",\"registrationKey\":\"%s\",\"hmac\":\"%s\"}",emmaUID.c_str(),regKey.c_str(),hmac.c_str()); rest.post(r,s); rest.getResponse(s,sizeof(s)); DBG.printf("rsp vrf:%s\r\n",s); TFT.locate(0,40); TFT.printf(" "); TFT.locate(0,40); TFT.printf(" wait:%d\r\n",loop); //check verification str = s; if(str.find("[") != std::string::npos && str.find("]") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("[")+1); str.erase(str.begin()+str.find("]"),str.end()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); if(jsonValue.hasMember("user")) { string val = jsonValue["user"].get<std::string>(); DBG.printf(" %s is registered\r\n",val.c_str()); TFT.locate(0,40); TFT.printf(" "); TFT.locate(0,40); TFT.printf(" %s is registered\r\n",val.c_str()); emmaRegistered = true; } } wait(5); loop++; } //check whether registration success if(emmaRegistered) { DBG.printf("registration successful\r\n"); TFT.locate(0,60); TFT.printf(" registration successful\r\n"); } else { DBG.printf("registration unsuccessful\r\n"); TFT.locate(0,60); TFT.printf(" registration unsuccessful. please restart.\r\n"); } while(1); } } else if(gprsConnected) { DBG.printf("emmaModeRegister - gprs\r\n"); } else { DBG.printf("no eth, wifi, or gprs is connected\r\n"); TFT.locate(0,60); TFT.printf(" no iface connected. please restart.\r\n"); } } void emmaModeOperation(void) { //char mqttClientId[32]; char connBody[256]; char p[64]; char q[32]; char r[32]; char s[4096]; int connBodyLen; int connPort; int loop=0; int trial=0; string hmacTime; string hmacCmd; string str; time_t seconds; Timer t; Timer tPanelEnergy; Timer tPanel; Timer tNodes; TFT.locate(0,0); TFT.printf(" please wait"); //check connected interface isEthConnected(); isWiFiConnected(); isGprsConnected(); DBG.printf("ethConnected:%d\r\n",ethConnected); DBG.printf("wifiConnected:%d\r\n",wifiConnected); TFT.locate(0,0); TFT.printf(" emmaModeOperation"); TFT.locate(0,20); if(ethConnected) { TFT.printf("ETH:Avail"); } else { TFT.printf("ETH:N/A"); } TFT.locate(80,20); if(wifiConnected) { TFT.printf("WiFi:Avail"); } else { TFT.printf("WiFi:N/A"); } TFT.locate(160,20); if(gprsConnected) { TFT.printf("GPRS:Avail"); } else { TFT.printf("GPRS:N/A"); } if(ethConnected) { DBG.printf("emmaModeOperation - eth\r\n"); /* //start new log indicator seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); DBG.printf("newLog:%d\r\n",writeLog(q,"++++++++++Ethernet++++++++++")); //set ade7758 parameter ADE.begin(); ADE.writeRMSOffset(AIRMSOFFSET, BIRMSOFFSET, CIRMSOFFSET, AVRMSOFFSET, BVRMSOFFSET, CVRMSOFFSET); ADE.write16bits(AWG, 0); ADE.write16bits(BWG, 0); ADE.write16bits(CWG, 0); ADE.write16bits(AVAG, 0); ADE.write16bits(BVAG, 0); ADE.write16bits(CVAG, 0); //check firmware update //execute last state of switches on board //get list of nodes from server connBodyLen = sprintf(connBody,"{\"uid\":\"%s\",\"hmac\":\"%s\"}",emmaUID.c_str(),hmac.c_str()); //sprintf(s,"GET /emma/api/controller/remotes?uid=%s&hmac=%s HTTP/1.0\nHost: %s\r\n\r\n",emmaUID.c_str(),hmac.c_str(),restSERVER.c_str()); sprintf(s,"POST /emma/api/controller/wifinodes HTTP/1.0\nHost: %s\nContent-Length:%d\n\n%s\r\n\r\n",restSERVER.c_str(),connBodyLen,connBody); str.clear(); sscanf(restPORT.c_str(),"%d",&connPort); str = ethREST(restSERVER,connPort,s); DBG.printf("str:%s\r\n",str.c_str()); if(str.rfind("[{\"type\"") != std::string::npos) { DBG.printf("get nodes from server\r\n"); str.erase(str.begin(),str.begin()+str.rfind("[{\"type\"")); str.erase(str.begin()+str.rfind("}]")+2,str.end()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); char *parameter[3] = {"type","mac","ip"}; TFT.locate(0,40); TFT.printf(" "); TFT.locate(0,40); TFT.printf("get %d nodes from server",jsonValue.size()); wait(0.5); TFT.locate(0,40); TFT.printf(" "); //check whether nodes valid bool validNodes = true; for(int i=0; i<jsonValue.size(); i++) { for(int j=0; j<3; j++) { validNodes = validNodes && jsonValue[i].hasMember(parameter[j]); } } DBG.printf("nodes validity:%d\r\n",validNodes); if(validNodes) { for(int i=0; i<jsonValue.size(); i++) { string typeValue = jsonValue[i][parameter[0]].get<std::string>(); string macValue = jsonValue[i][parameter[1]].get<std::string>(); string ipValue = jsonValue[i][parameter[2]].get<std::string>(); nodes[i].type = typeValue; nodes[i].macAddr = macValue; nodes[i].ipAddr = ipValue; DBG.printf("nodes[%d]type:%s\r\n",i,nodes[i].type.c_str()); DBG.printf("nodes[%d]mac:%s\r\n",i,nodes[i].macAddr.c_str()); DBG.printf("nodes[%d]ip:%s\r\n",i,nodes[i].ipAddr.c_str()); } } } else { DBG.printf("no nodes from server\r\n"); } //define thread osThreadDef(energyThread, osPriorityBelowNormal, (8*DEFAULT_STACK_SIZE)); //create thread osThreadCreate(osThread(energyThread),NULL); tPanelEnergy.start(); tPanel.start(); tNodes.start(); wait(1); while(1) { //checkVoltagePower(); //need revision to support ethernet //panelEnergy, panelVoltage, and panelPower if(tPanelEnergy.read() > 30.0f) { DBG.printf("[%d]WattHR for each phase: %.2f, %.2f, %.2f\r\n", loop, AWattHr, BWattHr, CWattHr); TFT.locate(0,60); TFT.printf(" "); TFT.locate(0,60); TFT.printf("[%d]WHR: %.1f, %.1f, %.1f", loop, AWattHr, BWattHr, CWattHr); DBG.printf("VRMS for each phase: %.2f, %.2f, %.2f\r\n", AVrms, BVrms, CVrms); TFT.locate(0,80); TFT.printf(" "); TFT.locate(0,80); TFT.printf("VRMS: %.1f, %.1f, %.1f", AVrms, BVrms, CVrms); DBG.printf("Watt for each phase: %.2f, %.2f, %.2f\r\n", AWatt, BWatt, CWatt); TFT.locate(0,100); TFT.printf(" "); TFT.locate(0,100); TFT.printf("Watt: %.1f, %.1f, %.1f", AWatt, BWatt, CWatt); if(newEnergyData) { //for(int i=1; i<4; i++) { for(int i=1; i<2; i++) { DBG.printf("sending channel: %d\r\n",i); if(i==1){ XWattHr = AWattHr; XVrms = AVrms; XWatt = AWatt; } else if(i==2) { XWattHr = BWattHr; XVrms = BVrms; XWatt = BWatt; } else { XWattHr = CWattHr; XVrms = CVrms; XWatt = CWatt; } if(XWattHr != 0.0f) { seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); //calculate hmacTime for(int j=0; j<sizeof(p); j++) { p[j]=0; } sprintf(p,"emma-%s-%s",emmaUID.c_str(),q); hmacTime = calculateMD5(p); connBodyLen = sprintf(connBody,"{\"uid\":\"%s\",\"hmac\":\"%s\",\"time\":\"%s\",\"energy\":%.2f,\"voltage\":%.2f,\"power\":%.2f}", emmaUID.c_str(),hmacTime.c_str(),q,XWattHr,XVrms,XWatt); //DBG.printf("dataEnergy:\r\n%s\r\n",connBody); sprintf(r,"POST /emma/api/controller/energy/%d HTTP/1.0\nHost:%s\nContent-Length:%d\n\n%s\r\n\r\n",i,restSERVER.c_str(),connBodyLen,connBody); str.clear(); sscanf(restPORT.c_str(),"%d",&connPort); str = ethREST(restSERVER,connPort,r); if(str.find("\"status\":\"success\"") != std::string::npos) { //logging purpose seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); DBG.printf("logPE:%d\r\n",writeLog(q,"sendEnergyData success")); DBG.printf("send channel: %d success\r\n",i); TFT.foreground(Green); TFT.locate(0,120); TFT.printf(" "); TFT.locate(0,120); TFT.printf("send ch%d success",i); wait(1); TFT.locate(0,120); TFT.printf(" "); TFT.foreground(White); } else { //logging purpose seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); DBG.printf("logPE:%d\r\n",writeLog(q,"sendEnergyData failed")); DBG.printf("send channel: %d failed\r\n",i); TFT.foreground(Red); TFT.locate(0,120); TFT.printf(" "); TFT.locate(0,120); TFT.printf("send ch%d failed",i); wait(1); TFT.locate(0,120); TFT.printf(" "); TFT.foreground(White); } } } newEnergyData = false; } tPanelEnergy.reset(); loop++; } //panel environment osDelay(5000); } */ } else if(wifiConnected) { DBG.printf("emmaModeOperation - wifi\r\n"); //start new log and dbg indicator seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); DBG.printf("newLog:%d\r\n",writeLog(q,"++++++++++WiFi++++++++++")); //DBG.printf("newDbg:%d\r\n",writeDbg(q,"++++++++++++++++++++")); //do not delete code below - indicator that esp need to MODE=B and esp.ready() to work //_ESP.printf("MODE=B"); //wait(1); //while(!esp.ready()); /* DBG.printf("emma: setup mqtt client\r\n"); sprintf(mqttClientId,"emma/%s",emmaUID.c_str()); if(mqtt.begin(mqttClientId, mqttKEY.c_str(), mqttSECRET.c_str(), 120, 1)) { mqtt.connectedCb.attach(&mqttConnected); mqtt.disconnectedCb.attach(&mqttDisconnected); mqtt.connect(mqttSERVER,mqttPORT,false); DBG.printf("emma: success to setup mqtt\r\n"); TFT.locate(0,40); TFT.printf("emma: success to setup mqtt"); } DBG.printf("emma: system started\r\n"); */ //t.start(); //while(t.read_ms() < 5000) { // esp.process(); //} //t.stop(); //t.reset(); //set ade7758 parameter ADE.begin(); ADE.writeRMSOffset(AIRMSOFFSET, BIRMSOFFSET, CIRMSOFFSET, AVRMSOFFSET, BVRMSOFFSET, CVRMSOFFSET); ADE.write16bits(AWG, 0); ADE.write16bits(BWG, 0); ADE.write16bits(CWG, 0); ADE.write16bits(AVAG, 0); ADE.write16bits(BVAG, 0); ADE.write16bits(CVAG, 0); //init rest to server sscanf(restPORT.c_str(),"%d",&connPort); if(rest.begin(restSERVER.c_str(),connPort,false)) { DBG.printf("rest to server is created\r\n"); TFT.locate(0,40); TFT.printf(" "); TFT.locate(0,40); TFT.printf("rest to server is created"); } else { DBG.printf("rest to server is NOT created\r\n"); TFT.locate(0,40); TFT.printf(" "); TFT.locate(0,40); TFT.printf("rest to server is NOT created"); } //check firmware update //execute last state of switches on board //get list of nodes from server /* //working sprintf(s,"/emma/api/controller/remotes?uid=%s&hmac=%s",emmaUID.c_str(),hmac.c_str()); rest.get(s); for(int i=0; i<sizeof(s); i++) { s[i]=0; } rest.getResponse(s,sizeof(s)); str = s; if(str.rfind("[{\"mac\"") != std::string::npos) { DBG.printf("get nodes from server\r\n"); str.erase(str.begin(),str.begin()+str.rfind("[{\"mac\"")); str.erase(str.begin()+str.rfind("}]")+2,str.end()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); char *parameter[2] = {"mac","ip"}; TFT.locate(0,40); TFT.printf(" "); TFT.locate(0,40); TFT.printf("get %d nodes from server",jsonValue.size()); wait(0.5); TFT.locate(0,40); TFT.printf(" "); //check whether nodes valid bool validNodes = true; for(int i=0; i<jsonValue.size(); i++) { for(int j=0; j<2; j++) { validNodes = validNodes && jsonValue[i].hasMember(parameter[j]); } } DBG.printf("nodes validity:%d\r\n",validNodes); if(validNodes) { for(int i=0; i<jsonValue.size(); i++) { string macValue = jsonValue[i][parameter[0]].get<std::string>(); string ipValue = jsonValue[i][parameter[1]].get<std::string>(); nodes[i].macAddr = macValue; nodes[i].ipAddr = ipValue; DBG.printf("nodes[%d]mac:%s\r\n",i,nodes[i].macAddr.c_str()); DBG.printf("nodes[%d]ip:%s\r\n",i,nodes[i].ipAddr.c_str()); } } } else { DBG.printf("no nodes from server\r\n"); } */ _ESP.attach(&rxInterrupt,Serial::RxIrq); //get list of nodes from server (post) sprintf(p,"/%s/api/controller/wifinodes",appNAME.c_str()); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\"}",emmaUID.c_str(),hmacTime.c_str()); rest.post(p,s); wait(2); str = rxBuf; if(str.rfind("[{\"type\"") != std::string::npos) { DBG.printf("get nodes from server\r\n"); str.erase(str.begin(),str.begin()+str.rfind("[{\"type\"")); str.erase(str.begin()+str.rfind("}]")+2,str.end()); //DBG.printf("strCrop:%s\r\n",str.c_str()); //start special handler while(1){ if(str.find("}],") != std::string::npos) { str.erase(str.begin()+str.find("}],")+1,str.begin()+str.find("}],")+2); } else { break; } } //end special handler DBG.printf("strCrop:%s\r\n",str.c_str()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); char *parameter[3] = {"type","mac","ip"}; TFT.locate(0,40); TFT.printf(" "); TFT.locate(0,40); TFT.printf("get %d nodes from server",jsonValue.size()); wait(0.5); TFT.locate(0,40); TFT.printf(" "); //check whether nodes valid bool validNodes = true; for(int i=0; i<jsonValue.size(); i++) { for(int j=0; j<3; j++) { validNodes = validNodes && jsonValue[i].hasMember(parameter[j]); } } DBG.printf("nodes validity:%d\r\n",validNodes); if(validNodes) { for(int i=0; i<jsonValue.size(); i++) { int typeValue = jsonValue[i][parameter[0]].get<int>(); string macValue = jsonValue[i][parameter[1]].get<std::string>(); string ipValue = jsonValue[i][parameter[2]].get<std::string>(); nodes[i].type = typeValue; nodes[i].macAddr = macValue; nodes[i].ipAddr = ipValue; DBG.printf("nodes[%d]type:%d\r\n",i,nodes[i].type); DBG.printf("nodes[%d]mac:%s\r\n",i,nodes[i].macAddr.c_str()); DBG.printf("nodes[%d]ip:%s\r\n",i,nodes[i].ipAddr.c_str()); } } } else { DBG.printf("no nodes from server\r\n"); } /* //working DBG.printf("emma: setup mqtt client\r\n"); sprintf(mqttClientId,"emma/%s",emmaUID.c_str()); if(mqtt.begin(mqttClientId, mqttKEY.c_str(), mqttSECRET.c_str(), 120, 1)) { mqtt.connectedCb.attach(&mqttConnected); mqtt.disconnectedCb.attach(&mqttDisconnected); mqtt.connect(mqttSERVER,mqttPORT,false); DBG.printf("emma: success to setup mqtt\r\n"); TFT.locate(0,40); TFT.printf("emma: success to setup mqtt"); } DBG.printf("emma: system started\r\n"); t.start(); while(t.read_ms() < 5000) { esp.process(); } t.stop(); t.reset(); */ //disable UART2 NVIC_DisableIRQ(USART2_IRQn); //init rest to remotes for(int i=0; i<NODES_MAX; i++) { if(!nodes[i].ipAddr.empty()) { DBG.printf("restConn nodes[%d] is created\r\n",i); nodes[i].restConn->begin(nodes[i].ipAddr.c_str(),16038,false); wait(1); } else { DBG.printf("restConn nodes[%d] is NOT created\r\n",i); wait(1); } } //enable UART2 NVIC_EnableIRQ(USART2_IRQn); //_ESP.attach(&rxInterrupt,Serial::RxIrq); //define thread osThreadDef(energyThread, osPriorityBelowNormal, (8*DEFAULT_STACK_SIZE)); //create thread osThreadCreate(osThread(energyThread),NULL); tPanelEnergy.start(); tPanel.start(); tNodes.start(); wait(1); while(1) { checkRxBuffer(); checkVoltagePower(); //whether espFreeMemory occurs if(espFreeMemory) { //logging seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); DBG.printf("logFreeMemory:%d\r\n",writeLog(q,rxLog.c_str())); espFreeMemory = false; } //whether espDHCPClientStart occurs if(espDHCPClientStart) { //logging seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); DBG.printf("logDHCPClientStart:%d\r\n",writeLog(q,rxLogA.c_str())); _ESP.printf("MODE=B"); wait(2); espDHCPClientStart = false; } //panelEnergy, panelVoltage, and panelPower if(tPanelEnergy.read() > 30.0f) { DBG.printf("[%d]WattHR for each phase: %.2f, %.2f, %.2f\r\n", loop, AWattHr, BWattHr, CWattHr); TFT.locate(0,60); TFT.printf(" "); TFT.locate(0,60); TFT.printf("[%d]WHR: %.1f, %.1f, %.1f", loop, AWattHr, BWattHr, CWattHr); DBG.printf("VRMS for each phase: %.2f, %.2f, %.2f\r\n", AVrms, BVrms, CVrms); TFT.locate(0,80); TFT.printf(" "); TFT.locate(0,80); TFT.printf("VRMS: %.1f, %.1f, %.1f", AVrms, BVrms, CVrms); DBG.printf("Watt for each phase: %.2f, %.2f, %.2f\r\n", AWatt, BWatt, CWatt); TFT.locate(0,100); TFT.printf(" "); TFT.locate(0,100); TFT.printf("Watt: %.1f, %.1f, %.1f", AWatt, BWatt, CWatt); if(newEnergyData) { //for(int i=1; i<4; i++) { for(int i=1; i<2; i++) { DBG.printf("sending channel: %d\r\n",i); if(i==1){ XWattHr = AWattHr; XVrms = AVrms; XWatt = AWatt; } else if(i==2) { XWattHr = BWattHr; XVrms = BVrms; XWatt = BWatt; } else { XWattHr = CWattHr; XVrms = CVrms; XWatt = CWatt; } if(XWattHr != 0.0f) { sprintf(r,"/%s/api/controller/energy/%d",appNAME.c_str(),i); seconds = time(NULL); //for(int j=0; j<sizeof(q); j++) { // q[j]=0; } strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); //calculate hmacTime for(int j=0; j<sizeof(p); j++) { p[j]=0; } sprintf(p,"emma-%s-%s",emmaUID.c_str(),q); hmacTime = calculateMD5(p); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\",\"time\":\"%s\",\"energy\":%.2f,\"voltage\":%.2f,\"power\":%.2f}", emmaUID.c_str(),hmacTime.c_str(),q,XWattHr,XVrms,XWatt); //DBG.printf("dataEnergy:\r\n%s\r\n",s); rest.post(r,s); wait(2); if(rxBuf.find("\"status\":\"success\"") != std::string::npos) { //logging purpose seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); DBG.printf("logPE:%d\r\n",writeLog(q,"sendEnergyData success")); DBG.printf("send channel: %d success\r\n",i); TFT.foreground(Green); TFT.locate(0,120); TFT.printf(" "); TFT.locate(0,120); TFT.printf("send ch%d success",i); wait(1); TFT.locate(0,120); TFT.printf(" "); TFT.foreground(White); } else { //logging purpose seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); DBG.printf("logPE:%d\r\n",writeLog(q,"sendEnergyData failed")); DBG.printf("send channel: %d failed\r\n",i); TFT.foreground(Red); TFT.locate(0,120); TFT.printf(" "); TFT.locate(0,120); TFT.printf("send ch%d failed",i); wait(1); TFT.locate(0,120); TFT.printf(" "); TFT.foreground(White); } } } newEnergyData = false; } tPanelEnergy.reset(); loop++; } //panel environment checkRxBuffer(); if(tPanel.read() > 900.0f) { //900 is 15 minutes int dTemp=0; int dHum=0; int dGas=0; DBG.printf("getPanelEnvironment\r\n"); //get environment sensor trial=0; while(1) { if(trial>=2) { //two times trial break; } if(d.readData() == DHT11::OK) { dTemp = d.readTemperature(); dHum = d.readHumidity(); break; } trial++; wait(3); } //send environment sensor if(dTemp!=0 && dHum!=0) { seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); //calculate hmacTime for(int j=0; j<sizeof(p); j++) { p[j]=0; } sprintf(p,"emma-%s-%s",emmaUID.c_str(),q); hmacTime = calculateMD5(p); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\",\"time\":\"%s\",\"temp\":%d,\"hum\":%d,\"gas\":%d}", emmaUID.c_str(),hmacTime.c_str(),q,dTemp,dHum,dGas); //DBG.printf("dataEnvironment:\r\n%s\r\n",s); sprintf(p,"/%s/api/controller/environment",appNAME.c_str()); rest.post(p,s); //rest.post("/emma/api/controller/environment",s); //working wait(2); str = rxBuf; if(str.rfind("/environment") != std::string::npos) { str.erase(str.begin(),str.begin()+str.rfind("/environment")); if(str.find("\"status\":\"success\"") != std::string::npos) { //logging purpose seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); DBG.printf("logPEnv:%d\r\n",writeLog(q,"sendPanelEnv success")); DBG.printf("send panel environment success\r\n"); } else { //logging purpose seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); DBG.printf("logPEnv:%d\r\n",writeLog(q,"sendPanelEnv failed")); DBG.printf("send panel environment failed\r\n"); } } checkRxBuffer(); } tPanel.reset(); } //nodeTemp checkRxBuffer(); if(tNodes.read() > 900.0f) { //900 is 15 minutes DBG.printf("getNodesTemperature\r\n"); for(int i=0; i<NODES_MAX; i++) { if(!nodes[i].ipAddr.empty()) { //get node's temp string temp; nodes[i].restConn->get("/","<?xml version=\"1.0\" encoding=\"utf-8\"?><app_cmd cmd=\"2\"/>\r\n"); wait(2); temp = rxBuf; if(temp.rfind(nodes[i].ipAddr) != std::string::npos) { temp.erase(temp.begin(),temp.begin()+temp.rfind(nodes[i].ipAddr)); if(temp.rfind("temp=") != std::string::npos) { temp.erase(temp.begin(),temp.begin()+temp.rfind("temp=")+6); temp.erase(temp.begin()+temp.find("\""),temp.end()); } else { temp = "0"; //connect to node, but receive none } } else { temp = "0"; //not connected to node } DBG.printf("nodeTemp[%d]:%s\r\n",i,temp.c_str()); //send node's temp if(temp != "0") { seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); //calculate hmacTime for(int j=0; j<sizeof(p); j++) { p[j]=0; } sprintf(p,"emma-%s-%s",emmaUID.c_str(),q); hmacTime = calculateMD5(p); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\",\"time\":\"%s\",\"mac\":\"%s\",\"value\":%s}", emmaUID.c_str(),hmacTime.c_str(),q,nodes[i].macAddr.c_str(),temp.c_str()); //DBG.printf("dataNodeTemp:\r\n%s\r\n",s); sprintf(p,"/%s/api/controller/nodetemp",appNAME.c_str()); rest.post(p,s); //rest.post("/emma/api/controller/nodetemp",s); //working wait(2); str = rxBuf; if(str.rfind("/nodetemp") != std::string::npos) { str.erase(str.begin(),str.begin()+str.rfind("/nodetemp")); if(str.find("\"status\":\"success\"") != std::string::npos) { DBG.printf("send nodeTemp success\r\n"); } else { DBG.printf("send nodeTemp failed\r\n"); } } checkRxBuffer(); } } } tNodes.reset(); } //command sprintf(r,"/%s/api/controller/command",appNAME.c_str()); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\"}", emmaUID.c_str(),hmacTime.c_str()); //rest.get("/emma/api/controller/command"); rest.post(r,s); checkRxBuffer(); if(newCommand) { //DBG.printf("newCommand:\r\n%s\r\n",globalCommand.c_str()); TFT.locate(0,160); TFT.printf(" "); TFT.locate(0,160); TFT.printf("newCommand"); MbedJSONValue jsonValue; parse(jsonValue,globalCommand.c_str()); char *parameter[5] = {"from","nType","nAddr","dType","cmd"}; DBG.printf("get %d command\r\n",jsonValue.size()); //processing each command bool validCommand; for(int i=0; i<jsonValue.size(); i++) { //check whether command is valid DBG.printf("\r\nprocessing cmd[%d]\r\n",i); validCommand = true; for(int j=0; j<5; j++) { validCommand = validCommand && jsonValue[i].hasMember(parameter[j]); } DBG.printf("command validity:%d\r\n",validCommand); if(validCommand) { string commandFrom = jsonValue[i][parameter[0]].get<std::string>(); string commandNType = jsonValue[i][parameter[1]].get<std::string>(); string commandNAddr = jsonValue[i][parameter[2]].get<std::string>(); string commandDType = jsonValue[i][parameter[3]].get<std::string>(); string commandCmd = jsonValue[i][parameter[4]].get<std::string>(); if(commandNType == "0") { //switch on panel controller DBG.printf("command for switch\r\n"); } else if(commandNType == "1") { //ir&rf remote control DBG.printf("command for remote control\r\n"); //get node ip address based on node mac address //string nodeIP; //nodeIp = readNodeIP(commandNAddr); //nodeIP = "192.168.2.15"; //DBG.printf("nodeIP: %s\r\n",nodeIP.c_str()); //get index of node list based on mac address int idx = NODES_INVALID; for(int i=0; i<NODES_MAX; i++) { if(!nodes[i].macAddr.compare(commandNAddr)) { idx = i; } } //execution process string execResult = "failed"; if(idx != NODES_INVALID) { DBG.printf("index found at %d\r\n",idx); //get cmd string based on device type and command number string nodeCmd; nodeCmd = readNodeCmd(commandDType,commandCmd); //execute command DBG.printf("executing command\r\n"); sprintf(s,"<?xml version=\"1.0\" encoding=\"utf-8\"?><app_cmd cmd=\"5\" /><app_data code=\"%s\"/>\r\n",nodeCmd.c_str()); trial=0; while(1) { rxBuf.clear(); if(trial>=2) { //two times trial DBG.printf("cmd is not executed\r\n"); TFT.foreground(Red); TFT.locate(0,180); TFT.printf(" "); TFT.locate(0,180); TFT.printf("cmd is not executed"); wait(1); TFT.locate(0,180); TFT.printf(" "); TFT.foreground(White); break; } nodes[idx].restConn->get("/",s); wait(2); if(rxBuf.find("REST: status = 200") != std::string::npos) { DBG.printf("cmd is executed\r\n"); TFT.foreground(Green); TFT.locate(0,180); TFT.printf(" "); TFT.locate(0,180); TFT.printf("cmd is executed"); wait(1); TFT.locate(0,180); TFT.printf(" "); TFT.foreground(White); execResult = "success"; break; } trial++; } } else { TFT.foreground(Red); TFT.locate(0,180); TFT.printf(" "); TFT.locate(0,180); TFT.printf("node is invalid"); wait(1); TFT.locate(0,180); TFT.printf(" "); TFT.foreground(White); } wait(2); //send execution result //DBG.printf("send execution result\r\n"); //calculate hmacCmd //for(int j=0; j<sizeof(p); j++) { // p[j]=0; } sprintf(p,"emma-%s-%s",emmaUID.c_str(),commandCmd.c_str()); hmacCmd = calculateMD5(p); sprintf(s,"{\"uid\":\"%s\",\"nType\":\"%s\",\"nAddr\":\"%s\",\"dType\":\"%s\",\"cmd\":\"%s\",\"from\":\"%s\",\"result\":\"%s\",\"hmac\":\"%s\"}", emmaUID.c_str(), commandNType.c_str(),commandNAddr.c_str(),commandDType.c_str(),commandCmd.c_str(),commandFrom.c_str(),execResult.c_str(),hmacCmd.c_str()); trial=0; while(1) { if(trial>=2) { //two times trial DBG.printf("failed to send execution result\r\n"); break; } sprintf(p,"/%s/api/controller/result",appNAME.c_str()); rest.post(p,s); //rest.post("/emma/api/controller/result",s); //working wait(2); str = rxBuf; if(str.rfind("/result") != std::string::npos) { str.erase(str.begin(),str.begin()+str.rfind("/result")); if(str.find("\"status\":\"success\"") != std::string::npos) { DBG.printf("success to send execution result\r\n"); break; } } //checkRxBuffer(); trial++; } } else if(commandNType == "2") { //wifi smart plug DBG.printf("command for smart plug\r\n"); //get index of node list based on mac address int idx = NODES_INVALID; for(int i=0; i<NODES_MAX; i++) { if(!nodes[i].macAddr.compare(commandNAddr)) { idx = i; } } //execution process string execResult = "failed"; if(idx != NODES_INVALID) { DBG.printf("index found at %d\r\n",idx); //execute command DBG.printf("executing command\r\n"); sprintf(s,"<?xml version=\"1.0\" encoding=\"utf-8\"?><app_cmd cmd=\"13\"/><app_data on-off=\"%s\"/>\r\n",commandCmd.c_str()); trial=0; while(1) { rxBuf.clear(); if(trial>=2) { //two times trial DBG.printf("cmd is not executed\r\n"); TFT.foreground(Red); TFT.locate(0,180); TFT.printf(" "); TFT.locate(0,180); TFT.printf("cmd is not executed"); wait(1); TFT.locate(0,180); TFT.printf(" "); TFT.foreground(White); break; } nodes[idx].restConn->get("/",s); wait(2); if(rxBuf.find("REST: status = 200") != std::string::npos) { DBG.printf("cmd is executed\r\n"); TFT.foreground(Green); TFT.locate(0,180); TFT.printf(" "); TFT.locate(0,180); TFT.printf("cmd is executed"); wait(1); TFT.locate(0,180); TFT.printf(" "); TFT.foreground(White); execResult = "success"; break; } trial++; } } else { TFT.foreground(Red); TFT.locate(0,180); TFT.printf(" "); TFT.locate(0,180); TFT.printf("node is invalid"); wait(1); TFT.locate(0,180); TFT.printf(" "); TFT.foreground(White); } wait(2); //send execution result //DBG.printf("send execution result\r\n"); //calculate hmacCmd sprintf(p,"emma-%s-%s",emmaUID.c_str(),commandCmd.c_str()); hmacCmd = calculateMD5(p); sprintf(s,"{\"uid\":\"%s\",\"nType\":\"%s\",\"nAddr\":\"%s\",\"dType\":\"%s\",\"cmd\":\"%s\",\"from\":\"%s\",\"result\":\"%s\",\"hmac\":\"%s\"}", emmaUID.c_str(), commandNType.c_str(),commandNAddr.c_str(),commandDType.c_str(),commandCmd.c_str(),commandFrom.c_str(),execResult.c_str(),hmacCmd.c_str()); trial=0; while(1) { if(trial>=2) { //two times trial DBG.printf("failed to send execution result\r\n"); break; } sprintf(p,"/%s/api/controller/result",appNAME.c_str()); rest.post(p,s); //rest.post("/emma/api/controller/result",s); //working wait(2); str = rxBuf; if(str.rfind("/result") != std::string::npos) { str.erase(str.begin(),str.begin()+str.rfind("/result")); if(str.find("\"status\":\"success\"") != std::string::npos) { DBG.printf("success to send execution result\r\n"); break; } } //checkRxBuffer(); trial++; } } } } //clear text on lcd TFT.locate(0,160); TFT.printf(" "); newCommand = false; /* //check whether command is valid bool validCommand = true; for(int i=0; i<5; i++) { validCommand = validCommand && jsonValue.hasMember(parameter[i]); } DBG.printf("command validity:%d\r\n",validCommand); if(validCommand) { string commandFrom = jsonValue[parameter[0]].get<std::string>(); string commandNType = jsonValue[parameter[1]].get<std::string>(); string commandNAddr = jsonValue[parameter[2]].get<std::string>(); string commandDType = jsonValue[parameter[3]].get<std::string>(); string commandCmd = jsonValue[parameter[4]].get<std::string>(); if(commandNType == "0") { //switch on panel controller DBG.printf("command for switch\r\n"); } else if(commandNType == "1") { //node with mac address DBG.printf("command for node\r\n"); //get node ip address based on node mac address //string nodeIP; //nodeIp = readNodeIP(commandNAddr); //nodeIP = "192.168.2.15"; //DBG.printf("nodeIP: %s\r\n",nodeIP.c_str()); //get index of node list based on mac address int idx = NODES_INVALID; for(int i=0; i<NODES_MAX; i++) { if(!nodes[i].macAddr.compare(commandNAddr)) { idx = i; } } //execution process //int trial; string execResult = "failed"; if(idx != NODES_INVALID) { DBG.printf("index found at %d\r\n",idx); //get cmd string based on device type and command number string nodeCmd; nodeCmd = readNodeCmd(commandDType,commandCmd); //nodeCmd = "020129A0163B161315131613153C151316131514143C153C16141414141415151315141414141514141415141414143D1514143D141415141414143D14000D"; //turn off //DBG.printf("nodeCmd: %s\r\n",nodeCmd.c_str()); //execute command DBG.printf("executing command\r\n"); sprintf(s,"<?xml version=\"1.0\" encoding=\"utf-8\"?><app_cmd cmd=\"5\" /><app_data code=\"%s\"/>\r\n",nodeCmd.c_str()); trial=0; while(1) { rxBuf.clear(); //cmdExecuted = false; if(trial>=2) { //two times trial DBG.printf("cmd is not executed\r\n"); TFT.foreground(Red); TFT.locate(0,180); TFT.printf(" "); TFT.locate(0,180); TFT.printf("cmd is not executed"); wait(1); TFT.locate(0,180); TFT.printf(" "); TFT.foreground(White); break; } nodes[idx].restConn->get("/",s); wait(2); if(rxBuf.find("REST: status = 200") != std::string::npos) { DBG.printf("cmd is executed\r\n"); TFT.foreground(Green); TFT.locate(0,180); TFT.printf(" "); TFT.locate(0,180); TFT.printf("cmd is executed"); wait(1); TFT.locate(0,180); TFT.printf(" "); TFT.foreground(White); execResult = "success"; break; } trial++; } } else { TFT.foreground(Red); TFT.locate(0,180); TFT.printf(" "); TFT.locate(0,180); TFT.printf("node is invalid"); wait(1); TFT.locate(0,180); TFT.printf(" "); TFT.foreground(White); } wait(2); //send execution result //DBG.printf("send execution result\r\n"); //calculate hmacCmd for(int j=0; j<sizeof(p); j++) { p[j]=0; } sprintf(p,"emma-%s-%s",emmaUID.c_str(),commandCmd.c_str()); hmacCmd = calculateMD5(p); sprintf(s,"{\"uid\":\"%s\",\"nType\":\"%s\",\"nAddr\":\"%s\",\"dType\":\"%s\",\"cmd\":\"%s\",\"from\":\"%s\",\"result\":\"%s\",\"hmac\":\"%s\"}", emmaUID.c_str(), commandNType.c_str(),commandNAddr.c_str(),commandDType.c_str(),commandCmd.c_str(),commandFrom.c_str(),execResult.c_str(),hmacCmd.c_str()); trial=0; while(1) { if(trial>=2) { //two times trial DBG.printf("failed to send execution result\r\n"); break; } rest.post("/emma/api/controller/result",s); wait(2); str = rxBuf; if(str.rfind("/result") != std::string::npos) { str.erase(str.begin(),str.begin()+str.rfind("/result")); if(str.find("\"status\":\"success\"") != std::string::npos) { DBG.printf("success to send execution result\r\n"); break; } } checkRxBuffer(); trial++; } } } //clear text on lcd TFT.locate(0,160); TFT.printf(" "); newCommand = false; */ } osDelay(5000); } } } void emmaModeFirmwareDownload(void) { bool emmaGetFirmwareParam = false; DBG.printf("emmaModeFirmwareDownload\r\n"); char s[384]; string str; string connData; string chunk; //firmware parameter string firmwareVer; string firmwareName; int numPart; //downloading string firmwarePart; string calcMD5; string srvrMD5; bool nextPart; //set wifi to mode bridge _ESP.printf("MODE=B"); DBG.printf("set mode bridge\r\n"); while(1) { char rcv[128] = {}; rcvReply(rcv,3000); str = rcv; if(str.find("MODE=B_OK") != std::string::npos) break; } DBG.printf("MODE=B\r\n"); esp.enable(); wait(1); while(!esp.ready()); if(!rest.begin("candra.tritronik.com",3128,false)) { DBG.printf("EMMA: fail to setup rest"); while(1); } //wifiConnected = true; //with custom firmware, panel should connect wifi automatically useProxy = true; esp.process(); //set connData if(useProxy) { for(int i=0; i<sizeof(s); i++) { s[i]=0; } //sprintf(s,"http://%s:%d/emma/api/controller/register?uid=%s&hmac=%s",restSERVER,restPORT,emmaUID.c_str(),hmac.c_str()); sprintf(s,"http://192.168.128.69/emmaController/firmware/firmwareParameter"); connData = s; } else { for(int i=0; i<sizeof(s); i++) { s[i]=0; } //sprintf(s,"/emma/api/controller/register?uid=%s&hmac=%s",emmaUID.c_str(),hmac.c_str()); sprintf(s,"/emmaController/firmware/firmwareParameter"); connData = s; } //get parameter of firmware to be downloaded while(!emmaGetFirmwareParam) { rest.get(connData.c_str()); for(int i=0; i<sizeof(s); i++) { s[i]=0; } rest.getResponse(s,sizeof(s)); //DBG.printf("rsp param:%s\r\n",s); str = s; if(str.find("[") != std::string::npos && str.find("]") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("[")+1); str.erase(str.begin()+str.find("]"),str.end()); MbedJSONValue jsonValue; parse(jsonValue,str.c_str()); char *parameter[2] = {"firmwareVer","numPart"}; for(int i=0; i<2; i++) { if(jsonValue.hasMember(parameter[i])) { string val = jsonValue[parameter[i]].get<std::string>(); if(i==0) { firmwareVer = val; } else if(i==1) { sscanf(val.c_str(),"%d",&numPart); } } } if(!firmwareVer.empty() && numPart!=0) { emmaGetFirmwareParam = true; } } } DBG.printf("firmwareVer:%s\r\n",firmwareVer.c_str()); DBG.printf("numPart:%d\r\n",numPart); //clear firmware file while(1) { if(clearFirmware()){ DBG.printf("clear firmware on sd card\r\n\r\n"); break; } wait(1); } //set connData if(useProxy) { for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"http://192.168.128.69/emmaController/firmware/%s",firmwareVer.c_str()); connData = s; } else { for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"/emmaController/firmware/%s",firmwareVer.c_str()); connData = s; } //download firmware for(int n=0; n<numPart; n++) { nextPart = false; while(!nextPart) { for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"%s/firmware_Hex_%s_%d",connData.c_str(),firmwareVer.c_str(),n); rest.get(s); for(int i=0; i<sizeof(s); i++) { s[i]=0; } rest.getResponse(s,sizeof(s)); //DBG.printf("rsp[%d]:%s\r\n",n,s); str = s; if(str.find("{") != std::string::npos && str.find("}") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("{")+1); str.erase(str.begin()+str.find("}"),str.end()); //DBG.printf("firmwarePart[%d]:%s\r\n",n,str.c_str()); firmwarePart = str; //calculated MD5 calcMD5 = calculateMD5(firmwarePart); //DBG.printf("calcMD5[%d]:%s\r\n",n,calcMD5.c_str()); //MD5 from server for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"%s/MD5/firmware_MD5_%s_%d",connData.c_str(),firmwareVer.c_str(),n); rest.get(s); for(int i=0; i<sizeof(s); i++) { s[i]=0; } rest.getResponse(s,sizeof(s)); str = s; if(str.find("{") != std::string::npos && str.find("}") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("{")+1); str.erase(str.begin()+str.find("}"),str.end()); srvrMD5 = str; //DBG.printf("srvrMD5[%d]:%s\r\n",n,srvrMD5.c_str()); //compare original MD5 vs MD5 from server if(strcmp(calcMD5.c_str(),srvrMD5.c_str()) == 0) { //DBG.printf("MD5 correct\r\n"); //save to sd card int st = writeFirmwareHexToChar(firmwarePart); if(st) { DBG.printf("firmwarePart[%d/%d] written\r\n",n,numPart-1); nextPart = true; } } else { DBG.printf("MD5 incorrect\r\n"); } } } else { DBG.printf("retry to fetch firmwarePart[%d]\r\n",n); } wait(0.5); } } DBG.printf("download finished\r\n"); } /*end emma mode*/ /*start energy related*/ void energyThread(void const*) { Timer tEnergy; while(1) { tEnergy.start(); DBG.printf("energyThread-start\r\n"); AWattHrSum = 0; BWattHrSum = 0; CWattHrSum = 0; while(tEnergy.read() < 1*60.0) { AWattHrValue = ADE.getWattHR(PHASE_A); BWattHrValue = ADE.getWattHR(PHASE_B); CWattHrValue = ADE.getWattHR(PHASE_C); AWattHrSum += AWattHrValue; BWattHrSum += BWattHrValue; CWattHrSum += CWattHrValue; //start check voltage and power AVrms = ADE.VRMS(PHASE_A) * 0.000124f; //0.000158; //constants are from calculateVRMS function BVrms = ADE.VRMS(PHASE_B) * 0.000123f; CVrms = ADE.VRMS(PHASE_C) * 0.000122f; AIrms = ADE.IRMS(PHASE_A) * 0.00001006f; //0.0000125f; //constants are from calculateIRMS function BIrms = ADE.IRMS(PHASE_B) * 0.00001005f; CIrms = ADE.IRMS(PHASE_C) * 0.00001004f; AWatt = AVrms * AIrms; BWatt = BVrms * BIrms; CWatt = CVrms * CIrms; //end check voltage and power } AWattHr = AWattHrSum * 0.000044169f; //0.0000198f; BWattHr = BWattHrSum * 0.000044168f; //0.0000197f; CWattHr = CWattHrSum * 0.000044167f; //0.0000196f; newEnergyData = true; tEnergy.stop(); tEnergy.reset(); DBG.printf("energyThread-finish\r\n"); } } void checkVoltagePower(void) { //check if voltage or power violates threshold char p[64]; char q[32]; char s[256]; string hmacTime; string str; time_t seconds; //DBG.printf("checkVoltagePower-start\r\n"); //vrms and irms might be placed inside energy calculation routine /* AVrms = ADE.VRMS(PHASE_A) * 0.000128f; //0.000158; //constants are from calculateVRMS function BVrms = ADE.VRMS(PHASE_B) * 0.000127f; //0.000157; CVrms = ADE.VRMS(PHASE_C) * 0.000126f; //0.000156; AIrms = ADE.IRMS(PHASE_A) * 0.0000125f; //constants are from calculateIRMS function BIrms = ADE.IRMS(PHASE_B) * 0.0000123f; CIrms = ADE.IRMS(PHASE_C) * 0.0000124f; AWatt = AVrms * AIrms; BWatt = BVrms * BIrms; CWatt = CVrms * CIrms; */ //DBG.printf("Vrms of each phase:%.2f - %.2f - %.2f\r\n", AVrms, BVrms, CVrms); //DBG.printf("Watt of each phase:%.2f - %.2f - %.2f\r\n", AWatt, BWatt, CWatt); //wait(1); //get time seconds = time(NULL); strftime(q, 32, "%Y-%m-%d %H:%M:%S",localtime(&seconds)); //calculate hmacTime for(int j=0; j<sizeof(p); j++) { p[j]=0; } sprintf(p,"emma-%s-%s",emmaUID.c_str(),q); hmacTime = calculateMD5(p); if(AVrms > VRMSTHRESHOLD || AWatt > WATTTHRESHOLD) { DBG.printf("alert on ch1\r\n"); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\",\"time\":\"%s\",\"voltage\":%.2f,\"power\":%.2f}", emmaUID.c_str(),hmacTime.c_str(),q,AVrms,AWatt); sprintf(p,"/%s/api/controller/alert/1",appNAME.c_str()); rest.post(p,s); //rest.post("/emma/api/controller/alert/1",s); //working wait(2); str = rxBuf; if(str.rfind("/alert/1") != std::string::npos) { str.erase(str.begin(),str.begin()+str.rfind("/alert/1")); if(str.find("\"status\":\"success\"") != std::string::npos) { DBG.printf("send alert ch1 success\r\n"); } else { DBG.printf("send alert ch1 failed\r\n"); } } } if(BVrms > VRMSTHRESHOLD || BWatt > WATTTHRESHOLD) { DBG.printf("alert on ch2\r\n"); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\",\"time\":\"%s\",\"voltage\":%.2f,\"power\":%.2f}", emmaUID.c_str(),hmacTime.c_str(),q,BVrms,BWatt); sprintf(p,"/%s/api/controller/alert/2",appNAME.c_str()); rest.post(p,s); //rest.post("/emma/api/controller/alert/2",s); wait(2); str = rxBuf; if(str.rfind("/alert/2") != std::string::npos) { str.erase(str.begin(),str.begin()+str.rfind("/alert/2")); if(str.find("\"status\":\"success\"") != std::string::npos) { DBG.printf("send alert ch2 success\r\n"); } else { DBG.printf("send alert ch2 failed\r\n"); } } } if(CVrms > VRMSTHRESHOLD || CWatt > WATTTHRESHOLD) { DBG.printf("alert on ch3\r\n"); DBG.printf("alert on ch3\r\n"); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\",\"time\":\"%s\",\"voltage\":%.2f,\"power\":%.2f}", emmaUID.c_str(),hmacTime.c_str(),q,CVrms,CWatt); sprintf(p,"/%s/api/controller/alert/3",appNAME.c_str()); rest.post(p,s); //rest.post("/emma/api/controller/alert/3",s); wait(2); str = rxBuf; if(str.rfind("/alert/3") != std::string::npos) { str.erase(str.begin(),str.begin()+str.rfind("/alert/3")); if(str.find("\"status\":\"success\"") != std::string::npos) { DBG.printf("send alert ch3 success\r\n"); } else { DBG.printf("send alert ch3 failed\r\n"); } } } //DBG.printf("checkVoltagePower-finish\r\n"); } /*end energy related*/ /*start wifi mqtt*/ void mqttConnected(void* response) { DBG.printf("MQTT Connected\r\n"); char mqttTopic[64]; sprintf(mqttTopic,"%s/%s/command",mqttDOMAIN.c_str(),emmaUID.c_str()); //mqtt.subscribe(mqttTopic); } void mqttDisconnected(void* response) { DBG.printf("MQTT Disconnected\r\n"); } /*end wifi mqtt*/ /*start wifi rest*/ void wifiCb(void* response) { uint32_t status; RESPONSE res(response); if(res.getArgc() == 1) { res.popArgs((uint8_t*)&status,4); if(status == STATION_GOT_IP) { DBG.printf("WIFI Connected\r\n"); //wifiConnected = true; } else { //wifiConnected = false; } } } void rxInterrupt(void) { char c; while(_ESP.readable()) { c = _ESP.getc(); if(c != 0) { //char is not null rxBuf += c; } } } void checkRxBuffer(void) { //check new command if(rxBuf.rfind("/command") != std::string::npos) { rxBuf.erase(rxBuf.begin(),rxBuf.begin()+rxBuf.rfind("/command")); if(rxBuf.find("[{") != std::string::npos && rxBuf.rfind("}]") != std::string::npos) { rxBuf.erase(rxBuf.begin(),rxBuf.begin()+rxBuf.find("[{")); rxBuf.erase(rxBuf.begin()+rxBuf.rfind("}]")+2,rxBuf.end()); //start special handler while(1){ if(rxBuf.find("}],") != std::string::npos) { rxBuf.erase(rxBuf.begin()+rxBuf.find("}],")+1,rxBuf.begin()+rxBuf.find("}],")+2); } else { break; } } //end special handler globalCommand = rxBuf; newCommand = true; } } //check free memory -> reinitialize mqtt connection if(rxBuf.rfind("Free memory") != std::string::npos) { rxLog = "Free memory-" + rxBuf; espFreeMemory = true; } //check dhcp client start -> initialize all connection if(rxBuf.rfind("dhcp client start") != std::string::npos) { rxLogA = "dhcp client start-" + rxBuf; espDHCPClientStart = true; } //clear rxBuf rxBuf.clear(); } /*end wifi rest*/ int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) { MQTT::Message message; char* topic = new char[strlen(mqttDOMAIN.c_str())+strlen(emmaUID.c_str())+9]; *topic = '\0'; strcat(topic, mqttDOMAIN.c_str()); strcat(topic, "/"); strcat(topic, emmaUID.c_str()); strcat(topic, "/dummy"); const char buf[25] = "{\"d\":{\"myName\":\"EMMA\"}}"; message.qos = MQTT::QOS2; message.retained = false; message.dup = false; message.payload = (void*)buf; message.payloadlen = strlen(buf); DBG.printf("Publishing %s\r\n", buf); return client->publish(topic, &message); } /*start eth mqtt*/ void ethMQTTMessageArrived(MQTT::MessageData& md) { MQTT::Message &message = md.message; char topic[md.topicName.lenstring.len + 1]; string str; sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data); DBG.printf("Message arrived on topic %s: %.*s\r\n", topic, message.payloadlen, message.payload); char *s = (char*)message.payload; string sp(s); if(sp.find("[") != std::string::npos && sp.find("]") != std::string::npos) { sp.erase(sp.begin(),sp.begin()+sp.find("[")+1); sp.erase(sp.begin()+sp.find("]"),sp.end()); } else { DBG.printf("Invalid MQTT command"); return; } MbedJSONValue jsonValue; parse(jsonValue, sp.c_str()); const char *parameter[5] = {"name","nType","nAddr","dType","cmd"}; //check if command is valid bool validCommand = true; for(int i=0; i<5; i++) { validCommand = validCommand && jsonValue.hasMember(parameter[i]); } DBG.printf("command validity:%d\r\n",validCommand); //check for new command if(validCommand) { string commandId = jsonValue[parameter[0]].get<std::string>(); string commandNType = jsonValue[parameter[1]].get<std::string>(); string commandNAddr = jsonValue[parameter[2]].get<std::string>(); string commandDType = jsonValue[parameter[3]].get<std::string>(); string commandCmd = jsonValue[parameter[4]].get<std::string>(); if(commandNType == "0") { //switch on panel controller DBG.printf("command for switch\r\n"); } else if(commandNType == "1") { //node with mac address DBG.printf("command for node\r\n"); //get node ip address based on node mac address string nodeIP = readNodeIP(commandNAddr); //DBG.printf("nodeIP: %s\r\n",nodeIP.c_str()); //get cmd string based on device type and command number string nodeCmd = readNodeCmd(commandDType,commandCmd); //DBG.printf("nodeCmd: %s\r\n",nodeCmd.c_str()); //execute command int trial=0; trial = 0; bool execStatus=false; while( !execStatus ) { sprintf(s,"<?xml version=\"1.0\" encoding=\"utf-8\"?><app_cmd cmd=\"5\" /><app_data code=\"%s\"/>\r\n",nodeCmd.c_str()); str.assign(s); DBG.printf("str value:%s\r\n",str.c_str()); string rcv = ethREST(nodeIP,REMOTE_TCP_PORT,str); // cause mqtt to stop DBG.printf("response:%s\r\n",rcv.c_str()); str = rcv; if(str.find("OK") != std::string::npos) { DBG.printf("CMD executed successfully\r\n"); execStatus = true; break; } if(trial>5) { //two times trial DBG.printf("cmd is not executed\r\n"); execStatus = false; } DBG.printf("Trial++\r\n"); trial++; wait(3); } DBG.printf("Send execution status\r\n"); //send execution status } } DBG.printf("Finish processing new command\r\n"); /* MQTT::Message &message = md.message; DBG.printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id); DBG.printf("Payload: %.*s\r\n", message.payloadlen, (char*)message.payload); //DBG.printf("Payload %s\r\n",message.payload); //check whether cmd is json //char r[255]; char *s = (char*)message.payload; string sp(s); //sprintf(s,"%.*s",message.payloadlen, (char*)message.payload); //sprintf(globCmd,"%s",s); //DBG.printf("Payload: %s\r\n", r); //string cmd = r; //globalCommand = cmd; //globalCommand = sp; //globCmd = (char*)message.payload; //string globCmd((char*)message.payload); //std::string *sp = static_cast<std::char*>(message.payload); //string sp((char*)message.payload); //DBG.printf("String: %s\r\n",sp.c_str()); //globCmd = sp; //newCommand = true; if(sp.find("[") != std::string::npos && sp.find("]") != std::string::npos) { sp.erase(sp.begin(),sp.begin()+sp.find("[")+1); sp.erase(sp.begin()+sp.find("]"),sp.end()); globalCommand = sp; newCommand = true; } sp.clear(); */ } int ethMQTTConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) { char *pMqttServer = &mqttSERVER[0u]; int connPort; sscanf(mqttPORT.c_str(),"%d",&connPort); int rc = ipstack->connect(pMqttServer, connPort); if(rc!=0) return rc; //MQTT Connect char clientId [64]; sprintf(clientId,"emma/%s",emmaUID.c_str()); //DBG.printf("clientId:%s\r\n",clientId); MQTTPacket_connectData data = MQTTPacket_connectData_initializer; data.MQTTVersion = 3; data.clientID.cstring = clientId; data.username.cstring = "761b233e-a49a-4830-a8ae-87cec3dc1086"; data.password.cstring = "ef25cf4567fbc07113252f8d72b7faf2"; if((rc = client->connect(&data)) == 0) { DBG.printf("ethMQTT connected\r\n"); } //MQTT Subscribe //char s[64]; //sprintf(s,"%s/%s/command",mqttDOMAIN.c_str(),emmaUID.c_str()); //string topic = s; char* topic = new char[strlen(mqttDOMAIN.c_str())+strlen(emmaUID.c_str())+9]; *topic = '\0'; strcat(topic, mqttDOMAIN.c_str()); strcat(topic, "/"); strcat(topic, emmaUID.c_str()); strcat(topic, "/command"); DBG.printf("topic:%s\r\n",topic); if((rc=client->subscribe(topic,MQTT::QOS0,ethMQTTMessageArrived)) == 0) { DBG.printf("subscribe success!\r\n"); } return rc; } void ethMQTTAttemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) { int retryAttempt = 0; while(!ipstack->getEth().linkstatus()) { DBG.printf("Ethernet link not present. Check cable connection\r\n"); wait(1); } while(ethMQTTConnect(client,ipstack) != 0) { int timeout = 3; DBG.printf("Retry attempt number %d waiting %d\r\n", retryAttempt, timeout); wait(timeout); retryAttempt++; } } /*end eth mqtt*/ /*start emma settings*/ string getUID(void) { char s[32]; unsigned long *unique = (unsigned long *)BASE_ADDR; sprintf(s,"%08x%08x%08x",unique[0], unique[1], unique[2]); return s; } string readSetting(string parameter) { FILE *fp; signed char c; int i=0; char s[64]; string strS; sprintf(s,"/sd/settings/%s.txt",parameter.c_str()); fp = fopen(s,"r"); memset(s,0,sizeof(s)); if(fp != NULL) { while(1) { c = fgetc(fp); if(c == EOF){ break; } s[i] = c; i++; } strS = s; if(strS.find("(") != std::string::npos && strS.find(")") != std::string::npos) { strS.erase(strS.begin(),strS.begin()+strS.find("(")+1); strS.erase(strS.begin()+strS.find(")"),strS.end()); } else { strS = ""; } } fclose(fp); free(fp); return strS; } bool writeSetting(string parameter, string value) { FILE *fp; char s[255]; sprintf(s,"/sd/settings/%s.txt",parameter.c_str()); fp = fopen(s,"w"); if(fp != NULL) { fprintf(fp,value.c_str()); fclose(fp); free(fp); return true; } fclose(fp); free(fp); return false; } /*end emma settings*/ /*start emma node*/ string readNodeIP(string macAddr) { FILE *fp; signed char c; int i=0; char s[64]; string strS; sprintf(s,"/sd/nodeList/%s/nodeIP.txt",macAddr.c_str()); fp = fopen(s,"r"); memset(s,0,sizeof(s)); if(fp != NULL) { while(1) { c = fgetc(fp); if(c == EOF){ break; } s[i] = c; i++; } strS = s; if(strS.find("(") != std::string::npos && strS.find(")") != std::string::npos) { strS.erase(strS.begin(),strS.begin()+strS.find("(")+1); strS.erase(strS.begin()+strS.find(")"),strS.end()); } else { strS = ""; } } fclose(fp); free(fp); return strS; } string readNodeCmd(string dType, string cmd) { FILE *fp; signed char c; int i=0; char s[2048]; string strS; sprintf(s,"/sd/nodeCode/%s/%s.txt",dType.c_str(),cmd.c_str()); fp = fopen(s,"r"); memset(s,0,sizeof(s)); if(fp != NULL) { while(1) { c = fgetc(fp); if(c == EOF){ break; } s[i] = c; i++; } strS = s; if(strS.find("(") != std::string::npos && strS.find(")") != std::string::npos) { strS.erase(strS.begin(),strS.begin()+strS.find("(")+1); strS.erase(strS.begin()+strS.find(")"),strS.end()); } else { strS = ""; } } fclose(fp); free(fp); return strS; } string *readNodeList(void) { static string nd[10]; //max node DIR *d; struct dirent *p; string q; int i=0; d = opendir("/sd/nodeList"); if(d != NULL) { while((p = readdir(d)) != NULL) { q = p->d_name; nd[i] = q; i++; } } closedir(d); free(d); return nd; } string wifiGetNodeTemp(string macAddr) { int trial=0; string nodeIP = readNodeIP(macAddr); string str; string temp = "0"; if(rest.begin(nodeIP.c_str(),REMOTE_TCP_PORT,false)) { while(1) { char rcv[256] = {}; rest.get("/","<?xml version=\"1.0\" encoding=\"utf-8\"?><app_cmd cmd=\"2\"/>\r\n"); rest.getResponse(rcv,sizeof(rcv)); str = rcv; if(str.find("temp=") != std::string::npos) { str.erase(str.begin(),str.begin()+str.find("temp=")+6); str.erase(str.begin()+str.find("\""),str.end()); temp = str; break; } if(trial>1) { //three times trial break; } trial++; wait(2); } } return temp; } /*end emma node*/ /*start emma connection function*/ string ethREST(string host, int port, string data) { char buf[1024]; char s[256]; int ret; TCPSocketConnection sock; Timer t; sprintf(s,"%s",data.c_str()); sock.connect(host.c_str(),port); sock.send_all(s,sizeof(s)-1); wait(2); //receive return t.start(); while(1) { ret = sock.receive(buf, sizeof(buf)); if(ret<=0 || t.read_ms() > 10000) { t.stop(); break; } } sock.close(); return buf; } /*end emma connection function*/ /*start emma private function*/ void isEthAvailable(void) { if(ipstack.getEth().linkstatus()) { ethAvailable = true; } else { ethAvailable = false; } } void isEthConnected(void) { char s[512]; int connPort; string connHost; string str; Timer t; if(ethAvailable) { if(useProxy) { connHost = proxySERVER; sscanf(proxyPORT.c_str(),"%d",&connPort); for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"GET http://%s:%s/%s/api/controller/test HTTP/1.0\nHost: %s\r\n\r\n",restSERVER.c_str(),restPORT.c_str(),appNAME.c_str(),restSERVER.c_str()); } else { connHost = restSERVER; //connPort = restPORT; sscanf(restPORT.c_str(),"%d",&connPort); for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"GET /%s/api/controller/test HTTP/1.0\nHost: %s\r\n\r\n",appNAME.c_str(),restSERVER.c_str()); } t.start(); while(1) { str = ethREST(connHost,connPort,s); if(str.find("OK") != std::string::npos) { t.stop(); ethConnected = true; break; } if(t.read_ms() > 5000) { t.stop(); ethConnected = false; break; } } } else { ethConnected = false; } } void isWiFiConnected(void) { //WARNING: should be run in emmaModeRegister and emmaModeOperation only - limitation with esp, after MODE=B, cannot go to MODE=S char s[512]; int connPort; string connHost; string str; Timer t; /* esp.enable(); wait(1); esp.reset(); wait(1); while(!esp.ready()); //rest begin if(!rest.begin(restSERVER,restPORT,false)) { DBG.printf("EMMA: fail to setup rest\r\n"); TFT.locate(0,20); TFT.printf("EMMA: fail to setup rest"); while(1); } //setup wifi DBG.printf("EMMA: setup wifi\r\n"); TFT.locate(0,20); TFT.printf("EMMA: setup wifi"); wait(1); esp.wifiCb.attach(&wifiCb); //esp.wifiConnect("Tritronik Mobile","Tri12@11"); esp.wifiConnect(wifiSSID.c_str(),wifiPASS.c_str()); DBG.printf("EMMA: system started\r\n"); TFT.locate(0,20); TFT.printf("EMMA: system started"); t.start(); while(t.read() < 20); t.stop(); t.reset(); TFT.locate(0,20); TFT.printf(" "); */ if(wifiAvailable) { _ESP.printf("MODE=B"); if(useProxy) { connHost = proxySERVER; sscanf(proxyPORT.c_str(),"%d",&connPort); for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"http://%s:%s/%s/api/controller/test HTTP/1.0\nHost: %s\r\n\r\n",restSERVER.c_str(),restPORT.c_str(),appNAME.c_str(),restSERVER.c_str()); } else { connHost = restSERVER; //connPort = restPORT; sscanf(restPORT.c_str(),"%d",&connPort); for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"/%s/api/controller/test",appNAME.c_str()); } wait(2); t.start(); while(!esp.ready() && t.read() < 20); t.stop(); t.reset(); if(rest.begin(connHost.c_str(),connPort,false)) { DBG.printf("rest begin\r\n"); esp.process(); rest.get(s); for(int i=0; i<sizeof(s); i++) { s[i]=0; } rest.getResponse(s,sizeof(s)); str = s; DBG.printf("response:%s\r\n",s); if(str.find("OK") != std::string::npos) { wifiConnected = true; } } else { wifiConnected = false; } } else { wifiConnected = false; } } void isGprsConnected(void) { } void addChar(char *s, char c) { uint16_t k; //customized for EMS k = strlen(s); s[k] = c; s[k + 1] = 0; } void rcvReply(char *r, int to) { Timer t; bool ended = false; char c; strcpy(r,""); t.start(); while(!ended) { if(_ESP.readable()) { c = _ESP.getc(); addChar(r,c); t.start(); } if(t.read_ms() > to) { ended = true; } } addChar(r, 0x00); } string calculateMD5(string text) { char s[64]; memset(s,0,sizeof(s)); //for unknown reason, after reading UID, the 's' will contaion UID data uint8_t hash[16]; MD5::computeHash(hash, (uint8_t*)text.c_str(), strlen(text.c_str())); for(int i=0; i<16; ++i) { sprintf(s,"%s%02x",s,hash[i]); } return s; } bool writeFirmwareHexToChar(string value) { FILE *fp; char s[32]; int number; string chunk; sprintf(s,"/sd/newFirmware/firmware.bin"); fp = fopen(s,"a"); if(fp != NULL) { for(int ch=0; ch<value.size(); ch+=2) { chunk = value.substr(ch,2); sscanf(chunk.c_str(),"%x",&number); fprintf(fp,"%c",number); } fclose(fp); free(fp); return true; } fclose(fp); free(fp); return false; } bool clearFirmware(void) { FILE *fp; char s[32]; sprintf(s,"/sd/newFirmware/firmware.bin"); fp = fopen(s,"w"); if(fp != NULL) { fprintf(fp,""); fclose(fp); free(fp); return true; } fclose(fp); free(fp); return false; } bool writeLog(string logTime, string logData) { FILE *fp; char s[255]; string logAll; logAll = logTime + "\t" + logData + "\r\n"; sprintf(s,"/sd/log.txt"); fp = fopen(s,"a"); if(fp != NULL) { fprintf(fp,logAll.c_str()); fclose(fp); free(fp); return true; } fclose(fp); free(fp); return false; } bool writeDbg(string dbgTime, string dbgData) { FILE *fp; char s[255]; string dbgAll; dbgAll = dbgTime + "\t" + dbgData + "\r\n"; sprintf(s,"/sd/dbg.txt"); fp = fopen(s,"a"); if(fp != NULL) { fprintf(fp,dbgAll.c_str()); fclose(fp); free(fp); return true; } fclose(fp); free(fp); return false; } /*end emma private function*/