able to subscribe for >10hrs and still running
Dependencies: ADE7758_v1 Crypto DHT11 MQTT MbedJSONValue SDFileSystem SPI_TFT_ILI9341 SWSPI SetRTC TFT_fonts Touch W5500Interface mbed-rtos mbed-src tuanpm
Fork of PB_emma_controller_mbed_src by
emmaCode.cpp
- Committer:
- arsenalist
- Date:
- 2015-07-15
- Revision:
- 15:136526c28afb
- Parent:
- 14:8287f0f5d987
- Child:
- 16:3c8d0142bf63
File content as of revision 15:136526c28afb:
#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 //InterruptIn tpIRQ(PB_2); //emma settings string emmaUID; string hmac; string platformDOMAIN; string platformKEY; string platformSECRET; string wifiSSID; string wifiPASS; string gprsAPN; string proxySERVER; string proxyPORT; string proxyAUTH; //nodes settings class NODES { public: REST *restConn; NODES(REST *r); 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; }; //ade7758 variables uint16_t AWattHrValue, BWattHrValue, CWattHrValue; uint16_t AVAHrValue, BVAHrValue, CVAHrValue; long AWattHrSum = 0; long BWattHrSum = 0; long 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; string globalCommand; string rxBuf; /*start lcd and touch*/ int emmaModeSelection(void) { bool modeSelected = false; int md=0; int TPx; int TPy; 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]); TFT.locate(0,0); TFT.printf(" X:"); TFT.locate(70,0); TFT.printf(" Y:"); //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 = "wifi config"; //setting mode menu[MODE_SETTINGS].xTL = 120; menu[MODE_SETTINGS].yTL = 25; menu[MODE_SETTINGS].xBR = 205; menu[MODE_SETTINGS].yBR = 90; menu[MODE_SETTINGS].text = "settings"; //register mode menu[MODE_REGISTER].xTL = 25; menu[MODE_REGISTER].yTL = 100; menu[MODE_REGISTER].xBR = 110; menu[MODE_REGISTER].yBR = 165; menu[MODE_REGISTER].text = "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 = "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 = "firmware download"; //reserved mode menu[5].xTL = 215; menu[5].yTL = 100; menu[5].xBR = 300; menu[5].yBR = 165; menu[5].text = "reserved"; for(int i=0; i<6; i++) { TFT.fillrect(menu[i].xTL,menu[i].yTL,menu[i].xBR,menu[i].yBR,Orange); } 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); TFT.locate(25,0); TFT.printf("%03d",TPx); TFT.locate(95,0); TFT.printf("%03d",TPy); for(int i=0; i<6; i++) { if((menu[i].xTL < TPx && TPx < menu[i].xBR) && (menu[i].yTL < TPy && TPy < menu[i].yBR)) { //TFT.locate(25,170); //TFT.printf(" "); //TFT.locate(25,170); //TFT.printf("mode: %s is selected",menu[i].text.c_str()); //wait(3); md = i; modeSelected = true; } } } } } TFT.locate(25,170); TFT.printf(" "); TFT.locate(25,170); TFT.printf("mode: %s is selected",menu[md].text.c_str()); wait(2); TFT.cls(); return md; } /*end lcd and touch*/ /*start emma mode*/ void emmaInit(int mode) { char s[64]; DBG.baud(19200); DBG.printf("\r\nemmaInit\r\n"); DBG.printf("mode:%d\r\n",mode); //read settings //readSetting("emmaUID"); //sd card need to be read once before working correctly 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()); platformDOMAIN = readSetting("platformDOMAIN"); //platformDOMAIN = "testdulu"; DBG.printf("platformDOMAIN:%s\r\n",platformDOMAIN.c_str()); platformKEY = readSetting("platformKEY"); //platformKEY = "5980e444-81dd-47ba-8222-6a40bc94fdce"; DBG.printf("platformKEY:%s\r\n",platformKEY.c_str()); platformSECRET = readSetting("platformSECRET"); //platformSECRET = "3ca8ec0239fda2b6d12ba1580c91a052"; DBG.printf("platformSECRET:%s\r\n",platformSECRET.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()); //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; //we assume wifi will always available 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; 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; } 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]); } else { DBG.printf("%s is not saved\r\n",parameter[i]); } } } } } } } else { DBG.printf("no wifi found\r\n"); } } void emmaModeSettings(void) { bool clientIsConnected = false; bool serverIsListened = false; char s[32]; string str; //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"); 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"); } else { DBG.printf("tcp server is listening...\r\n"); } clientSock.set_blocking(false,30000); //timeout after 30sec //listening while (serverIsListened) { if(svr.accept(clientSock) < 0) { DBG.printf("failed to accept connection\r\n"); } else { DBG.printf("connection success!\r\nIP: %s\r\n",clientSock.get_address()); 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()); } else { DBG.printf("%s is not saved\r\n",parameter[i]); } } } //set time if(jsonValue.hasMember(parameter[4])) { string epTime = jsonValue[parameter[4]].get<std::string>(); int seconds; sscanf(epTime.c_str(),"%d",&seconds); set_time(seconds); DBG.printf("time is set\r\n"); } } break; } } DBG.printf("close connection\r\n"); 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"); 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()); } else { DBG.printf("%s is not saved\r\n",parameter[i]); } } } //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"); } } } else if(str.find("connect") != std::string::npos) { DBG.printf("connection success!\r\n"); } } } else { DBG.printf("no eth or wifi is available\r\n"); } } void emmaModeRegister(void) { bool emmaGetRegKey = false; bool emmaRegistered = false; char s[512]; char r[256]; int connPort; int loop = 0; string connData; string connHost; //string hmac; string str; string regKey; Timer t; //check connected interface //connectedIface(); isEthConnected(); isWiFiConnected(); isGprsConnected(); DBG.printf("ethConnected:%d\r\n",ethConnected); DBG.printf("wifiConnected:%d\r\n",wifiConnected); //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()); if(ethConnected) { DBG.printf("emmaModeRegister - eth\r\n"); //set connHost, connPort, connData 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:%d/emma/api/controller/register?uid=%s&hmac=%s HTTP/1.0\nHost: %s\r\n\r\n",EMMA_SERVER_HOST,EMMA_SERVER_PORT,emmaUID.c_str(),hmac.c_str(),EMMA_SERVER_HOST); connData = s; } else { DBG.printf("no proxy\r\n"); connHost = EMMA_SERVER_HOST; connPort = EMMA_SERVER_PORT; 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(),EMMA_SERVER_HOST); connData = s; } //register while(!emmaGetRegKey) { str = ""; str = ethGET(connHost,connPort,connData); DBG.printf("rsp reg:%s\r\n",str.c_str()); //check and save platform 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] = {"platformDOMAIN","platformKEY","platformSECRET","registrationKey"}; //save platform 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()); 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 connData if(useProxy) { DBG.printf("use proxy\r\n"); for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"GET http://%s:%d/emma/api/controller/verify?uid=%s®istrationKey=%s&hmac=%s HTTP/1.0\nHost: %s\r\n\r\n",EMMA_SERVER_HOST,EMMA_SERVER_PORT,emmaUID.c_str(),regKey.c_str(),hmac.c_str(),EMMA_SERVER_HOST); 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(),EMMA_SERVER_HOST); connData = s; } //verify registration while(!emmaRegistered && loop < 12){ str.clear(); str = ethGET(connHost,connPort,connData); DBG.printf("rsp vrf:%s\r\n",str.c_str()); //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()); emmaRegistered = true; } } wait(5); loop++; } //check whether registration success if(emmaRegistered) { DBG.printf("registration successful\r\n"); } else { DBG.printf("registration unsuccessful\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 = EMMA_SERVER_HOST; connPort = EMMA_SERVER_PORT; } //rest begin if(!rest.begin(connHost.c_str(),connPort,false)) { DBG.printf("EMMA: fail to setup rest"); while(1); } //wifiConnected = true; //with custom firmware, wifi module should connect automatically esp.process(); if(wifiConnected) { //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",EMMA_SERVER_HOST,EMMA_SERVER_PORT,emmaUID.c_str(),hmac.c_str()); 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()); connData = s; } //register while(!emmaGetRegKey) { rest.get(connData.c_str()); 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 platform 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] = {"platformDOMAIN","platformKEY","platformSECRET","registrationKey"}; //save platform 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()); 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 connData if(useProxy) { for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"http://%s:%d/emma/api/controller/verify?uid=%s®istrationKey=%s&hmac=%s",EMMA_SERVER_HOST,EMMA_SERVER_PORT,emmaUID.c_str(),regKey.c_str(),hmac.c_str()); connData = s; } else { for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"/emma/api/controller/verify?uid=%s®istrationKey=%s&hmac=%s",emmaUID.c_str(),regKey.c_str(),hmac.c_str()); connData = s; } //verify registration while(!emmaRegistered && loop < 12){ rest.get(connData.c_str()); for(int i=0; i<sizeof(s); i++) { s[i]=0; } rest.getResponse(s,sizeof(s)); DBG.printf("rsp vrf:%s\r\n",s); //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()); emmaRegistered = true; } } wait(5); loop++; } //check whether registration success if(emmaRegistered) { DBG.printf("registration successful\r\n"); } else { DBG.printf("registration unsuccessful\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"); } } void emmaModeOperation(void) { char mqttClientId[32]; char q[32]; char r[32]; char s[512]; int loop=0; //string hmac; string str; time_t seconds; Timer t; Timer tNodes; //check connected interface //connectedIface(); 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"); } //calculate hmac //for(int j=0; j<sizeof(s); j++) { // s[j]=0; } //sprintf(s,"emma-%s",emmaUID.c_str()); //hmac = calculateMD5(s); //DBG.printf("hmac:%s\r\n",hmac.c_str()); if(ethConnected) { DBG.printf("emmaModeOperation - eth\r\n"); //DBG.printf("IP Address:%s\r\n",ipstack.getEth().getIPAddress()); //DBG.printf("MAC Address:%s\r\n",ipstack.getEth().getMACAddress()); ethMQTTAttemptConnect(&client, &ipstack); //t.start(); DBG.printf("start\r\n"); while(true) { //if(!ipstack.getEth().linkstatus()) { // NVIC_SystemReset(); //} //if(t.read_ms() > 5000) { // if(publish(&client,&ipstack) != 0) // ethMQTTAttemptConnect(&client, &ipstack); // t.reset(); //} //check for new command if(newCommand) { DBG.printf("newCommand\r\n"); //DBG.printf("globalCommand: %s\r\n",globalCommand.c_str()); //string qw(globCmd); //if(cmd.find("[") != std::string::npos && cmd.find("]") != std::string::npos) { // cmd.erase(cmd.begin(),cmd.begin()+cmd.find("[")+1); // cmd.erase(cmd.begin()+cmd.find("]"),cmd.end()); //globalCommand = cmd; //newCommand = true; //} /* MbedJSONValue jsonValue; parse(jsonValue,globalCommand.c_str()); char *parameter[5] = {"id","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); 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; string execStatus="failed"; while(1) { sprintf(s,"<?xml version=\"1.0\" encoding=\"utf-8\"?><app_cmd cmd=\"5\" /><app_data code=\"%s\"/>\r\n",nodeCmd.c_str()); str = s; string rcv = ethGET(nodeIP,REMOTE_TCP_PORT,str); DBG.printf("response:%s\r\n",rcv.c_str()); str = rcv; if(str.find("OK") != std::string::npos) { DBG.printf("cmd executed\r\n"); execStatus = "success"; break; } if(trial>0) { //two times trial DBG.printf("cmd is not executed\r\n"); break; } trial++; wait(3); } //send execution status } } */ newCommand = false; } client.yield(100); //allow MQTT client to receive message } } else if(wifiConnected) { DBG.printf("emmaModeOperation - wifi\r\n"); //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, platformKEY.c_str(), platformSECRET.c_str(), 120, 1)) { mqtt.connectedCb.attach(&mqttConnected); mqtt.disconnectedCb.attach(&mqttDisconnected); mqtt.connect(MQTT_HOST,MQTT_PORT,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.AVRMSCalib = 1526873.00; ADE.BVRMSCalib = 534202.00; ADE.CVRMSCalib = 456990.00; ADE.AIRMSCalib = 39248.00; ADE.BIRMSCalib = 654.00; ADE.CIRMSCalib = 111.00; 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); ADE.AWhLSB = 0.000001192;//0.00006025556; ADE.BWhLSB = 0.25075167; ADE.CWhLSB = 0.25075167; ADE.AVAhLSB = 0.00008370; ADE.BVAhLSB = 0; ADE.CVAhLSB = 0; //init rest to server if(rest.begin(EMMA_SERVER_HOST,EMMA_SERVER_PORT,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 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"); } //preset nodes' macAddr and ipAddr //nodes[0].macAddr = "002629034222"; //nodes[0].ipAddr = "192.168.2.15"; //nodes[1].macAddr = "00262903424e"; //nodes[1].ipAddr = "192.168.2.32"; //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); } } _ESP.attach(&rxInterrupt,Serial::RxIrq); //define thread osThreadDef(energyThread, osPriorityBelowNormal, (4*DEFAULT_STACK_SIZE)); //create thread osThreadCreate(osThread(energyThread),NULL); t.start(); tNodes.start(); wait(1); while(1) { checkRxBuffer(); checkVoltagePower(); //panelEnergy, panelVoltage, and panelPower if(t.read_ms() > 10000) { 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); //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; } sprintf(r,"/emma/api/controller/energy/%d",i); seconds = time(NULL); for(int j=0; j<sizeof(q); j++) { q[j]=0; } strftime(q, 32, "%Y-%m-%d %H:%M:%S\r\n",localtime(&seconds)); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\",\"time\":\"%s\",\"energy\":%.2f,\"voltage\":%.2f,\"power\":%.2f}", emmaUID.c_str(),hmac.c_str(),q,XWattHr,XVrms,XWatt); //DBG.printf("dataEnergy:%s\r\n",s); rest.post(r,s); wait(2); if(rxBuf.find("\"status\":\"success\"") != std::string::npos) { 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 { 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); } } t.reset(); loop++; } checkRxBuffer(); checkVoltagePower(); //nodeTemp if(tNodes.read_ms() > 30000) { 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 seconds = time(NULL); for(int j=0; j<sizeof(q); j++) { q[j]=0; } strftime(q, 32, "%Y-%m-%d %H:%M:%S\r\n",localtime(&seconds)); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\",\"time\":\"%s\",\"mac\":\"%s\",\"value\":%s}", emmaUID.c_str(),hmac.c_str(),q,nodes[i].macAddr.c_str(),temp.c_str()); //DBG.printf("dataNodeTemp:%s\r\n",s); rest.post("/emma/api/controller/nodetemp",s); wait(2); temp = rxBuf; if(temp.rfind("/nodetemp") != std::string::npos) { temp.erase(temp.begin(),temp.begin()+temp.rfind("/nodetemp")); if(temp.find("\"status\":\"success\"") != std::string::npos) { DBG.printf("send nodeTemp success\r\n"); } else { DBG.printf("send nodeTemp failed\r\n"); } } checkRxBuffer(); checkVoltagePower(); } } } checkRxBuffer(); checkVoltagePower(); //command 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] = {"name","nType","nAddr","dType","cmd"}; //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 commandName = 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) { //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: Sent") != 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"); sprintf(s,"{\"uid\":\"%s\",\"nType\":\"%s\",\"nAddr\":\"%s\",\"dType\":\"%s\",\"cmd\":\"%s\",\"result\":\"%s\",\"name\":\"%s\"}", emmaUID.c_str(), commandNType.c_str(),commandNAddr.c_str(),commandDType.c_str(),commandCmd.c_str(),execResult.c_str(),commandName.c_str()); trial=0; while(1) { if(trial>=2) { //two times trial DBG.printf("send execution result failed\r\n"); break; } rest.post("/emma/api/controller/test",s); wait(2); if(rxBuf.find("\"status\":\"OK\"") != std::string::npos) { DBG.printf("send execution result success\r\n"); break; } 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",EMMA_SERVER_HOST,EMMA_SERVER_PORT,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*) { while(1) { //DBG.printf("insideEnergyThread\r\n"); //osDelay(5000); //calculate energy /* DBG.printf("energyThread-start\r\n"); float period = 0; AWattHrSum = 0; BWattHrSum = 0; CWattHrSum = 0; while(period < 1*60.0) { period += ADE.getAccumulationTime(PHASE_A); ADE.getAccumulatedEnergy(PHASE_A, &AWattHrValue, &BWattHrValue, &CWattHrValue, &AVAHrValue, &BVAHrValue, &CVAHrValue); AWattHrSum += AWattHrValue; BWattHrSum += BWattHrValue; CWattHrSum += CWattHrValue; } AWattHr = AWattHrSum;// * ADE.AWhLSB; BWattHr = BWattHrSum * ADE.BWhLSB; CWattHr = CWattHrSum * ADE.CWhLSB; DBG.printf("energyThread-finish\r\n"); */ //testing DBG.printf("thread called\r\n"); Timer t; t.start(); while(t.read_ms() < 5000) { t.stop(); t.reset(); } DBG.printf("thread ended\r\n"); } } void checkVoltagePower() { //check if voltage or power violates threshold char s[256]; string str; //DBG.printf("checkVoltagePower-start\r\n"); AVrms = ADE.VRMS(PHASE_A) * 0.000128; //0.000158; //constants are from calculateVRMS function BVrms = ADE.VRMS(PHASE_B) * 0.000127; //0.000157; CVrms = ADE.VRMS(PHASE_C) * 0.000126; //0.000156; AIrms = ADE.IRMS(PHASE_A) * 0.0000125; //constants are from calculateIRMS function BIrms = ADE.IRMS(PHASE_B) * 0.0000123; CIrms = ADE.IRMS(PHASE_C) * 0.0000124; AWatt = AVrms * AIrms; BWatt = BVrms * BIrms; CWatt = CVrms * CIrms; if(AVrms > VRMSTHRESHOLD || AWatt > WATTTHRESHOLD) { DBG.printf("alert on ch1\r\n"); sprintf(s,"{\"uid\":\"%s\",\"hmac\":\"%s\",\"time\":\"2015-06-09 12:32:12\",\"voltage\":%.2f,\"power\":%.2f}", emmaUID.c_str(),hmac.c_str(),AVrms,AWatt); rest.post("/emma/api/controller/alert/1",s); 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\":\"2015-06-09 12:32:12\",\"voltage\":%.2f,\"power\":%.2f}", emmaUID.c_str(),hmac.c_str(),BVrms,BWatt); 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\":\"2015-06-09 12:32:12\",\"voltage\":%.2f,\"power\":%.2f}", emmaUID.c_str(),hmac.c_str(),CVrms,CWatt); 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",platformDOMAIN.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 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.find("}]") != std::string::npos) { rxBuf.erase(rxBuf.begin(),rxBuf.begin()+rxBuf.find("[{")+1); rxBuf.erase(rxBuf.begin()+rxBuf.find("]"),rxBuf.end()); globalCommand = rxBuf; //DBG.printf("gC:%s\r\n",globalCommand.c_str()); newCommand = true; } } //clear rxBuf rxBuf.clear(); } /*end wifi rest*/ /*start eth mqtt*/ void ethMQTTMessageArrived(MQTT::MessageData& md) { 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 hostname[] = "q.thingfabric.com"; //char hostname[] = "192.168.131.200"; //int rc = ipstack->connect(hostname, MQTT_PORT); int rc = ipstack->connect(MQTT_HOST, MQTT_PORT); if(rc!=0) return rc; //MQTT Connect //char clientId[] = "emma/0674ff575349896767072538"; char clientId [32]; 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("connected\r\n"); } //MQTT Subscribe //char* topic = "gaisbwqreqrfxjc/0674ff575349896767072538/command"; char s[64]; sprintf(s,"%s/%s/command",platformDOMAIN.c_str(),emmaUID.c_str()); string topic = s; //DBG.printf("topic:%s\r\n",topic.c_str()); if((rc=client->subscribe(topic.c_str(),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); 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); return true; } 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); return strS; } string readNodeCmd(string dType, string cmd) { FILE *fp; signed char c; int i=0; char s[128]; 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); 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); 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 ethGET(string host, int port, string url) { char buf[1024]; char s[256]; int ret; TCPSocketConnection sock; Timer t; sprintf(s,"%s",url.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 connectedIface(void) { //WARNING: should be run in emmaModeRegister and emmaModeOperation only - problem with esp, after MODE=B, cannot go back to MODE=S char s[512]; int connPort; string connHost; string str; Timer t; //wifi interface 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:%d/emma/api/controller/test HTTP/1.0\nHost: %s\r\n\r\n",EMMA_SERVER_HOST,EMMA_SERVER_PORT,EMMA_SERVER_HOST); } else { connHost = EMMA_SERVER_HOST; connPort = EMMA_SERVER_PORT; for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"/emma/api/controller/test"); } wait(1); t.start(); while(!esp.ready() && t.read_ms() < 5000); t.stop(); 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; } //eth interface 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:%d/emma/api/web/test HTTP/1.0\nHost: %s\r\n\r\n",EMMA_SERVER_HOST,EMMA_SERVER_PORT,EMMA_SERVER_HOST); } else { connHost = EMMA_SERVER_HOST; connPort = EMMA_SERVER_PORT; for(int i=0; i<sizeof(s); i++) { s[i]=0; } strcpy(s,"GET /emma/api/web/test HTTP/1.0\nHost: %s\r\n\r\n"); } t.start(); while(1) { str = ethGET(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; } //gprs interface } */ 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:%d/emma/api/controller/test HTTP/1.0\nHost: %s\r\n\r\n",EMMA_SERVER_HOST,EMMA_SERVER_PORT,EMMA_SERVER_HOST); } else { connHost = EMMA_SERVER_HOST; connPort = EMMA_SERVER_PORT; for(int i=0; i<sizeof(s); i++) { s[i]=0; } strcpy(s,"GET /emma/api/controller/test HTTP/1.0\nHost: %s\r\n\r\n"); } t.start(); while(1) { str = ethGET(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; 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:%d/emma/api/controller/test HTTP/1.0\nHost: %s\r\n\r\n",EMMA_SERVER_HOST,EMMA_SERVER_PORT,EMMA_SERVER_HOST); } else { connHost = EMMA_SERVER_HOST; connPort = EMMA_SERVER_PORT; for(int i=0; i<sizeof(s); i++) { s[i]=0; } sprintf(s,"/emma/api/controller/test"); } wait(1); t.start(); while(!esp.ready() && t.read_ms() < 5000); t.stop(); 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); return true; } 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); return true; } return false; } /*end emma private function*/