Safety confirmation program for the elderly persons. (LPC1768)

Dependencies:   EthernetInterface HTTPClient mbed-rtos mbed

Revision:
0:928a824c31d7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Feb 13 11:36:45 2015 +0000
@@ -0,0 +1,260 @@
+/*
+* Copyright (C) 2015 KLab Inc.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include "HTTPClient.h"
+
+#define DEVELOP
+#ifdef DEVELOP
+#define dbg(...) printf(__VA_ARGS__)
+#else
+#define dbg(...)
+#endif
+
+// Parse.com に設置ずみのの対向アプリの ID と RESTAPIKEY
+#define PARSE_COM_APPID       "** YOUR PARSE APP ID **"
+#define PARSE_COM_RESTAPIKEY  "** YOUR PARSE APP REST API KEY **"
+
+#define REQUEST_HEADER_FOR_PARSE_COM \
+    "X-Parse-Application-Id: " PARSE_COM_APPID      "\r\n" \
+    "X-Parse-REST-API-Key: "   PARSE_COM_RESTAPIKEY "\r\n" \
+    "Content-Type: "           "application/json"   "\r\n"
+
+#define URL_POSTDATA  "https://api.parse.com/1/functions/detected"
+#define URL_SENDMAIL  "https://api.parse.com/1/functions/sendmail"
+
+// for LM61BIZ
+#define GAP_DIGREE_ZERO  (600.0/3300.0)
+#define DIGREE_PER_VALUE (10.0/3300.0)
+
+#define SW_ON 0
+#define LED_MAX 5
+#define HTTPS_REQUEST_INTERVAL 1800 // 30分
+
+EthernetInterface eth;
+HTTPClient http;
+LocalFileSystem local("local");
+
+#define DEVICEID_FILENAME  "/local/id.txt"
+#define DEVICEID_MAXLENGTH 16
+
+DigitalOut LEDS[LED_MAX] = {p21, LED1, LED2, LED3, LED4};
+DigitalOut buzzer(p5);     // 電子ブザー
+AnalogIn sensorTEMP(p15);  // 温度センサ
+DigitalIn sensorPIR(p20);  // 赤外線センサ
+DigitalIn switchPUSH(p24); // 外付けプッシュボタン
+Ticker timer;
+char deviceId[DEVICEID_MAXLENGTH];
+
+// すべてのLEDをON/OFF
+void LedsShow(int OnOrOff)
+{
+    for (int i = 0; i < LED_MAX; i++) {
+        LEDS[i] = OnOrOff;
+    }
+}
+
+// すべてのLEDを順次点灯
+void LedsRotate(float interval)
+{
+    LedsShow(0);
+    for (int i = 0; i < LED_MAX; i++) {
+        LEDS[i] = 1;
+        wait(interval);
+    }
+    LedsShow(0);
+}
+
+// time() 用にダミー日時をセット
+void setTime()
+{
+    struct tm t;
+    t.tm_sec  = 1;
+    t.tm_min  = 1;
+    t.tm_hour = 1;
+    t.tm_mday = 1;
+    t.tm_mon  = 1;
+    t.tm_year = 100;
+    time_t seconds = mktime(&t);
+    set_time(seconds);
+}
+
+void handlerLedsRotate()
+{
+    LedsRotate(0.1);
+}
+
+void handlerLed1Blink()
+{
+    LEDS[1] = !LEDS[1];
+}
+
+// 初期化
+int init()
+{
+    int sts;
+
+    // 押しボタン接続ポートの DigitalIn をプルアップ
+    switchPUSH.mode(PullUp);
+
+    setTime();
+    timer.attach(&handlerLedsRotate, 1);
+
+    // イーサネットの初期化
+    dbg("- start eth.init\r\n" );
+    sts = eth.init(); //Use DHCP
+    if (sts != 0) {
+        dbg("- ech.init error!\r\n" );
+        timer.detach();
+        return -1;
+    }
+
+    dbg("- start eth.connect\r\n" );
+    sts = eth.connect();
+    if (sts != 0) {
+        dbg("- eth.connect error!\r\n" );
+        timer.detach();
+        return -2;
+    }
+    dbg("- my IP Address = %s\r\n", eth.getIPAddress());
+
+    // 自デバイス名を id.txt から読み込む
+    strncpy(deviceId, eth.getIPAddress(), 15);
+    deviceId[15] = '\0';
+    FILE *fp = fopen(DEVICEID_FILENAME, "r");
+    if (!fp) {
+        // id.txt が存在しなければ新規作成し IP アドレスを書き込む
+        fp = fopen(DEVICEID_FILENAME, "w");
+        if (fp) {
+            fprintf(fp, "%s", deviceId);
+        }
+    } else {
+        fgets(deviceId, DEVICEID_MAXLENGTH, fp);
+        for (int i = 0; i < DEVICEID_MAXLENGTH; i++) {
+            if (deviceId[i] == '\r' || deviceId[i] == '\n') {
+                deviceId[i] = '\0';
+                break;
+            }
+        }
+    }
+    if (fp) {
+        fclose(fp);
+    }
+    dbg("- my DeviceId = %s\r\n", deviceId);
+
+    // センサ安定化待ち
+    wait(4.0);
+    timer.detach();
+    return 0;
+}
+
+// Parse.com への POST
+int postToParseCom(const char *ApiUrl, char *postData)
+{
+    int sts;
+    char buf[256];
+    HTTPText dataToPost(postData);
+    HTTPText resData(buf, sizeof(buf));
+    http.setHeader(REQUEST_HEADER_FOR_PARSE_COM);
+    dbg("- start HTTPS request\r\n");
+    sts = http.post(ApiUrl, dataToPost, &resData, HTTP_CLIENT_DEFAULT_TIMEOUT);
+    if (sts == HTTP_OK) {
+        dbg("- received HTTPS response\r\n");
+        dbg("- head of data [%s]\r\n", buf);
+        dbg("- done\r\n\r\n");
+    } else {
+        dbg("- HTTPS request error=%d, status=%d\r\n", sts, http.getHTTPResponseCode());
+        dbg("- head of data [%s]\r\n", buf);
+        return sts;
+    }
+    return HTTP_OK;
+}
+
+// エントリーポイント
+int main()
+{
+    time_t lastRequestTime = 0;
+    char reqData[128];
+    int sts = init();
+    if (sts != 0) {
+        // 初期化エラー時は LED 全点灯で終了
+        LedsShow(1);
+        return -1;
+    }
+    while(1) {
+        int buttonPressedMsecs = 0;
+        // 緊急ボタン押下状態
+        while (switchPUSH == SW_ON) {
+            LEDS[2] = 1;
+            // 長押し2秒でメール送信
+            if (buttonPressedMsecs >= 2000) {
+                LEDS[1] = 1;
+                buzzer = 1; // ブザーを鳴らす
+                dbg("- long-pressed\r\n");
+                // デバイス名
+                sprintf(reqData, "{\"devid\" : \"%s\"}", deviceId);
+                sts = postToParseCom(URL_SENDMAIL, reqData);
+                if (sts != HTTP_OK) {
+                    // あとで考える
+                }
+                break;
+            }
+            wait(0.2);
+            buttonPressedMsecs += 200;
+        }
+        LEDS[1] = LEDS[2] = 0;
+        buzzer = 0;
+
+        // 赤外線センサ反応状態
+        int detected = sensorPIR;
+        if (!detected) {
+            LEDS[0] = 0;
+        } else {
+            if (LEDS[0] == 0) {
+                LEDS[0] = 1;
+                dbg("- detected!\r\n");
+                // 温度センサの出力電圧値を摂氏値に
+                float valueTemp = (sensorTEMP - GAP_DIGREE_ZERO) / DIGREE_PER_VALUE;
+                dbg("- temperature = %2.1f C\r\n", valueTemp);
+
+                // 前回の送信から所定時間が経過していれば再び送信
+                int elapsed = time(NULL) - lastRequestTime;
+                if (elapsed > HTTPS_REQUEST_INTERVAL) {
+                    // 温度情報・デバイス名・ローカル IP アドレス
+                    sprintf(reqData, "{\"temp\" : \"%2.1f\", \"devid\" : \"%s\", \"ip\" : \"%s\"}",
+                            valueTemp, deviceId, eth.getIPAddress());
+                    timer.detach();
+                    LEDS[1] = 1;
+
+                    sts = postToParseCom(URL_POSTDATA, reqData);
+                    if (sts == HTTP_OK) {
+                        lastRequestTime = time(NULL);
+                        LEDS[1] = 0;
+                    } else {
+                        // エラー時は LED1 を点滅状態に
+                        timer.attach(&handlerLed1Blink, 1.0);
+                    }
+                } else {
+                    dbg("- HTTPS request is pending.. [%d/%d sec]\r\n", elapsed, HTTPS_REQUEST_INTERVAL);
+                }
+            }
+        }
+        wait(0.2);
+    }
+    eth.disconnect(); // unreachable
+}
+