GroveStreams is a helper class to assist with pushing data into the GroveStreams.com IoT platform.
Embed:
(wiki syntax)
Show/hide line numbers
GroveStreams.cpp
00001 /* 00002 GroveStreams is a helper class to assist with pushing data into the 00003 GroveStreams.com IoT platform. 00004 00005 License: 00006 Copyright (C) 2017 GroveStreams LLC. 00007 Licensed under the Apache License, Version 2.0 (the "License"); 00008 you may not use this file except in compliance with the License. 00009 You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0 00010 00011 Unless required by applicable law or agreed to in writing, software 00012 distributed under the License is distributed on an "AS IS" BASIS, 00013 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 See the License for the specific language governing permissions and 00015 limitations under the License. 00016 */ 00017 00018 #include "GroveStreams.h" 00019 00020 GroveStreams::GroveStreams(const char* apiKey, LcdDiscoF746NgTracer* pLcd) 00021 { 00022 init(apiKey, pLcd); 00023 } 00024 00025 GroveStreams::GroveStreams(const char* apiKey) 00026 { 00027 init(apiKey, NULL); 00028 } 00029 00030 GroveStreams::~GroveStreams() { 00031 _eth.disconnect(); 00032 } 00033 00034 int GroveStreams::init(const char* apiKey, LcdDiscoF746NgTracer* pLcd) 00035 { 00036 _domain = "grovestreams.com"; 00037 _port = 80; 00038 _apiKey = apiKey; 00039 _myIPAddress = NULL; //Don't Change. Set below from DHCP. Needed by GroveStreams to verify that a device is not uploading more than once every 10s. 00040 _pLcd = pLcd; 00041 00042 return startEthernet(); 00043 } 00044 00045 void GroveStreams::printf(const char* format, ...) 00046 { 00047 00048 va_list args; 00049 va_start(args, format); 00050 00051 if (_pLcd != NULL) { 00052 char sbuffer[512]; 00053 vsprintf(sbuffer, format, args); 00054 _pLcd->println(sbuffer); 00055 } else { 00056 vprintf(format, args); 00057 } 00058 00059 va_end(args); 00060 } 00061 00062 unsigned long GroveStreams::send(const char* componentId, const char* samples) 00063 { 00064 char resultBuffer[256]= {0}; 00065 return send(componentId, samples, NULL, NULL, resultBuffer, sizeof resultBuffer); 00066 } 00067 00068 unsigned long GroveStreams::send(const char* componentId, const char* samples, char* resultBuffer, size_t resultBufferSize) 00069 { 00070 return send(componentId, samples, NULL, NULL, resultBuffer, resultBufferSize); 00071 } 00072 00073 unsigned long GroveStreams::send(const char* componentId, const char* samples, const char* componentName, 00074 const char* compTmplId, char* resultBuffer, size_t resultBufferSize) 00075 { 00076 int failedCounter = 0; 00077 int result = 1; 00078 00079 while (failedCounter < 3 && result != 0) { 00080 00081 result = sendNoRetry(componentId, samples, componentName, compTmplId, resultBuffer, resultBufferSize); 00082 00083 this->printf("send result code: %d", result); 00084 00085 if (result != 0) { 00086 //Wait and try again 00087 failedCounter++; 00088 this->printf("send failed %d times", failedCounter); 00089 wait(2); 00090 } 00091 00092 if (failedCounter > 3 ) { 00093 this->printf("Too many failures. Restarting Ethernet."); 00094 startEthernet(); 00095 } 00096 } 00097 00098 return result; 00099 } 00100 00101 unsigned long GroveStreams::sendNoRetry(const char* componentId, const char* samples, const char* componentName, 00102 const char* compTmplId, char* resultBuffer, size_t resultBufferSize) 00103 { 00104 //Assemble the url that is used to pass the temperature readings to GroveStreams and call it 00105 00106 network::tcp::Socket socket; 00107 00108 int openResult = socket.open(); 00109 if (openResult == 0) { 00110 00111 int connResult = socket.connect(_domain, _port); 00112 if(connResult == 0) { 00113 00114 char compNamePart[100] = {0}; 00115 if (strlen(componentName) > 0) { 00116 sprintf(compNamePart, "&compName=%s",componentName); 00117 } 00118 00119 char compTmplIdPart[100] = {0}; 00120 if (strlen(compTmplId) > 0) { 00121 sprintf(compTmplIdPart, "&compTmplId=%s",compTmplId); 00122 } 00123 00124 //You may need to increase the size of sbuffer if any other char array sizes have increased 00125 char sbuffer[512]= {0}; 00126 00127 sprintf(sbuffer, "PUT /api/feed?compId=%s%s%s&api_key=%s%s HTTP/1.1\r\nHost: \r\nConnection: close\r\nX-Forwarded-For:%s\r\n\r\n", 00128 componentId, compTmplIdPart, compNamePart, _apiKey, samples, _myIPAddress); 00129 00130 this->printf("send sbuffer size: %d", strlen(sbuffer)); 00131 00132 int scount = socket.write(sbuffer, strlen(sbuffer)); 00133 this->printf("sent %d bytes: [%.*s]", scount, strstr(sbuffer, "\r\n")-sbuffer, sbuffer); 00134 00135 //Read status line 00136 00137 int rcount = socket.read(resultBuffer, resultBufferSize); 00138 00139 this->printf("HTTP Response size: %d bytes", rcount); 00140 this->printf("HTTP Response Status:[%.*s]", strstr(resultBuffer, "\r\n")-resultBuffer, resultBuffer); 00141 00142 //Only return the body 00143 strcpy(resultBuffer, strstr(resultBuffer, "\r\n\r\n") + strlen("\r\n\r\n")); 00144 strcat(resultBuffer, "\0"); 00145 this->printf("HTTP Body: [%s]", resultBuffer); 00146 00147 socket.close(); 00148 } else { 00149 00150 this->printf("Socket Connect Failed: %d", connResult); 00151 } 00152 00153 } else { 00154 this->printf("Socket Open Failed: %d", openResult); 00155 socket.close(); 00156 return 1; 00157 } 00158 00159 return 0; 00160 } 00161 00162 00163 int GroveStreams::startEthernet() 00164 { 00165 //Start or restart the Ethernet connection. 00166 int result = _eth.disconnect(); 00167 if (result != 0) { 00168 this->printf("Ethernet diconnect Failed: %d", result); 00169 return result; 00170 } 00171 00172 this->printf("Connecting STM32 to network..."); 00173 00174 //Connect to the network and obtain an IP address using DHCP 00175 result = _eth.init(); 00176 if (result != 0) { 00177 this->printf("Ethernet init Failed: %d", result); 00178 return result; 00179 } 00180 00181 result = _eth.connect(); 00182 if (result != 0) { 00183 this->printf("Ethernet connect Failed: %d", result); 00184 return result; 00185 } else { 00186 this->printf("STM32 connected to network"); 00187 00188 //Set the mac and ip variables so that they can be used during sensor uploads later 00189 _myIPAddress = _eth.getIPAddress(); 00190 00191 this->printf("IP address: %s", _myIPAddress ? _myIPAddress : "No IP"); 00192 } 00193 00194 return 0; 00195 } 00196 00197 const char* GroveStreams::getMACAddress() 00198 { 00199 return _eth.getMACAddress(); 00200 }
Generated on Thu Jul 14 2022 03:13:34 by 1.7.2