我对手表有着深厚的感情,每当人生遇到坎坷时,或者愤怒不已的时候,我都会想象和安慰自己“我去年买了块表”。刚有taobao的时候,我买了一块卡西欧的太阳能手表,时至今日我还记得价格是 258元。十多年过去了,这块表的卖家已经消失,我从来没有给他更换过电池,这块手表依然行走完好。
古人云“穷玩车,富玩表”。为了体验一下富人的感觉,最近入手了一块麦步智能手表。对于这块手表,最重要的是可以写程序。于是我就尝试给他编写程序,听上去又在重复“屌丝玩电脑”。
首先通读API,了解这个手表的原理。简单的说,这块手表通过蓝牙连接,从而实现WIFI通讯。
目标是编写一个获取当前比特币行情。huobi 网提供了行情API, http://api.huobi.com/staticmarket/ticker_btc_json.js 可以显示实时行情。例如:一次返回数据如下
{"time":"1467817886","ticker":{"open":4479,"vol":604962.2546,"symbol":"btccny","last":4522.79,"buy":4522.79,"sell":4523.03,"high":4612,"low":4467.64} }。 其中的 last 就是当前的价格。
配合麦步手表提供的显示股票行情的代码,编写自己的程序如下:
#include <stdlib.h> #include <stdio.h> #include <string.h> #include "maibu_sdk.h" #include "maibu_res.h" /*Web通讯ID*/ static uint32_t g_comm_id_web = 0; /*Web request地址*/ #define DATA_WEB "http://api.huobi.com/staticmarket/ticker_btc_json.js" /* 时间项 */ #define DATE_TEXT_POS_X 2 #define DATE_TEXT_POS_Y 6 #define DATE_TEXT_SIZE_W 70 #define DATE_TEXT_SIZE_H 14 #define TIME_TEXT_POS_X 90 #define TIME_TEXT_POS_Y 6 #define TIME_TEXT_SIZE_W 36 #define TIME_TEXT_SIZE_H 14 static const char weekday[7][11] = { {"周日"}, {"周一"}, {"周二"}, {"周三"}, {"周四"}, {"周五"}, {"周六"} }; /*窗口ID*/ static int32_t g_window_id = -1; //数据提示 static int32_t g_layer_id_text = -1; //数据内容 static int32_t g_layer_id_data = -1; //时间的句柄 static int32_t g_layer_id_time = -1; //日期的句柄 static int32_t g_layer_id_date = -1; //整个窗体句柄 static P_Window h_window; void data_request_web() { /*拼接url请求地址, 注意url的缓存大小*/ char url[200] = ""; sprintf(url, "%s", DATA_WEB); /* 拼接过滤参数,即只接受和过滤参数匹配的返回值 个人感觉这里的过滤可能是让手机做的,就是这里通知手机:json中的数据除了我制定的其他都过滤掉 */ /*发送一次*/ g_comm_id_web = maibu_comm_request_web(url, "last", 0); } void add_text_layer(P_Window p_window, int32_t *p_layer_id, char *p_str, GRect *p_frame, enum GAlign align, int8_t font, enum GColor color) { LayerText text_cfg = {p_str, *p_frame, align, font, 0}; P_Layer layer = app_layer_create_text(&text_cfg); app_layer_set_bg_color(layer, color); P_Layer old_layer = app_window_get_layer_by_id(p_window, *p_layer_id); if(old_layer) { *p_layer_id = app_window_replace_layer(p_window, old_layer, layer); } else { *p_layer_id = app_window_add_layer(p_window, layer); } } static void add_time_bar(P_Window p_window) { /* 添加时间图层 */ uint8_t text_buf[40]; struct date_time t; app_service_get_datetime(&t); memset(text_buf, 0, sizeof(text_buf)); sprintf((char *)text_buf, "%s", (char *)&weekday[t.wday][0]); sprintf(&text_buf[6], "%02d-%02d", t.mon, t.mday); GRect frame; frame.origin.x = DATE_TEXT_POS_X; frame.origin.y = DATE_TEXT_POS_Y; frame.size.h = DATE_TEXT_SIZE_H; frame.size.w = DATE_TEXT_SIZE_W; add_text_layer(p_window, &g_layer_id_date, (char*)text_buf, &frame, GAlignLeft, U_ASCII_ARIAL_14, GColorWhite); frame.origin.x = TIME_TEXT_POS_X; frame.origin.y = TIME_TEXT_POS_Y; frame.size.h = TIME_TEXT_SIZE_H; frame.size.w = TIME_TEXT_SIZE_W; memset(text_buf, 0, sizeof(text_buf)); sprintf(text_buf, "%02d:%02d", t.hour, t.min); add_text_layer(p_window, &g_layer_id_time, (char*)text_buf, &frame, GAlignLeft, U_ASCII_ARIAL_14, GColorWhite); } P_Window init_btc_window() { static P_Window p_window; p_window = app_window_create(); if (NULL == p_window) { return NULL; } /* 添加表盘背景 */ GRect frame = {{0, 0}, {128, 128}}; GBitmap bitmap; res_get_user_bitmap(BMP_STOCK_BG, &bitmap); LayerBitmap layer_bitmap = {bitmap, frame, GAlignCenter}; P_Layer layer = app_layer_create_bitmap(&layer_bitmap); app_window_add_layer(p_window, layer); /* 添加时间栏 */ add_time_bar(p_window); /*加入你的代码 begin*/ /*添加数据提示信息*/ GRect frame_main = {{0, 30}, {16, 128}}; add_text_layer(p_window, &g_layer_id_text, "BTC", &frame_main, GAlignCenter, U_ASCII_ARIAL_14, GColorWhite); /*添加数据*/ GRect frame_data = {{0, 60}, {16, 128}}; add_text_layer(p_window, &g_layer_id_data, "waiting", &frame_data, GAlignCenter, U_ASCII_ARIAL_14, GColorWhite); return p_window; } void data_comm_result_callback(enum ECommResult result, uint32_t comm_id, void *context) { /*如果上一次请求WEB通讯失败,并且通讯ID相同,则重新发送*/ if ((result == ECommResultFail) && (comm_id == g_comm_id_web)) { data_request_web(); } } static void web_recv_callback(const uint8_t *buff, uint16_t size) { char stock_gid[10]; char i; maibu_get_json_str(buff, "last", stock_gid, 10); for (i=0;i<10;i++) { if (stock_gid[i]=='}') { stock_gid[i]=0; } } /*添加数据*/ GRect frame_data = {{0, 60}, {16, 128}}; add_text_layer(h_window, &g_layer_id_data, stock_gid, &frame_data, GAlignCenter, U_ASCII_ARIAL_14, GColorWhite); app_window_update(h_window); } static void watch_time_change_callback(enum SysEventType type, void *context) { /*时间更改,分变化*/ if (type == SysEventTypeTimeChange) { uint8_t text_buf[40]; struct date_time t; app_service_get_datetime(&t); memset(text_buf, 0, sizeof(text_buf)); sprintf((char *)text_buf, "%s", (char *)&weekday[t.wday][0]); sprintf(&text_buf[6], "%02d-%02d", t.mon, t.mday); GRect frame; frame.origin.x = DATE_TEXT_POS_X; frame.origin.y = DATE_TEXT_POS_Y; frame.size.h = DATE_TEXT_SIZE_H; frame.size.w = DATE_TEXT_SIZE_W; add_text_layer(h_window, &g_layer_id_date, (char*)text_buf, &frame, GAlignLeft, U_ASCII_ARIAL_14, GColorWhite); frame.origin.x = TIME_TEXT_POS_X; frame.origin.y = TIME_TEXT_POS_Y; frame.size.h = TIME_TEXT_SIZE_H; frame.size.w = TIME_TEXT_SIZE_W; memset(text_buf, 0, sizeof(text_buf)); sprintf(text_buf, "%02d:%02d", t.hour, t.min); add_text_layer(h_window, &g_layer_id_time, (char*)text_buf, &frame, GAlignLeft, U_ASCII_ARIAL_14, GColorWhite); app_window_update(h_window); } } static void data_timer_callback(date_time_t tick_time, uint32_t millis, void *context) { data_request_web(); } int main() { /*创建消息列表窗口*/ h_window = init_btc_window(); //订阅时间改变事件 maibu_service_sys_event_subscribe(watch_time_change_callback); /*放入窗口栈显示*/ g_window_id = app_window_stack_push(h_window); data_request_web(); /*注册通讯结果回调*/ maibu_comm_register_result_callback(data_comm_result_callback); //注册网络请求回调函数 maibu_comm_register_web_callback(web_recv_callback); //聚合数据源每隔10s更新数据 app_window_timer_subscribe(h_window, 10000, data_timer_callback, (void *)h_window); return 0; }
编译之后上传到手表上就OK了。
看起来工作正常,美中不足就是屏幕有点小,如果能像美国队长那块一样大就完美了。
这块手表的一大重要特性就是采用电纸屏幕,就是那种 Kindle 的屏幕材质,不改变内容无需耗电,这样待机可以很长时间(标称21天)。说道这里,我想起来一个很老的苏联笑话:
有一个人在机场等六点的飞机,可是他忘记了带手表,于是他想找
个人问问。这时,他看见一个人提着两个巨大的手提箱吃力的走过来,手腕上戴
着一块异常漂亮的一看就知道是高科技产品的手表。
“请问,几点了?”他问道。
“哪个国家的时间?”那人反问。
“哦?”他的好奇心来了,“你都知道哪些国家的时间呢?”
“所有的国家,”那人回答道。
“哇!那可真是一块好手表呀!”
“还不止这些呢,这块表还有GPS卫星系统,可以随时收发电子邮件、
传真,这个彩色的屏幕可以收看NTSC制式的电视节目!”那人给他
演示,果真如此!
“哦!太棒了,我真想拥有一块这样的手表,您……您可以把它卖给我吗?”
“说实话,我已经烦透了这块表了,这样吧,900美元,如何?”
他马上掏出支票簿,写了900美元给那人,“成交!”
“好的,现在,它是你的了。”那人如释重负,把手表交给他,“这个是你
的手表”,然后指着地上的两个大箱子说,“这两个是电池!”
无数的科学家和工程师在不断的努力改造着我们的生活。