#include // Persistent storage key #define SETTINGS_KEY 1 // Largest expected inbox and outbox message sizes const uint32_t inbox_size = 64; const uint32_t outbox_size = 64; static char s_api[40]; static char s_username[40]; static char s_password[40]; static char s_server[255]; static bool s_js_ready; static Window *s_window; //static Layer *window_layer; //static GRect bounds; static TextLayer *s_text_layer; static ActionBarLayer *s_action_bar_layer; static GBitmap *s_h_on_bitmap, *s_h_off_bitmap, *s_q_mark_bitmap; bool is_home_on = false; static uint32_t size ; typedef enum { status, username, password, server } AppKey; static char * msg; // Define our settings struct typedef struct Settings { char username; char password; char server; } Settings; // An instance of the struct static Settings settings; // Save the settings to persistent storage static void prv_save_settings() { persist_write_data(SETTINGS_KEY, &settings, sizeof(settings)); } static void inbox_dropped_callback(AppMessageResult reason, void *context) { // A message was received, but had to be dropped APP_LOG(APP_LOG_LEVEL_ERROR, "Message dropped. Reason: %d", (int)reason); } static void outbox_sent_callback(DictionaryIterator *iter, void *context) { // The message just sent has been successfully delivered APP_LOG(APP_LOG_LEVEL_INFO, "Message sent. "); } static void outbox_failed_callback(DictionaryIterator *iter, AppMessageResult reason, void *context) { // The message just sent failed to be delivered APP_LOG(APP_LOG_LEVEL_ERROR, "Message send failed. Reason: %d", (int)reason); } static void select_click_handler(ClickRecognizerRef recognizer, void *context) { // Declare the dictionary's iterator DictionaryIterator *out_iter; // Prepare the outbox buffer for this message AppMessageResult result = app_message_outbox_begin(&out_iter); if(result == APP_MSG_OK) { // Add an item to ask for weather data msg = "get"; dict_write_cstring(out_iter, status, msg); // Send this message result = app_message_outbox_send(); if(result != APP_MSG_OK) { APP_LOG(APP_LOG_LEVEL_ERROR, "Error sending the outbox: %d", (int)result); } } else { // The outbox cannot be used right now APP_LOG(APP_LOG_LEVEL_ERROR, "Error preparing the outbox: %d", (int)result); } } static void up_click_handler(ClickRecognizerRef recognizer, void *context) { // Declare the dictionary's iterator DictionaryIterator *out_iter; // Prepare the outbox buffer for this message AppMessageResult result = app_message_outbox_begin(&out_iter); if(result == APP_MSG_OK) { // Add an item to ask for weather data msg = "home_on"; dict_write_cstring(out_iter, status, msg); // Send this message result = app_message_outbox_send(); if(result != APP_MSG_OK) { APP_LOG(APP_LOG_LEVEL_ERROR, "Error sending the outbox: %d", (int)result); } } else { // The outbox cannot be used right now APP_LOG(APP_LOG_LEVEL_ERROR, "Error preparing the outbox: %d", (int)result); } } static void down_click_handler(ClickRecognizerRef recognizer, void *context) { // Declare the dictionary's iterator DictionaryIterator *out_iter; // Prepare the outbox buffer for this message AppMessageResult result = app_message_outbox_begin(&out_iter); if(result == APP_MSG_OK) { // Add an item to ask for weather data msg = "home_off"; dict_write_cstring(out_iter, status, msg); // Send this message result = app_message_outbox_send(); if(result != APP_MSG_OK) { APP_LOG(APP_LOG_LEVEL_ERROR, "Error sending the outbox: %d", (int)result); } } else { // The outbox cannot be used right now APP_LOG(APP_LOG_LEVEL_ERROR, "Error preparing the outbox: %d", (int)result); } } static void click_config_provider(void *context) { window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler); window_single_click_subscribe(BUTTON_ID_UP, up_click_handler); window_single_click_subscribe(BUTTON_ID_DOWN, down_click_handler); } void comm_is_ready() { // Get information about the window Layer *window_layer = window_get_root_layer(s_window); GRect bounds = layer_get_bounds(window_layer); // Create a text layer and set the text const GEdgeInsets label_insets = {.right = ACTION_BAR_WIDTH, .left = ACTION_BAR_WIDTH / 2}; s_text_layer = text_layer_create(grect_inset(bounds, label_insets)); text_layer_set_text(s_text_layer, "Welcome to Syno Cam Switch ! ready to switch..."); // Set the font and text alignment text_layer_set_font(s_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); text_layer_set_text_alignment(s_text_layer, GTextAlignmentCenter); // Add the text layer to the window layer_add_child(window_get_root_layer(s_window), text_layer_get_layer(s_text_layer)); // Enable text flow and paging on the text layer, with a slight inset of 10, for round screens text_layer_enable_screen_text_flow_and_paging(s_text_layer, 10); // Push the window, setting the window animation to 'true' window_stack_push(s_window, true); // App Logging! APP_LOG(APP_LOG_LEVEL_DEBUG, "Just pushed a window!"); // waiting for BT comm ready // click provider window_set_click_config_provider(s_window, click_config_provider); } static void inbox_received_callback(DictionaryIterator *iter, void *context) { // A new message has been successfully received APP_LOG(APP_LOG_LEVEL_DEBUG, "New message! "); size = dict_size(iter); // JS readiness Tuple *ready_tuple = dict_find(iter, MESSAGE_KEY_JSReady); if(ready_tuple){ //Pebblekit JS is ready ! Safe to send messages s_js_ready = true; comm_is_ready(); } // Read API returns // Tuple *api_tuple = dict_read_first(iter); Tuple *api_tuple = dict_find(iter, MESSAGE_KEY_status); if(api_tuple) { strncpy(s_api, api_tuple->value->cstring, 40); // Display in the TextLayer text_layer_set_text(s_text_layer, s_api); }else{ APP_LOG(APP_LOG_LEVEL_DEBUG, "not status message... "); } // Read String preferences Tuple *username_t = dict_find(iter, MESSAGE_KEY_username); if(username_t) { strncpy(s_username, username_t->value->cstring, 40); prv_save_settings(); APP_LOG(APP_LOG_LEVEL_DEBUG, "new username in settings... %s",s_username); } Tuple *password_t = dict_find(iter, MESSAGE_KEY_password); if(password_t) { strncpy(s_password, password_t->value->cstring, 40); prv_save_settings(); APP_LOG(APP_LOG_LEVEL_DEBUG, "new password in settings... %s",s_password); } Tuple *server_t = dict_find(iter, MESSAGE_KEY_server); if(server_t) { strncpy(s_server, server_t->value->cstring, 255); prv_save_settings(); APP_LOG(APP_LOG_LEVEL_DEBUG, "new server in settings... %s",s_server); } } static void init(void) { // Open AppMessage app_message_open(inbox_size, outbox_size); // Register to be notified about inbox received events app_message_register_inbox_received(inbox_received_callback); // Register to be notified about inbox dropped events app_message_register_inbox_dropped(inbox_dropped_callback); // Register to be notified about outbox sent events app_message_register_outbox_sent(outbox_sent_callback); // Register to be notified about outbox failed events app_message_register_outbox_failed(outbox_failed_callback); // Create a window and get information about the window s_window = window_create(); Layer *window_layer = window_get_root_layer(s_window); GRect bounds = layer_get_bounds(window_layer); //load buttons s_h_on_bitmap = gbitmap_create_with_resource(RESOURCE_ID_HOME_ON); s_q_mark_bitmap = gbitmap_create_with_resource(RESOURCE_ID_Q_MARK); s_h_off_bitmap = gbitmap_create_with_resource(RESOURCE_ID_HOME_OFF); s_action_bar_layer = action_bar_layer_create(); action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_UP, s_h_on_bitmap); action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_SELECT, s_q_mark_bitmap); action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_DOWN, s_h_off_bitmap); action_bar_layer_add_to_window(s_action_bar_layer, s_window); // Create a text layer and set the text const GEdgeInsets label_insets = {.right = ACTION_BAR_WIDTH, .left = ACTION_BAR_WIDTH / 2}; s_text_layer = text_layer_create(grect_inset(bounds, label_insets)); text_layer_set_text(s_text_layer, "Welcome to Syno Cam Switch !"); // Set the font and text alignment text_layer_set_font(s_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); text_layer_set_text_alignment(s_text_layer, GTextAlignmentCenter); // Add the text layer to the window layer_add_child(window_get_root_layer(s_window), text_layer_get_layer(s_text_layer)); // Enable text flow and paging on the text layer, with a slight inset of 10, for round screens text_layer_enable_screen_text_flow_and_paging(s_text_layer, 10); // Push the window, setting the window animation to 'true' window_stack_push(s_window, true); // App Logging! APP_LOG(APP_LOG_LEVEL_DEBUG, "Just pushed a window!"); } static void deinit(void) { // Destroy the text layer text_layer_destroy(s_text_layer); // Destroy the action bar layer action_bar_layer_destroy(s_action_bar_layer); // Destroy the window window_destroy(s_window); } int main(void) { init(); app_event_loop(); deinit(); }