Sample program for communicating with Fujitsuu IoT Platform using HTTP
Dependencies: AsciiFont GR-PEACH_video GraphicsFramework LCD_shield_config R_BSP USBHost_custom easy-connect-gr-peach mbed-http picojson BM1383GLV KX022 rohm-sensor-hal rohm-bh1745
iot_platform.cpp
00001 #include "mbed.h" 00002 #include "picojson.h" 00003 #include "select-demo.h" 00004 #include "iot_platform.h" 00005 #include <string> 00006 #include <iostream> 00007 #include <vector> 00008 #include "BM1383GLV.h" 00009 #include "KX022.h" 00010 #include "BH1745NUC.h" 00011 #include "bh1745_driver.h" 00012 #include "I2CCommon.h" 00013 #include "BM1422AGMV.h" 00014 00015 #if DEMO == DEMO_HTTP 00016 #include "easy-connect.h" 00017 #include "http_request.h" 00018 #include "NTPClient.h" 00019 #include <time.h> 00020 00021 /* Detect result */ 00022 result_hvcp2_fd_t result_hvcp2_fd[DETECT_MAX]; 00023 result_hvcp2_bd_t result_hvcp2_bd[DETECT_MAX]; 00024 uint32_t result_hvcp2_bd_cnt; 00025 uint32_t result_hvcp2_fd_cnt; 00026 00027 Timer http_resp_time; // response time 00028 uint16_t data[4]; // for color data 00029 float magne[3]; // for geomagnetism data 00030 00031 BM1383GLV sensor_BM(I2C_SDA, I2C_SCL); // Atmosphere 00032 KX022 *sensor_acc; // Accelerometer 00033 BM1422AGMV sensor_magne(I2C_SDA, I2C_SCL); // Geomagnetism 00034 00035 #define JST_OFFSET 9 00036 00037 #define ACCESS_CODE <Access CODE> 00038 #error "You need to replace <Access CODE for your resource> with yours" 00039 00040 std::string put_uri_base("<Base URI>/v1/<Tenant ID>/<Path-to-Resource>.json"); 00041 #error "You need to replace <Base URI>, <Tenant ID> and <Path-to-Resource> with yours" 00042 00043 std::string put_uri; 00044 00045 // json-object for camera 00046 picojson::object o_bd[DETECT_MAX], o_fd[DETECT_MAX], o_fr[DETECT_MAX], o_scr[DETECT_MAX]; 00047 // json-object for sensor 00048 picojson::object o_acc, o_atmo, o_col, o_temp, o_magne; 00049 00050 picojson::array data_array_acc(6); 00051 picojson::array data_array_atmo(6); 00052 picojson::array data_array_col(6); 00053 picojson::array data_array_temp(6); 00054 picojson::array data_array_magne(6); 00055 00056 // URI for GET request 00057 std::string get_uri("<Base URI>/v1/<Tenant ID>/<Path-to-Resource>/_past.json"); 00058 #error "You need to replace <Base URI>, <Tenant ID> and <Path-to-Resource> with yours" 00059 00060 void dump_response(HttpResponse* res) 00061 { 00062 DEBUG_PRINT("Status: %d - %s\n", res->get_status_code(), 00063 res->get_status_message().c_str()); 00064 00065 DEBUG_PRINT("Headers:\n"); 00066 for (size_t ix = 0; ix < res->get_headers_length(); ix++) { 00067 DEBUG_PRINT("\t%s: %s\n", res->get_headers_fields()[ix]->c_str(), 00068 res->get_headers_values()[ix]->c_str()); 00069 } 00070 DEBUG_PRINT("\nBody (%d bytes):\n\n%s\n", res->get_body_length(), 00071 res->get_body_as_string().c_str()); 00072 } 00073 00074 std::string create_put_uri(std::string uri_base) 00075 { 00076 time_t ctTime; 00077 struct tm *pnow; 00078 char date_and_hour[50]; 00079 std::string uri; 00080 00081 ctTime = time(NULL); 00082 pnow = localtime(&ctTime); 00083 sprintf(date_and_hour, "?$date=%04d%02d%02dT%02d%02d%02d.000%%2B%02d00", 00084 (pnow->tm_year + 1900), (pnow->tm_mon + 1), pnow->tm_mday, 00085 (pnow->tm_hour + JST_OFFSET - pnow->tm_isdst), pnow->tm_min, 00086 pnow->tm_sec, (JST_OFFSET - pnow->tm_isdst)); 00087 00088 uri = uri_base + date_and_hour; 00089 00090 return(uri); 00091 } 00092 00093 int iot_put(NetworkInterface *network, picojson::object o4) 00094 { 00095 00096 #ifdef ENABLED_NTP 00097 put_uri = create_put_uri(put_uri_base); 00098 #else 00099 put_uri = put_uri_base; 00100 #endif // ENABLED_NTP 00101 00102 // PUT request to IoT Platform 00103 HttpRequest* put_req = new HttpRequest(network, HTTP_PUT, put_uri.c_str()); 00104 put_req->set_header("Authorization", ACCESS_CODE); 00105 00106 picojson::value v_all(o4); 00107 00108 std::string body = v_all.serialize(); 00109 00110 HttpResponse* put_res = put_req->send(body.c_str(), body.length()); 00111 00112 if (!put_res) { 00113 DEBUG_PRINT("HttpRequest failed (error code %d)\n", put_req->get_error()); 00114 return 1; 00115 } 00116 00117 delete put_req; 00118 return 0; 00119 } 00120 00121 int iot_get(NetworkInterface *network) 00122 { 00123 // Do GET request to IoT Platform 00124 // By default the body is automatically parsed and stored in a buffer, this is memory heavy. 00125 // To receive chunked response, pass in a callback as last parameter to the constructor. 00126 HttpRequest* get_req = new HttpRequest(network, HTTP_GET, get_uri.c_str()); 00127 get_req->set_header("Authorization", ACCESS_CODE); 00128 00129 HttpResponse* get_res = get_req->send(); 00130 00131 if (!get_res) { 00132 DEBUG_PRINT("HttpRequest failed (error code %d)\n", get_req->get_error()); 00133 return 1; 00134 } 00135 00136 DEBUG_PRINT("\n----- HTTP GET response -----\n"); 00137 00138 delete get_req; 00139 00140 return 0; 00141 } 00142 #endif // DEMO == DEMO_HTTP 00143 00144 void read_color(void) 00145 { 00146 bool error; 00147 I2CCommonBegin(); 00148 bh1745_wait_until_found(); 00149 bh1745_initial_setup(); 00150 error = bh1745_read_data(&data[0]); 00151 MBED_ASSERT(error==0); 00152 } 00153 00154 void get_geomagnetism_value(void) 00155 { 00156 sensor_magne.get_val(magne); 00157 } 00158 00159 int send_sensor_info(NetworkInterface *network) 00160 { 00161 00162 /* Type */ 00163 o_acc["RecordType"] = picojson::value((string)"Accelerometer"); 00164 o_atmo["RecordType"] = picojson::value((string)"Atmosphere"); 00165 o_col["RecordType"] = picojson::value((string)"Color"); 00166 o_temp["RecordType"] = picojson::value((string)"Temperature"); 00167 o_magne["RecordType"] = picojson::value((string)"Geomagnetism"); 00168 00169 /* ID */ 00170 o_acc["id"] = picojson::value((string)"0001-0001"); 00171 o_atmo["id"] = picojson::value((string)"0001-0002"); 00172 o_col["id"] = picojson::value((string)"0001-0003"); 00173 o_temp["id"] = picojson::value((string)"0001-0004"); 00174 o_magne["id"] = picojson::value((string)"0001-0005"); 00175 00176 /* Accelerometer data array */ 00177 data_array_acc[0] = picojson::value((double)sensor_acc->getAccX()); 00178 data_array_acc[1] = picojson::value((double)sensor_acc->getAccY()); 00179 data_array_acc[2] = picojson::value((double)sensor_acc->getAccZ()); 00180 00181 /* Atmosphere data array */ 00182 data_array_atmo[0] = picojson::value((double)sensor_BM.getPressure()); 00183 00184 /* Color data array */ 00185 read_color(); 00186 for(int i = 0; i < 4; i++) { 00187 data_array_col[i] = picojson::value(picojson::value((double)data[i])); 00188 } 00189 00190 /* Temperature data array */ 00191 data_array_temp[0] = picojson::value((double)sensor_BM.getTemperature()); 00192 00193 /* Geomagnetism data array */ 00194 get_geomagnetism_value(); 00195 for(int i = 0; i < 3; i++) { 00196 data_array_magne[i] = picojson::value(picojson::value((double)magne[i])); 00197 } 00198 00199 /* Combine data array with object. */ 00200 o_acc["data"] = picojson::value(data_array_acc); 00201 o_atmo["data"] = picojson::value(data_array_atmo); 00202 o_col["data"] = picojson::value(data_array_col); 00203 o_temp["data"] = picojson::value(data_array_temp); 00204 o_magne["data"] = picojson::value(data_array_magne); 00205 00206 http_resp_time.reset(); 00207 http_resp_time.start(); 00208 00209 /* send data */ 00210 iot_put(network, o_acc); 00211 iot_put(network, o_atmo); 00212 iot_put(network, o_col); 00213 iot_put(network, o_temp); 00214 iot_put(network, o_magne); 00215 00216 00217 DEBUG_PRINT("iot_put() Response time:%dms\n", http_resp_time.read_ms()); 00218 00219 return 0; 00220 } 00221 00222 int send_hvc_info(NetworkInterface *network) 00223 { 00224 /* No face detect */ 00225 if (result_hvcp2_fd_cnt == 0) { 00226 /* Do nothing */ 00227 } else { 00228 for (uint32_t i = 0; i < result_hvcp2_fd_cnt; i++) { 00229 /* picojson-object clear */ 00230 o_fd[i].clear(); 00231 o_fr[i].clear(); 00232 o_scr[i].clear(); 00233 /* Type */ 00234 o_fd[i]["RecordType"] = picojson::value((string)"HVC-P2(face)"); 00235 o_fd[i]["id"] = picojson::value((string) "0001-0006"); 00236 /* Age */ 00237 o_fd[i]["Age"] = picojson::value((double)result_hvcp2_fd[i].age.age); 00238 /* Gender */ 00239 o_fd[i]["Gender"] = picojson::value((double)result_hvcp2_fd[i].gender.gender); 00240 /* FaceRectangle */ 00241 o_fr[i]["Top"] = picojson::value((double)result_hvcp2_fd[i].face_rectangle.MinY); 00242 o_fr[i]["Left"] = picojson::value((double)result_hvcp2_fd[i].face_rectangle.MinX); 00243 o_fr[i]["Width"] = picojson::value((double)result_hvcp2_fd[i].face_rectangle.Width); 00244 o_fr[i]["Height"] = picojson::value((double)result_hvcp2_fd[i].face_rectangle.Height); 00245 /* Scores */ 00246 o_scr[i]["Neutral"] = picojson::value((double)result_hvcp2_fd[i].scores.score_neutral); 00247 o_scr[i]["Anger"] = picojson::value((double)result_hvcp2_fd[i].scores.score_anger); 00248 o_scr[i]["Happiness"] = picojson::value((double)result_hvcp2_fd[i].scores.score_happiness); 00249 o_scr[i]["Surprise"] = picojson::value((double)result_hvcp2_fd[i].scores.score_surprise); 00250 o_scr[i]["Sadness"] = picojson::value((double)result_hvcp2_fd[i].scores.score_sadness); 00251 /* insert 2 structures */ 00252 o_fd[i]["FaceRectangle"] = picojson::value(o_fr[i]); 00253 o_fd[i]["Scores"] = picojson::value(o_scr[i]); 00254 } 00255 } 00256 00257 /* No body detect */ 00258 if (result_hvcp2_bd_cnt == 0) { 00259 /* Do nothing */ 00260 } else { 00261 for (uint32_t i = 0; i < result_hvcp2_bd_cnt; i++) { 00262 /* picojson-object clear */ 00263 o_bd[i].clear(); 00264 /* Type */ 00265 o_bd[i]["RecordType"] = picojson::value((string)"HVC-P2(body)"); 00266 o_bd[i]["id"] = picojson::value((string)"0001-0007"); 00267 /* BodyRectangle */ 00268 o_bd[i]["Top"] = picojson::value((double)result_hvcp2_bd[i].body_rectangle.MinY); 00269 o_bd[i]["Left"] = picojson::value((double)result_hvcp2_bd[i].body_rectangle.MinX); 00270 o_bd[i]["Width"] = picojson::value((double)result_hvcp2_bd[i].body_rectangle.Width); 00271 o_bd[i]["Height"] = picojson::value((double)result_hvcp2_bd[i].body_rectangle.Height); 00272 } 00273 } 00274 00275 DEBUG_PRINT("Face detect count : %d\n", result_hvcp2_fd_cnt); 00276 DEBUG_PRINT("Body detect count : %d\n", result_hvcp2_bd_cnt); 00277 00278 http_resp_time.reset(); 00279 http_resp_time.start(); 00280 00281 /* send data */ 00282 if (result_hvcp2_fd_cnt == 0) { 00283 /* No need to send data */ 00284 } else { 00285 for (uint32_t i = 0; i < result_hvcp2_fd_cnt; i++) { 00286 iot_put(network, o_fd[i]); 00287 } 00288 } 00289 if (result_hvcp2_bd_cnt == 0) { 00290 /* No need to send data */ 00291 } else { 00292 for (uint32_t i = 0; i < result_hvcp2_bd_cnt; i++) { 00293 iot_put(network, o_bd[i]); 00294 } 00295 } 00296 DEBUG_PRINT("iot_put() Response time:%dms\n", http_resp_time.read_ms()); 00297 return 0; 00298 } 00299 00300 void iot_ready_task(void) 00301 { 00302 KX022 acc(I2C_SDA, I2C_SCL); 00303 sensor_acc = &acc; 00304 00305 /* Initialize http */ 00306 NetworkInterface *network = easy_connect(true); 00307 MBED_ASSERT(network); 00308 00309 #ifdef ENABLED_NTP 00310 // Generate the string indicating the date and hour specified for PUT request 00311 NTPClient ntp; 00312 time_t ctTime; 00313 struct tm *pnow; 00314 NTPResult ret; 00315 00316 ret = ntp.setTime("ntp.nict.jp"); 00317 MBED_ASSERT( ret==0 ); 00318 00319 ctTime = time(NULL); 00320 #endif // Enabled_NTP 00321 00322 while (1) { 00323 00324 semaphore_wait_ret = iot_ready_semaphore.wait(); 00325 MBED_ASSERT(semaphore_wait_ret != -1); 00326 00327 #ifdef USE_HVC_P2 00328 /* send hvc-p2 data */ 00329 http_resp_time.reset(); 00330 http_resp_time.start(); 00331 send_hvc_info(network); 00332 DEBUG_PRINT("send_hvc_info() Response time:%dms\n", 00333 http_resp_time.read_ms()); 00334 #endif // USE_HVC_P2 00335 00336 #ifdef USE_SENSOR_SHIELD 00337 /* send sensor data */ 00338 http_resp_time.reset(); 00339 http_resp_time.start(); 00340 send_sensor_info(network); 00341 DEBUG_PRINT("send_sensor_info() Response time:%dms\n", 00342 http_resp_time.read_ms()); 00343 #endif // USE_SENSOR_SHIELD 00344 iot_ready_semaphore.release(); 00345 00346 Thread::wait(WAIT_TIME); 00347 }; 00348 }
Generated on Wed Jul 13 2022 06:45:29 by 1.7.2