branch with improvemnts
Fork of M2XStreamClient by
Embed:
(wiki syntax)
Show/hide line numbers
M2XStreamClient.h
00001 #ifndef M2XStreamClient_h 00002 #define M2XStreamClient_h 00003 00004 #define MIN(a, b) (((a) > (b))?(b):(a)) 00005 00006 #define MBED_PLATFORM 00007 00008 #ifdef ARDUINO_PLATFORM 00009 #include "Arduino.h" 00010 00011 #define USER_AGENT "User-Agent: M2X Arduino Client/0.1" 00012 #endif 00013 00014 #ifdef MBED_PLATFORM 00015 #include "mbed.h" 00016 00017 #define USER_AGENT "User-Agent: M2X Mbed Client/0.1" 00018 #endif 00019 00020 #include "Client.h" 00021 #include "NullPrint.h" 00022 00023 #ifdef DEBUG 00024 #ifdef ARDUINO_PLATFORM 00025 #define DBG(fmt_, data_) Serial.print(data_) 00026 #define DBGLN(fmt_, data_) Serial.println(data_) 00027 #define DBGLNEND Serial.println() 00028 #endif // ARDUINO_PLATFORM 00029 00030 #ifdef MBED_PLATFORM 00031 #define DBG(fmt_, data_) printf((fmt_), (data_)) 00032 #define DBGLN(fmt_, data_) printf((fmt_), (data_)); printf("\n") 00033 #define DBGLNEND printf("\n") 00034 #endif // MBED_PLATFORM 00035 #else 00036 #define DBG(fmt_, data_) 00037 #define DBGLN(fmt_, data_) 00038 #define DBGLNEND 00039 #endif // DEBUG 00040 00041 #define HEX(t_) ((char) (((t_) > 9) ? ((t_) - 10 + 'A') : ((t_) + '0'))) 00042 #define MAX_DOUBLE_DIGITS 7 00043 00044 static const int E_OK = 0; 00045 static const int E_NOCONNECTION = -1; 00046 static const int E_DISCONNECTED = -2; 00047 static const int E_NOTREACHABLE = -3; 00048 static const int E_INVALID = -4; 00049 static const int E_JSON_INVALID = -5; 00050 00051 /* 00052 * +type+ indicates the value type: 1 for string, 2 for number 00053 * NOTE that the value type here only contains a hint on how 00054 * you can use the value. Even though 2 is returned, the value 00055 * is still stored in (const char *), and atoi/atof is needed to 00056 * get the actual value 00057 */ 00058 typedef void (*stream_value_read_callback)(const char* at, 00059 const char* value, 00060 int index, 00061 void* context, 00062 int type); 00063 00064 typedef void (*location_read_callback)(const char* name, 00065 double latitude, 00066 double longitude, 00067 double elevation, 00068 const char* timestamp, 00069 int index, 00070 void* context); 00071 00072 class M2XStreamClient { 00073 public: 00074 static const char* kDefaultM2XHost; 00075 static const int kDefaultM2XPort = 80; 00076 00077 M2XStreamClient(Client* client, 00078 const char* key, 00079 int case_insensitive = 1, 00080 const char* host = kDefaultM2XHost, 00081 int port = kDefaultM2XPort); 00082 00083 // Push data stream value using PUT request, returns the HTTP status code 00084 template <class T> 00085 int put(const char* feedId, const char* streamName, T value); 00086 00087 // Post multiple values to M2X all at once. 00088 // +feedId+ - id of the feed to post values 00089 // +streamNum+ - Number of streams to post 00090 // +names+ - Array of stream names, the length of the array should 00091 // be exactly +streamNum+ 00092 // +counts+ - Array of +streamNum+ length, each item in this array 00093 // containing the number of values we want to post for each stream 00094 // +ats+ - Timestamps for each value, the length of this array should 00095 // be the some of all values in +counts+, for the first +counts[0]+ 00096 // items, the values belong to the first stream, for the following 00097 // +counts[1]+ number of items, the values belong to the second stream, 00098 // etc. Notice that timestamps are required here: you must provide 00099 // a timestamp for each value posted. 00100 // +values+ - Values to post. This works the same way as +ats+, the 00101 // first +counts[0]+ number of items contain values to post to the first 00102 // stream, the succeeding +counts[1]+ number of items contain values 00103 // for the second stream, etc. The length of this array should be 00104 // the sum of all values in +counts+ array. 00105 template <class T> 00106 int postMultiple(const char* feedId, int streamNum, 00107 const char* names[], const int counts[], 00108 const char* ats[], T values[]); 00109 00110 // Fetch values for a particular data stream. Since memory is 00111 // very limited on an Arduino, we cannot parse and get all the 00112 // data points in memory. Instead, we use callbacks here: whenever 00113 // a new data point is parsed, we call the callback using the values, 00114 // after that, the values will be thrown away to make space for new 00115 // values. 00116 // Note that you can also pass in a user-specified context in this 00117 // function, this context will be passed to the callback function 00118 // each time we get a data point. 00119 // For each data point, the callback will be called once. The HTTP 00120 // status code will be returned. And the content is only parsed when 00121 // the status code is 200. 00122 int fetchValues(const char* feedId, const char* streamName, 00123 stream_value_read_callback callback, void* context, 00124 const char* startTime = NULL, const char* endTime = NULL, 00125 const char* limit = NULL); 00126 00127 // Update datasource location 00128 // NOTE: On an Arduino Uno and other ATMEGA based boards, double has 00129 // 4-byte (32 bits) precision, which is the same as float. So there's 00130 // no natural double-precision floating number on these boards. With 00131 // a float value, we have a precision of roughly 7 digits, that means 00132 // either 5 or 6 digits after the floating point. According to wikipedia, 00133 // a difference of 0.00001 will give us ~1.1132m distance. If this 00134 // precision is good for you, you can use the double-version we provided 00135 // here. Otherwise, you may need to use the string-version and do the 00136 // actual conversion by yourselves. 00137 // However, with an Arduino Due board, double has 8-bytes (64 bits) 00138 // precision, which means you are free to use the double-version only 00139 // without any precision problems. 00140 // Returned value is the http status code. 00141 template <class T> 00142 int updateLocation(const char* feedId, const char* name, 00143 T latitude, T longitude, T elevation); 00144 00145 // Read location information for a feed. Also used callback to process 00146 // data points for memory reasons. The HTTP status code is returned, 00147 // response is only parsed when the HTTP status code is 200 00148 int readLocation(const char* feedId, location_read_callback callback, 00149 void* context); 00150 00151 // Delete values from a data stream 00152 // You will need to provide from and end date/time strings in the ISO8601 00153 // format "yyyy-mm-ddTHH:MM:SS.SSSZ" where 00154 // yyyy: the year 00155 // mm: the month 00156 // dd: the day 00157 // HH: the hour (24 hour format) 00158 // MM: the minute 00159 // SS.SSS: the seconds (to the millisecond) 00160 // NOTE: the time is given in Zulu (GMT) 00161 // M2X will delete all values within the from to end date/time range. 00162 // The status code is 204 on success and 400 on a bad request (e.g. the 00163 // timestamp is not in ISO8601 format or the from timestamp is not less than 00164 // or equal to the end timestamp. 00165 int deleteValues(const char* feedId, const char* streamName, 00166 const char* from, const char* end); 00167 private: 00168 Client* _client; 00169 const char* _key; 00170 int _case_insensitive; 00171 const char* _host; 00172 int _port; 00173 NullPrint _null_print; 00174 00175 // Writes the HTTP header part for updating a stream value 00176 void writePutHeader(const char* feedId, 00177 const char* streamName, 00178 int contentLength); 00179 // Writes the HTTP header part for deleting stream values 00180 void writeDeleteHeader(const char* feedId, 00181 const char* streamName, 00182 int contentLength); 00183 // Writes HTTP header lines including M2X API Key, host, content 00184 // type and content length(if the body exists) 00185 void writeHttpHeader(int contentLength); 00186 // Parses HTTP response header and return the content length. 00187 // Note that this function does not parse all http headers, as long 00188 // as the content length is found, this function will return 00189 int readContentLength(); 00190 // Skips all HTTP response header part. Return minus value in case 00191 // the connection is closed before we got all headers 00192 int skipHttpHeader(); 00193 // Parses and returns the HTTP status code, note this function will 00194 // return immediately once it gets the status code 00195 int readStatusCode(bool closeClient); 00196 // Waits for a certain string pattern in the HTTP header, and returns 00197 // once the pattern is found. In the pattern, you can use '*' to denote 00198 // any character 00199 int waitForString(const char* str); 00200 // Closes the connection 00201 void close(); 00202 // Parses JSON response of stream value API, and calls callback function 00203 // once we get a data point 00204 int readStreamValue(stream_value_read_callback callback, void* context); 00205 // Parses JSON response of location API, and calls callback function once 00206 // we get a data point 00207 int readLocation(location_read_callback callback, void* context); 00208 }; 00209 00210 #include "M2XStreamClient_template.h" 00211 00212 #endif /* M2XStreamClient_h */
Generated on Wed Jul 13 2022 05:32:06 by 1.7.2