GroveStreams is a helper class to assist with pushing data into the GroveStreams.com IoT platform.

Dependents:   GroveStreams-Temp

Committer:
mmills
Date:
Thu Jan 05 18:39:43 2017 +0000
Revision:
0:8b675b2726b7
Initial Revision.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mmills 0:8b675b2726b7 1 /*
mmills 0:8b675b2726b7 2 GroveStreams is a helper class to assist with pushing data into the
mmills 0:8b675b2726b7 3 GroveStreams.com IoT platform.
mmills 0:8b675b2726b7 4
mmills 0:8b675b2726b7 5 License:
mmills 0:8b675b2726b7 6 Copyright (C) 2017 GroveStreams LLC.
mmills 0:8b675b2726b7 7 Licensed under the Apache License, Version 2.0 (the "License");
mmills 0:8b675b2726b7 8 you may not use this file except in compliance with the License.
mmills 0:8b675b2726b7 9 You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
mmills 0:8b675b2726b7 10
mmills 0:8b675b2726b7 11 Unless required by applicable law or agreed to in writing, software
mmills 0:8b675b2726b7 12 distributed under the License is distributed on an "AS IS" BASIS,
mmills 0:8b675b2726b7 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mmills 0:8b675b2726b7 14 See the License for the specific language governing permissions and
mmills 0:8b675b2726b7 15 limitations under the License.
mmills 0:8b675b2726b7 16 */
mmills 0:8b675b2726b7 17
mmills 0:8b675b2726b7 18 #include "GroveStreams.h"
mmills 0:8b675b2726b7 19
mmills 0:8b675b2726b7 20 GroveStreams::GroveStreams(const char* apiKey, LcdDiscoF746NgTracer* pLcd)
mmills 0:8b675b2726b7 21 {
mmills 0:8b675b2726b7 22 init(apiKey, pLcd);
mmills 0:8b675b2726b7 23 }
mmills 0:8b675b2726b7 24
mmills 0:8b675b2726b7 25 GroveStreams::GroveStreams(const char* apiKey)
mmills 0:8b675b2726b7 26 {
mmills 0:8b675b2726b7 27 init(apiKey, NULL);
mmills 0:8b675b2726b7 28 }
mmills 0:8b675b2726b7 29
mmills 0:8b675b2726b7 30 GroveStreams::~GroveStreams() {
mmills 0:8b675b2726b7 31 _eth.disconnect();
mmills 0:8b675b2726b7 32 }
mmills 0:8b675b2726b7 33
mmills 0:8b675b2726b7 34 int GroveStreams::init(const char* apiKey, LcdDiscoF746NgTracer* pLcd)
mmills 0:8b675b2726b7 35 {
mmills 0:8b675b2726b7 36 _domain = "grovestreams.com";
mmills 0:8b675b2726b7 37 _port = 80;
mmills 0:8b675b2726b7 38 _apiKey = apiKey;
mmills 0:8b675b2726b7 39 _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.
mmills 0:8b675b2726b7 40 _pLcd = pLcd;
mmills 0:8b675b2726b7 41
mmills 0:8b675b2726b7 42 return startEthernet();
mmills 0:8b675b2726b7 43 }
mmills 0:8b675b2726b7 44
mmills 0:8b675b2726b7 45 void GroveStreams::printf(const char* format, ...)
mmills 0:8b675b2726b7 46 {
mmills 0:8b675b2726b7 47
mmills 0:8b675b2726b7 48 va_list args;
mmills 0:8b675b2726b7 49 va_start(args, format);
mmills 0:8b675b2726b7 50
mmills 0:8b675b2726b7 51 if (_pLcd != NULL) {
mmills 0:8b675b2726b7 52 char sbuffer[512];
mmills 0:8b675b2726b7 53 vsprintf(sbuffer, format, args);
mmills 0:8b675b2726b7 54 _pLcd->println(sbuffer);
mmills 0:8b675b2726b7 55 } else {
mmills 0:8b675b2726b7 56 vprintf(format, args);
mmills 0:8b675b2726b7 57 }
mmills 0:8b675b2726b7 58
mmills 0:8b675b2726b7 59 va_end(args);
mmills 0:8b675b2726b7 60 }
mmills 0:8b675b2726b7 61
mmills 0:8b675b2726b7 62 unsigned long GroveStreams::send(const char* componentId, const char* samples)
mmills 0:8b675b2726b7 63 {
mmills 0:8b675b2726b7 64 char resultBuffer[256]= {0};
mmills 0:8b675b2726b7 65 return send(componentId, samples, NULL, NULL, resultBuffer, sizeof resultBuffer);
mmills 0:8b675b2726b7 66 }
mmills 0:8b675b2726b7 67
mmills 0:8b675b2726b7 68 unsigned long GroveStreams::send(const char* componentId, const char* samples, char* resultBuffer, size_t resultBufferSize)
mmills 0:8b675b2726b7 69 {
mmills 0:8b675b2726b7 70 return send(componentId, samples, NULL, NULL, resultBuffer, resultBufferSize);
mmills 0:8b675b2726b7 71 }
mmills 0:8b675b2726b7 72
mmills 0:8b675b2726b7 73 unsigned long GroveStreams::send(const char* componentId, const char* samples, const char* componentName,
mmills 0:8b675b2726b7 74 const char* compTmplId, char* resultBuffer, size_t resultBufferSize)
mmills 0:8b675b2726b7 75 {
mmills 0:8b675b2726b7 76 int failedCounter = 0;
mmills 0:8b675b2726b7 77 int result = 1;
mmills 0:8b675b2726b7 78
mmills 0:8b675b2726b7 79 while (failedCounter < 3 && result != 0) {
mmills 0:8b675b2726b7 80
mmills 0:8b675b2726b7 81 result = sendNoRetry(componentId, samples, componentName, compTmplId, resultBuffer, resultBufferSize);
mmills 0:8b675b2726b7 82
mmills 0:8b675b2726b7 83 this->printf("send result code: %d", result);
mmills 0:8b675b2726b7 84
mmills 0:8b675b2726b7 85 if (result != 0) {
mmills 0:8b675b2726b7 86 //Wait and try again
mmills 0:8b675b2726b7 87 failedCounter++;
mmills 0:8b675b2726b7 88 this->printf("send failed %d times", failedCounter);
mmills 0:8b675b2726b7 89 wait(2);
mmills 0:8b675b2726b7 90 }
mmills 0:8b675b2726b7 91
mmills 0:8b675b2726b7 92 if (failedCounter > 3 ) {
mmills 0:8b675b2726b7 93 this->printf("Too many failures. Restarting Ethernet.");
mmills 0:8b675b2726b7 94 startEthernet();
mmills 0:8b675b2726b7 95 }
mmills 0:8b675b2726b7 96 }
mmills 0:8b675b2726b7 97
mmills 0:8b675b2726b7 98 return result;
mmills 0:8b675b2726b7 99 }
mmills 0:8b675b2726b7 100
mmills 0:8b675b2726b7 101 unsigned long GroveStreams::sendNoRetry(const char* componentId, const char* samples, const char* componentName,
mmills 0:8b675b2726b7 102 const char* compTmplId, char* resultBuffer, size_t resultBufferSize)
mmills 0:8b675b2726b7 103 {
mmills 0:8b675b2726b7 104 //Assemble the url that is used to pass the temperature readings to GroveStreams and call it
mmills 0:8b675b2726b7 105
mmills 0:8b675b2726b7 106 network::tcp::Socket socket;
mmills 0:8b675b2726b7 107
mmills 0:8b675b2726b7 108 int openResult = socket.open();
mmills 0:8b675b2726b7 109 if (openResult == 0) {
mmills 0:8b675b2726b7 110
mmills 0:8b675b2726b7 111 int connResult = socket.connect(_domain, _port);
mmills 0:8b675b2726b7 112 if(connResult == 0) {
mmills 0:8b675b2726b7 113
mmills 0:8b675b2726b7 114 char compNamePart[100] = {0};
mmills 0:8b675b2726b7 115 if (strlen(componentName) > 0) {
mmills 0:8b675b2726b7 116 sprintf(compNamePart, "&compName=%s",componentName);
mmills 0:8b675b2726b7 117 }
mmills 0:8b675b2726b7 118
mmills 0:8b675b2726b7 119 char compTmplIdPart[100] = {0};
mmills 0:8b675b2726b7 120 if (strlen(compTmplId) > 0) {
mmills 0:8b675b2726b7 121 sprintf(compTmplIdPart, "&compTmplId=%s",compTmplId);
mmills 0:8b675b2726b7 122 }
mmills 0:8b675b2726b7 123
mmills 0:8b675b2726b7 124 //You may need to increase the size of sbuffer if any other char array sizes have increased
mmills 0:8b675b2726b7 125 char sbuffer[512]= {0};
mmills 0:8b675b2726b7 126
mmills 0:8b675b2726b7 127 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",
mmills 0:8b675b2726b7 128 componentId, compTmplIdPart, compNamePart, _apiKey, samples, _myIPAddress);
mmills 0:8b675b2726b7 129
mmills 0:8b675b2726b7 130 this->printf("send sbuffer size: %d", strlen(sbuffer));
mmills 0:8b675b2726b7 131
mmills 0:8b675b2726b7 132 int scount = socket.write(sbuffer, strlen(sbuffer));
mmills 0:8b675b2726b7 133 this->printf("sent %d bytes: [%.*s]", scount, strstr(sbuffer, "\r\n")-sbuffer, sbuffer);
mmills 0:8b675b2726b7 134
mmills 0:8b675b2726b7 135 //Read status line
mmills 0:8b675b2726b7 136
mmills 0:8b675b2726b7 137 int rcount = socket.read(resultBuffer, resultBufferSize);
mmills 0:8b675b2726b7 138
mmills 0:8b675b2726b7 139 this->printf("HTTP Response size: %d bytes", rcount);
mmills 0:8b675b2726b7 140 this->printf("HTTP Response Status:[%.*s]", strstr(resultBuffer, "\r\n")-resultBuffer, resultBuffer);
mmills 0:8b675b2726b7 141
mmills 0:8b675b2726b7 142 //Only return the body
mmills 0:8b675b2726b7 143 strcpy(resultBuffer, strstr(resultBuffer, "\r\n\r\n") + strlen("\r\n\r\n"));
mmills 0:8b675b2726b7 144 strcat(resultBuffer, "\0");
mmills 0:8b675b2726b7 145 this->printf("HTTP Body: [%s]", resultBuffer);
mmills 0:8b675b2726b7 146
mmills 0:8b675b2726b7 147 socket.close();
mmills 0:8b675b2726b7 148 } else {
mmills 0:8b675b2726b7 149
mmills 0:8b675b2726b7 150 this->printf("Socket Connect Failed: %d", connResult);
mmills 0:8b675b2726b7 151 }
mmills 0:8b675b2726b7 152
mmills 0:8b675b2726b7 153 } else {
mmills 0:8b675b2726b7 154 this->printf("Socket Open Failed: %d", openResult);
mmills 0:8b675b2726b7 155 socket.close();
mmills 0:8b675b2726b7 156 return 1;
mmills 0:8b675b2726b7 157 }
mmills 0:8b675b2726b7 158
mmills 0:8b675b2726b7 159 return 0;
mmills 0:8b675b2726b7 160 }
mmills 0:8b675b2726b7 161
mmills 0:8b675b2726b7 162
mmills 0:8b675b2726b7 163 int GroveStreams::startEthernet()
mmills 0:8b675b2726b7 164 {
mmills 0:8b675b2726b7 165 //Start or restart the Ethernet connection.
mmills 0:8b675b2726b7 166 int result = _eth.disconnect();
mmills 0:8b675b2726b7 167 if (result != 0) {
mmills 0:8b675b2726b7 168 this->printf("Ethernet diconnect Failed: %d", result);
mmills 0:8b675b2726b7 169 return result;
mmills 0:8b675b2726b7 170 }
mmills 0:8b675b2726b7 171
mmills 0:8b675b2726b7 172 this->printf("Connecting STM32 to network...");
mmills 0:8b675b2726b7 173
mmills 0:8b675b2726b7 174 //Connect to the network and obtain an IP address using DHCP
mmills 0:8b675b2726b7 175 result = _eth.init();
mmills 0:8b675b2726b7 176 if (result != 0) {
mmills 0:8b675b2726b7 177 this->printf("Ethernet init Failed: %d", result);
mmills 0:8b675b2726b7 178 return result;
mmills 0:8b675b2726b7 179 }
mmills 0:8b675b2726b7 180
mmills 0:8b675b2726b7 181 result = _eth.connect();
mmills 0:8b675b2726b7 182 if (result != 0) {
mmills 0:8b675b2726b7 183 this->printf("Ethernet connect Failed: %d", result);
mmills 0:8b675b2726b7 184 return result;
mmills 0:8b675b2726b7 185 } else {
mmills 0:8b675b2726b7 186 this->printf("STM32 connected to network");
mmills 0:8b675b2726b7 187
mmills 0:8b675b2726b7 188 //Set the mac and ip variables so that they can be used during sensor uploads later
mmills 0:8b675b2726b7 189 _myIPAddress = _eth.getIPAddress();
mmills 0:8b675b2726b7 190
mmills 0:8b675b2726b7 191 this->printf("IP address: %s", _myIPAddress ? _myIPAddress : "No IP");
mmills 0:8b675b2726b7 192 }
mmills 0:8b675b2726b7 193
mmills 0:8b675b2726b7 194 return 0;
mmills 0:8b675b2726b7 195 }
mmills 0:8b675b2726b7 196
mmills 0:8b675b2726b7 197 const char* GroveStreams::getMACAddress()
mmills 0:8b675b2726b7 198 {
mmills 0:8b675b2726b7 199 return _eth.getMACAddress();
mmills 0:8b675b2726b7 200 }