Train status

tokyoMetro.cpp

Committer:
takashikojo
Date:
2015-11-22
Revision:
6:d4d781f31f70
Parent:
5:6105553963bb

File content as of revision 6:d4d781f31f70:

#include "mbed.h"
#include "EthernetInterface.h"
#include "HTTPClient.h"
#include "vector"
#include "picojson.h"
#include <SDFileSystem.h>

#include "AlarmClock.h"
#include "matchLine.h"

#define ACCESS_TOKEN "/sd/TMetroToken.txt" 

#define API_URL      "https://api.tokyometroapp.jp:443/api/v2"

#if 0
//Enable debug
#define DBG(x, ...) std::printf("[tokyoMetro : DBG]"x"\r\n", ##__VA_ARGS__);
#define WARN(x, ...) std::printf("[tokyoMetro : WARN]"x"\r\n", ##__VA_ARGS__);
#else
//Disable debug
#define DBG(x, ...)
#define WARN(x, ...)
#endif

#define ERR(x, ...) std::printf("[tokyoMetro : ERR]"x"\r\n", ##__VA_ARGS__);

extern AlarmClock alarmclock ;
extern HTTPClient httpClient;
extern matchLine watchList ;
extern SDFileSystem sdCard ;

static picojson::value trainStat ;

static std::map<std::string, string> lineTbl ;
void TMetro_initLine(void)
{
    lineTbl["odpt.Railway:TokyoMetro.Tozai"]      = "東京メトロ東西線 " ;
    lineTbl["odpt.Railway:TokyoMetro.Marunouchi"] = "東京メトロ丸の内線" ;
    lineTbl["odpt.Railway:TokyoMetro.Namboku"]    = "東京メトロ南北線 " ;
    lineTbl["odpt.Railway:TokyoMetro.Hibiya"]     = "東京メトロ日比谷線" ;
    lineTbl["odpt.Railway:TokyoMetro.Fukutoshin"] = "東京メトロ副都心線" ;
    lineTbl["odpt.Railway:TokyoMetro.Hanzomon"]   = "東京メトロ半蔵門線" ;
    lineTbl["odpt.Railway:TokyoMetro.Ginza"]      = "東京メトロ銀座線 " ;
    lineTbl["odpt.Railway:TokyoMetro.Yurakucho"]  = "東京メトロ有楽町線" ;
    lineTbl["odpt.Railway:TokyoMetro.Chiyoda"]    = "東京メトロ千代田線" ;
}

#define TOKEN_SIZE 100
static char accessToken[TOKEN_SIZE] = { 0x0 } ;

static void removeCRLF(char *str)
{
    for(int i = strlen(str)-1; i>0 ; i--) {
        if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
            str[strlen(str)-1] = '\0' ;
        else break ;
    }
}

static const char *getToken()
{
    FILE *fp ;
    if(accessToken[0] == 0x0) {
        fp = fopen(ACCESS_TOKEN, "r");
        if (fp == NULL) {
            ERR("Cannot open \"%s\"\n", ACCESS_TOKEN) ;
            return false ;
        }
        fgets(accessToken, sizeof(accessToken), fp) ;
        removeCRLF(accessToken) ;
        fclose(fp) ;
        TMetro_initLine() ;
    }
    return accessToken ;
}

bool TMetro_query(const char *type, const char *query, char *recv, unsigned int size)
{
    int ret ;
#define BUFF_SIZE   256
    char queryBuff[BUFF_SIZE] ;
    sprintf(queryBuff, "%s/%s?rdf:type=%s&acl:consumerKey=%s", API_URL, type, query, getToken()) ;
    DBG("%s",queryBuff) ;
    ret = httpClient.get(queryBuff, recv, size);
    if (!ret) {
        DBG("Result: %s\n", recv);
        return true ;
    } else {
        ERR("Error - ret = %d - HTTP return code = %d\n", ret, httpClient.getHTTPResponseCode());
        return false ;
    }
}

static void printStat(const char *line, const char *stat)
{
#define JST (9*60*60)
    struct tm t;
    time_t ctTime;
    ctTime = time(NULL) + JST ;
    t  = *localtime(&ctTime);

    printf("%d月%d日%d時%d分:%s:%s\n",
           t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, line, stat) ;
}

bool TMetro_getStat(const char *buff)
{

    std::string err;
    picojson::parse(trainStat, (const char *)buff, (const char *)buff+strlen(buff), &err);
    if (!err.empty()) {
        ERR("Metro Site Result ERROR: %s", err.c_str());
        return false ;
    }
    picojson::array array = trainStat.get<picojson::array>();
    for (picojson::array::iterator it = array.begin(); it != array.end(); it++) {
        picojson::object& obj = it->get<picojson::object>();
        DBG("Line=%s, %s, %s\n", obj["odpt:railway"].get<std::string>().c_str(), 
                             lineTbl[obj["odpt:railway"].get<std::string>()].c_str(),
                             obj["odpt:trainInformationText"].get<std::string>()) ;
        if(watchList.find(lineTbl[obj["odpt:railway"].get<std::string>()])) {
            printStat(
                lineTbl[obj["odpt:railway"].get<std::string>()].c_str(),
                obj["odpt:trainInformationText"].get<std::string>().c_str());
            if(obj["odpt:trainInformationText"].get<std::string>().find("平常どおり") == std::string::npos)
                return true ;
        }
    }
    return false ;
}