commit ba131ad1bc750a6352d1e5b18482db442325eb9e
parent 4485bc672fd62f1f2244a72d9cc7cf39edbaf32f
Author: Natasha Kerensikova <natacha@instinctive.eu>
Date: Wed, 11 May 2016 20:29:15 +0000
Add transmission of CSV data from watch to phone
Diffstat:
3 files changed, 151 insertions(+), 0 deletions(-)
diff --git a/appinfo.json b/appinfo.json
@@ -11,6 +11,11 @@
"watchapp": {
"watchface": false
},
+ "appKeys": {
+ "lastSent": 110,
+ "dataKey": 210,
+ "dataLine": 220
+ },
"resources": {
"media": []
}
diff --git a/src/battery-minus.c b/src/battery-minus.c
@@ -16,6 +16,7 @@
#include <inttypes.h>
#include <pebble.h>
+#include "dict_tools.h"
#include "simple_dialog.h"
#include "storage.h"
@@ -56,6 +57,12 @@ first_index(struct event *page, size_t page_length) {
* DATA UPLOAD TO WEB *
**********************/
+#define MSG_KEY_LAST_SENT 110
+#define MSG_KEY_DATA_TIME 210
+#define MSG_KEY_DATA_LINE 220
+
+static unsigned upload_index;
+
static const char keyword_anomalous[] = "error";
static const char keyword_charge_start[] = "charge";
static const char keyword_charge_stop[] = "dischg";
@@ -155,6 +162,120 @@ event_csv_image(char *buffer, size_t size, struct event *event) {
return true;
}
+static bool
+send_event(struct event *event) {
+ AppMessageResult msg_result;
+ DictionaryIterator *iter;
+ DictionaryResult dict_result;
+ char buffer[64];
+ bool result = true;
+
+ if (!event) return false;
+
+ if (!event_csv_image(buffer, sizeof buffer, event))
+ return false;
+
+ msg_result = app_message_outbox_begin(&iter);
+ if (msg_result) {
+ APP_LOG(APP_LOG_LEVEL_ERROR,
+ "send_event: app_message_outbox_begin returned %d",
+ (int)msg_result);
+ return false;
+ }
+
+ dict_result = dict_write_int(iter, MSG_KEY_DATA_TIME,
+ &event->time, sizeof event->time, true);
+ if (dict_result != DICT_OK) {
+ APP_LOG(APP_LOG_LEVEL_ERROR,
+ "send_event: [%d] unable to add data time %" PRIi32,
+ (int)dict_result, event->time);
+ result = false;
+ }
+
+ dict_result = dict_write_cstring(iter, MSG_KEY_DATA_LINE, buffer);
+ if (dict_result != DICT_OK) {
+ APP_LOG(APP_LOG_LEVEL_ERROR,
+ "send_event: [%d] unable to add data line \"%s\"",
+ (int)dict_result, buffer);
+ result = false;
+ }
+
+ msg_result = app_message_outbox_send();
+ if (msg_result) {
+ APP_LOG(APP_LOG_LEVEL_ERROR,
+ "send_event: app_mesage_outbox_send returned %d",
+ (int)msg_result);
+ result = false;
+ }
+
+ return result;
+}
+
+static void
+handle_last_sent(Tuple *tuple) {
+ time_t t = tuple_int(tuple);
+
+ upload_index = first_index(current_page, PAGE_LENGTH);
+
+ if (!current_page[upload_index].time)
+ /* empty page */
+ return;
+
+ if (t)
+ while (current_page[upload_index].time <= t) {
+ unsigned next_index = (upload_index + 1) % PAGE_LENGTH;
+ if (current_page[upload_index].time
+ > current_page[next_index].time)
+ /* end of page reached without match */
+ return;
+ upload_index = next_index;
+ }
+
+ send_event(current_page + upload_index);
+}
+
+static void
+inbox_received_handler(DictionaryIterator *iterator, void *context) {
+ Tuple *tuple;
+ (void)context;
+
+ for (tuple = dict_read_first(iterator);
+ tuple;
+ tuple = dict_read_next(iterator)) {
+ switch (tuple->key) {
+ case MSG_KEY_LAST_SENT:
+ handle_last_sent(tuple);
+ break;
+
+ default:
+ APP_LOG(APP_LOG_LEVEL_ERROR,
+ "Unknown key %" PRIu32 " in received message",
+ tuple->key);
+ break;
+ }
+ }
+}
+
+static void
+outbox_sent_handler(DictionaryIterator *iterator, void *context) {
+ unsigned next_index = (upload_index + 1) % PAGE_LENGTH;
+ (void)iterator;
+ (void)context;
+
+ if (current_page[upload_index].time <= current_page[next_index].time) {
+ upload_index = next_index;
+ send_event(current_page + next_index);
+ }
+}
+
+static void
+outbox_failed_handler(DictionaryIterator *iterator, AppMessageResult reason,
+ void *context) {
+ (void)iterator;
+ (void)context;
+ APP_LOG(APP_LOG_LEVEL_ERROR, "Outbox failed: 0x%x", (unsigned)reason);
+}
+
/*************
* MENU ITEM *
*************/
@@ -478,6 +599,11 @@ init(void) {
.appear = window_appear,
});
window_stack_push(window, true);
+
+ app_message_register_inbox_received(inbox_received_handler);
+ app_message_register_outbox_failed(outbox_failed_handler);
+ app_message_register_outbox_sent(outbox_sent_handler);
+ app_message_open(256, 2048);
}
static void
diff --git a/src/js/app.js b/src/js/app.js
@@ -20,6 +20,11 @@ var cfg_extra_fields = [];
var to_send = [];
+function enqueue(key, line) {
+ to_send.push(key + ";" + line);
+ localStorage.setItem("toSend", to_send.join("|"));
+}
+
Pebble.addEventListener("ready", function(e) {
console.log("Battery- JS ready");
@@ -31,6 +36,17 @@ Pebble.addEventListener("ready", function(e) {
cfg_endpoint = localStorage.getItem("cfgEndpoint");
cfg_data_field = localStorage.getItem("cfgDataField");
+
+ if (cfg_endpoint && cfg_data_field) {
+ Pebble.sendAppMessage({ "lastSent":
+ parseInt(localStorage.getItem("lastSent") || "0", 10) });
+ }
+});
+
+Pebble.addEventListener("appmessage", function(e) {
+ if (e.payload.dataKey && e.payload.dataLine) {
+ enqueue(e.payload.dataKey, e.payload.dataLine);
+ }
});
Pebble.addEventListener("showConfiguration", function() {
@@ -80,4 +96,8 @@ Pebble.addEventListener("webviewclosed", function(e) {
to_send = [];
wasConfigured = false;
}
+
+ if (!wasConfigured && cfg_endpoint && cfg_data_field) {
+ Pebble.sendAppMessage({ "lastSent": 0 });
+ }
});