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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers iot_platform.cpp Source File

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 }