20160126_jeffrey - silenceuncrio/diary GitHub Wiki
- 0920 - 寫 engineering notebook
- 1045 - 支援 Smart Plug 的事情優先考慮
- 1115 - get_common.c
- 1335 - 修正 iot_init.sql
- 1635 - 進度快照
- 1550 - 在 database 新增一個 WhiteBoxes
寫 engineering notebook
mantis 上的 database 就夠了
交 Engineering Notebook 時
Pioneer 告知說要調一下 Schedule 將支援 Smart Plug 的事情優先考慮
藍芽模組對 Control Center 來說要透過 UART 溝通
如果是 JS9331 的話
TTL/RS232 串口應該可以拿來用
Linkit 那一片看來也沒啥問題
Pin out 圖看來有兩組 UART
繼續上禮拜的 get_common.c
修正上禮拜的 iot_init.sql
from ThingType INTEGER NOT NULL,
to ThingType TEXT NOT NULL,
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS Boxes (
BoxId INTEGER PRIMARY KEY NOT NULL,
BoxName TEXT NOT NULL,
BoxLocation TEXT NOT NULL,
BoxConfig_ TEXT NOT NULL
);
CREATE TABLE Things (
ThingId INTEGER PRIMARY KEY,
ThingType TEXT NOT NULL,
ThingStatus_ TEXT NOT NULL,
BoxId INTEGER NOT NULL REFERENCES Boxes( BoxId )
);
CREATE TABLE OpenDetectors (
OpenId INTEGER PRIMARY KEY,
OpenConfig_ TEXT NOT NULL,
OpenStatus_ TEXT NOT NULL,
ThingId INTEGER NOT NULL REFERENCES Things( ThingId )
);
CREATE TABLE LightDetectors (
LightId INTEGER PRIMARY KEY,
LightConfig_ TEXT NOT NULL,
LightStatus_ TEXT NOT NULL,
ThingId INTEGER NOT NULL REFERENCES Things( ThingId )
);
COMMIT;
今天的進度快照
Makefile
CROSS_COMPILE = mips-openwrt-linux-uclibc-
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
CC_I = -I/home/jeffrey/openwrt/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/include/
CC_I += -I/home/jeffrey/openwrt/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/include/
CC_L = -L/home/jeffrey/openwrt/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/
CC_L += -L/home/jeffrey/openwrt/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/lib
LIBS = -lm -ldl -lpthread -lfcgi -ljson-c -lpolarssl -lcurl -lsqlite3
get_common_1: get_common_1.o database.o
$(CC) $(CC_I) $(CC_L) $(LIBS) -o $@ get_common_1.o database.o
%.o: %.c
@echo Compile $< ...
$(CC) $(CC_I) $(CC_L) $(LIBS) -c -o $@ $<
get_common_1.c
/* standard includes */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
/* json-c (https://github.com/json-c/json-c) */
#include <json-c/json.h>
/* libcurl (http://curl.haxx.se/libcurl/c) */
#include <curl/curl.h>
#include <sys/time.h>
#include "database.h"
/* holder for curl fetch */
struct curl_fetch_st {
char *payload;
size_t size;
};
/* callback for curl fetch */
size_t curl_callback (void *contents, size_t size, size_t nmemb, void *userp) {
size_t realsize = size * nmemb; /* calculate buffer size */
struct curl_fetch_st *p = (struct curl_fetch_st *) userp; /* cast pointer to fetch struct */
/* expand buffer */
p->payload = (char *) realloc(p->payload, p->size + realsize + 1);
/* check buffer */
if (p->payload == NULL) {
/* this isn't good */
fprintf(stderr, "ERROR: Failed to expand buffer in curl_callback");
/* free buffer */
free(p->payload);
/* return */
return -1;
}
/* copy contents to buffer */
memcpy(&(p->payload[p->size]), contents, realsize);
/* set new buffer size */
p->size += realsize;
/* ensure null termination */
p->payload[p->size] = 0;
/* return size */
return realsize;
}
/* fetch and return url body via curl */
CURLcode curl_fetch_url(CURL *ch, const char *url, struct curl_fetch_st *fetch) {
CURLcode rcode; /* curl result code */
/* init payload */
fetch->payload = (char *) calloc(1, sizeof(fetch->payload));
/* check payload */
if (fetch->payload == NULL) {
/* log error */
fprintf(stderr, "ERROR: Failed to allocate payload in curl_fetch_url");
/* return error */
return CURLE_FAILED_INIT;
}
/* init size */
fetch->size = 0;
/* set url to fetch */
curl_easy_setopt(ch, CURLOPT_URL, url);
/* set calback function */
curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, curl_callback);
/* pass fetch struct pointer */
curl_easy_setopt(ch, CURLOPT_WRITEDATA, (void *) fetch);
/* set default user agent */
curl_easy_setopt(ch, CURLOPT_USERAGENT, "libcurl-agent/1.0");
/* set timeout */
curl_easy_setopt(ch, CURLOPT_TIMEOUT, 5);
/* enable location redirects */
curl_easy_setopt(ch, CURLOPT_FOLLOWLOCATION, 1);
/* set maximum allowed redirects */
curl_easy_setopt(ch, CURLOPT_MAXREDIRS, 1);
/* fetch the url */
rcode = curl_easy_perform(ch);
/* return */
return rcode;
}
static int _key2string(json_object *obj, const char *key, char *value) {
json_object *j;
if (!json_object_object_get_ex(obj, key, &j)) {
printf("Error: %s(%s) fail\n", __FUNCTION__, key);
return -1;
}
strcpy(value, json_object_get_string(j));
printf("%s: %s\n", key, value);
return 0;
}
static int _key2obj(json_object *obj, const char *key, json_object **keyObj) {
if (!json_object_object_get_ex(obj, key, keyObj)) {
printf("Error: %s(%s) fail\n", __FUNCTION__, key);
return -1;
}
printf("%s: %s\n", key, json_object_to_json_string(*keyObj));
return 0;
}
static int _hasKey(json_object *obj, const char *key) {
json_object *j;
if (!json_object_object_get_ex(obj, key, &j)) {
printf("Error: %s(%s) fail\n", __FUNCTION__, key);
return 0;
}
return 1;
}
int main(int argc, char *argv[]) {
CURL *ch; /* curl handle */
CURLcode rcode; /* curl result code */
json_object *json; /* json post body */
enum json_tokener_error jerr = json_tokener_success; /* json parse error */
struct curl_fetch_st curl_fetch; /* curl fetch struct */
struct curl_fetch_st *cf = &curl_fetch; /* pointer to fetch struct */
struct timeval t1, t2;
double timecost;
// start timer
gettimeofday(&t1, NULL);
/* url to test site */
char *url = "http://192.168.1.113:8888/common";
/* init curl handle */
if ((ch = curl_easy_init()) == NULL) {
/* log error */
fprintf(stderr, "ERROR: Failed to create curl handle in fetch_session");
/* return error */
return 1;
}
/* fetch page and capture return code */
rcode = curl_fetch_url(ch, url, cf);
/* cleanup curl handle */
curl_easy_cleanup(ch);
/* check return code */
if (rcode != CURLE_OK || cf->size < 1) {
/* log error */
fprintf(stderr, "ERROR: Failed to fetch url (%s) - curl said: %s",
url, curl_easy_strerror(rcode));
/* return error */
return 2;
}
/* check payload */
if (cf->payload != NULL) {
/* print result */
printf("CURL Returned: \n%s\n", cf->payload);
/* parse return */
json = json_tokener_parse_verbose(cf->payload, &jerr);
/* free payload */
free(cf->payload);
} else {
/* error */
fprintf(stderr, "ERROR: Failed to populate payload");
/* free payload */
free(cf->payload);
/* return */
return 3;
}
/* check error */
if (jerr != json_tokener_success) {
/* error */
fprintf(stderr, "ERROR: Failed to parse json string");
/* free json object */
json_object_put(json);
/* return */
return 4;
}
/* debugging */
printf("Parsed JSON: %s\n", json_object_to_json_string(json));
/*
** {
** "name": "ward",
** "location": "room",
** "config": {
** "mode": "on"
** },
** "thing": {
** "openDetector" : 1,
** "lightDetector": 1
** }
** }
*/
char name[32];
char location[32];
json_object *config;
json_object *things;
if (_key2string(json, "name", name) < 0) return 0;
if (_key2string(json, "location", location) < 0) return 0;
if (_key2obj(json, "config", &config) < 0) return 0;
if (_key2obj(json, "things", &things) < 0) return 0;
printf("config: %s\n", json_object_to_json_string(config));
int last_box_id, last_thing_id;
database_open();
last_box_id = database_insert_into_boxes(name, location, json_object_to_json_string(config));
printf("last_box_id after insert_into_boxes(%s, %s): %d\n", name, location, last_box_id);
printf("things: %s\n", json_object_to_json_string(things));
if (_hasKey(things, "openDetector")) {
printf("find thing: openDetector\n");
last_thing_id = database_insert_into_things("OpenDetector", "OpenDetector Status ...", last_box_id);
printf("last_thing_id after insert_into_things(OpenDetector): %d\n", last_thing_id);
int last_openDetector_id = database_insert_into_openDetectors(
"openDetector config ...",
"openDetector status ...",
last_thing_id);
printf("last_openDetector_id after insert_into_openDetectors(): %d\n", last_openDetector_id);
}
if (_hasKey(things, "lightDetector")) {
printf("find thing: lightDetector\n");
last_thing_id = database_insert_into_things("LightDetector", "LightDetector Status ...", last_box_id);
printf("last_thing_id after insert_into_things(lightDetector): %d\n", last_thing_id);
int last_openDetector_id = database_insert_into_lightDetectors(
"openDetector config ...",
"openDetector status ...",
last_thing_id);
printf("last_openDetector_id after insert_into_openDetectors(): %d\n", last_openDetector_id);
}
database_close();
if (_hasKey(things, "xxx")) {
printf("find thing: xxx\n");
}
// stop timer
gettimeofday(&t2, NULL);
// compute and print time cost in ms
timecost = (t2.tv_sec - t1.tv_sec) * 1000.0; // sec to ms
timecost += (t2.tv_usec - t1.tv_usec) / 1000.0; // us to ms
printf("Code time cost: %f\n", timecost);
/* exit */
return 0;
}
database.c
#include "database.h"
sqlite3 *Database;
int database_insert_into_openDetectors(const char *OpenConfig_, const char *OpenStatus_, int ThingId) {
char sql[256];
sprintf(sql,
"INSERT INTO OpenDetectors(OpenConfig_, OpenStatus_, ThingId)"
"VALUES ('%s', '%s', %d);"
, OpenConfig_, OpenStatus_, ThingId);
char *err_msg = 0;
if (SQLITE_OK != sqlite3_exec(Database, sql, 0, 0, &err_msg)) {
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
return -1;
}
return sqlite3_last_insert_rowid(Database);
}
int database_insert_into_lightDetectors(const char *LightConfig_, const char *LightStatus_, int ThingId) {
char sql[256];
sprintf(sql,
"INSERT INTO LightDetectors(LightConfig_, LightStatus_, ThingId)"
"VALUES ('%s', '%s', %d);"
, LightConfig_, LightStatus_, ThingId);
char *err_msg = 0;
if (SQLITE_OK != sqlite3_exec(Database, sql, 0, 0, &err_msg)) {
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
return -1;
}
return sqlite3_last_insert_rowid(Database);
}
int database_insert_into_things(const char *ThingType, const char *ThingStatus_, int BoxId) {
char sql[256];
sprintf(sql,
"INSERT INTO Things(ThingType, ThingStatus_, BoxId) "
"VALUES ('%s', '%s', %d);"
, ThingType, ThingStatus_, BoxId);
char *err_msg = 0;
if (SQLITE_OK != sqlite3_exec(Database, sql, 0, 0, &err_msg)) {
fprintf(stderr, "Failed to insert into Things\n");
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
return -1;
}
return sqlite3_last_insert_rowid(Database);
}
int database_insert_into_boxes(const char *BoxName, const char *BoxLocation, const char *BoxConfig_) {
char sql[256];
sprintf(sql,
"INSERT INTO Boxes(BoxName, BoxLocation, BoxConfig_) "
"VALUES ('%s', '%s', '%s');"
, BoxName, BoxLocation, BoxConfig_);
char *err_msg = 0;
if (SQLITE_OK != sqlite3_exec(Database, sql, 0, 0, &err_msg)) {
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
return -1;
}
return sqlite3_last_insert_rowid(Database);
}
int database_open() {
if (SQLITE_OK != sqlite3_open("iot.db", &Database)) {
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(Database));
sqlite3_close(Database);
return -1;
}
}
void database_close() {
sqlite3_close(Database);
}
database.h
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sqlite3.h>
extern sqlite3 *Database;
int database_insert_into_openDetectors(const char *OpenConfig_, const char *OpenStatus_, int ThingId);
int database_insert_into_lightDetectors(const char *LightConfig_, const char *LightStatus_, int ThingId);
int database_insert_into_things(const char *ThingType, const char *ThingStatus_, int BoxId);
int database_insert_into_boxes(const char *BoxName, const char *BoxLocation, const char *BoxConfig_);
int database_open();
void database_close();
應該在 database 新增一個 WhiteBoxes
CREATE TABLE WhiteBoxes (
WhiteBoxId INTEGER PRIMARY KEY NOT NULL,
WhiteBoxUrl TEXT NOT NULL,
WhiteBoxActive INTEGER PRIMARY KEY NOT NULL
);
initialize 的時候就放個幾筆假想的 box 資料方便讓 get_common 有個清單可以做事
修正 iot_init.sql
BEGIN TRANSACTION;
DROP TABLE IF EXISTS WhiteBoxes;
DROP TABLE IF EXISTS Boxes;
DROP TABLE IF EXISTS Things;
DROP TABLE IF EXISTS OpenDetectors;
DROP TABLE IF EXISTS LightDetectors;
CREATE TABLE IF NOT EXISTS WhiteBoxes (
WhiteBoxId INTEGER PRIMARY KEY NOT NULL,
WhiteBoxUrl TEXT NOT NULL,
WhiteBoxActive INTEGER PRIMARY KEY NOT NULL
);
INSERT INTO WhiteBoxes(WhiteBoxUrl, WhiteBoxActive) VALUES('http://192.168.1.113:8888/common', 0);
CREATE TABLE IF NOT EXISTS Boxes (
BoxId INTEGER PRIMARY KEY NOT NULL,
BoxName TEXT NOT NULL,
BoxLocation TEXT NOT NULL,
BoxConfig_ TEXT NOT NULL
);
CREATE TABLE Things (
ThingId INTEGER PRIMARY KEY,
ThingType TEXT NOT NULL,
ThingStatus_ TEXT NOT NULL,
BoxId INTEGER NOT NULL REFERENCES Boxes( BoxId )
);
CREATE TABLE OpenDetectors (
OpenId INTEGER PRIMARY KEY,
OpenConfig_ TEXT NOT NULL,
OpenStatus_ TEXT NOT NULL,
ThingId INTEGER NOT NULL REFERENCES Things( ThingId )
);
CREATE TABLE LightDetectors (
LightId INTEGER PRIMARY KEY,
LightConfig_ TEXT NOT NULL,
LightStatus_ TEXT NOT NULL,
ThingId INTEGER NOT NULL REFERENCES Things( ThingId )
);
COMMIT;