├── .gitignore ├── LICENSE ├── README.md ├── appinfo.json ├── classio-battery-connection-screenshot.png ├── src └── classio.c └── wscript /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Pebble Technology 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # classio 2 | 3 | ![screenshot](classio-battery-connection-screenshot.png) 4 | 5 | Example watchface showing the time, including seconds. 6 | 7 | This version also displays the battery level and status of the Bluetooth 8 | connection. -------------------------------------------------------------------------------- /appinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "uuid": "54d3118f-3346-462c-995c-0d0b4e01148c", 3 | "shortName": "Classio B&B", 4 | "longName": "Classio B&B", 5 | "companyName": "Camembert, Inc.", 6 | "versionCode": 2, 7 | "versionLabel": "2.0", 8 | "watchapp": { 9 | "watchface": true 10 | }, 11 | "appKeys": {}, 12 | "resources": { 13 | "media": [] 14 | }, 15 | "targetPlatforms": [ 16 | "aplite", 17 | "basalt", 18 | "chalk" 19 | ], 20 | "sdkVersion": "3" 21 | } -------------------------------------------------------------------------------- /classio-battery-connection-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pebble-examples/classio-battery-connection/c3a3cd14b8021c57ab10c1accd97139b59031776/classio-battery-connection-screenshot.png -------------------------------------------------------------------------------- /src/classio.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static Window *s_main_window; 4 | static TextLayer *s_time_layer; 5 | static TextLayer *s_battery_layer; 6 | static TextLayer *s_connection_layer; 7 | 8 | static void handle_battery(BatteryChargeState charge_state) { 9 | static char battery_text[] = "100% charged"; 10 | 11 | if (charge_state.is_charging) { 12 | snprintf(battery_text, sizeof(battery_text), "charging"); 13 | } else { 14 | snprintf(battery_text, sizeof(battery_text), "%d%% charged", charge_state.charge_percent); 15 | } 16 | text_layer_set_text(s_battery_layer, battery_text); 17 | } 18 | 19 | static void handle_second_tick(struct tm* tick_time, TimeUnits units_changed) { 20 | // Needs to be static because it's used by the system later. 21 | static char s_time_text[] = "00:00:00"; 22 | 23 | strftime(s_time_text, sizeof(s_time_text), "%T", tick_time); 24 | text_layer_set_text(s_time_layer, s_time_text); 25 | } 26 | 27 | static void handle_bluetooth(bool connected) { 28 | text_layer_set_text(s_connection_layer, connected ? "connected" : "disconnected"); 29 | } 30 | 31 | static void main_window_load(Window *window) { 32 | Layer *window_layer = window_get_root_layer(window); 33 | GRect bounds = layer_get_frame(window_layer); 34 | 35 | s_time_layer = text_layer_create(GRect(0, 40, bounds.size.w, 34)); 36 | text_layer_set_text_color(s_time_layer, GColorWhite); 37 | text_layer_set_background_color(s_time_layer, GColorClear); 38 | text_layer_set_font(s_time_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); 39 | text_layer_set_text_alignment(s_time_layer, GTextAlignmentCenter); 40 | 41 | s_connection_layer = text_layer_create(GRect(0, 90, bounds.size.w, 34)); 42 | text_layer_set_text_color(s_connection_layer, GColorWhite); 43 | text_layer_set_background_color(s_connection_layer, GColorClear); 44 | text_layer_set_font(s_connection_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18)); 45 | text_layer_set_text_alignment(s_connection_layer, GTextAlignmentCenter); 46 | handle_bluetooth(connection_service_peek_pebble_app_connection()); 47 | 48 | s_battery_layer = text_layer_create(GRect(0, 120, bounds.size.w, 34)); 49 | text_layer_set_text_color(s_battery_layer, GColorWhite); 50 | text_layer_set_background_color(s_battery_layer, GColorClear); 51 | text_layer_set_font(s_battery_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18)); 52 | text_layer_set_text_alignment(s_battery_layer, GTextAlignmentCenter); 53 | text_layer_set_text(s_battery_layer, "100% charged"); 54 | 55 | // Ensures time is displayed immediately (will break if NULL tick event accessed). 56 | // (This is why it's a good idea to have a separate routine to do the update itself.) 57 | time_t now = time(NULL); 58 | struct tm *current_time = localtime(&now); 59 | handle_second_tick(current_time, SECOND_UNIT); 60 | 61 | tick_timer_service_subscribe(SECOND_UNIT, handle_second_tick); 62 | battery_state_service_subscribe(handle_battery); 63 | 64 | connection_service_subscribe((ConnectionHandlers) { 65 | .pebble_app_connection_handler = handle_bluetooth 66 | }); 67 | 68 | layer_add_child(window_layer, text_layer_get_layer(s_time_layer)); 69 | layer_add_child(window_layer, text_layer_get_layer(s_connection_layer)); 70 | layer_add_child(window_layer, text_layer_get_layer(s_battery_layer)); 71 | 72 | handle_battery(battery_state_service_peek()); 73 | } 74 | 75 | static void main_window_unload(Window *window) { 76 | tick_timer_service_unsubscribe(); 77 | battery_state_service_unsubscribe(); 78 | connection_service_unsubscribe(); 79 | text_layer_destroy(s_time_layer); 80 | text_layer_destroy(s_connection_layer); 81 | text_layer_destroy(s_battery_layer); 82 | } 83 | 84 | static void init() { 85 | s_main_window = window_create(); 86 | window_set_background_color(s_main_window, GColorBlack); 87 | window_set_window_handlers(s_main_window, (WindowHandlers) { 88 | .load = main_window_load, 89 | .unload = main_window_unload, 90 | }); 91 | window_stack_push(s_main_window, true); 92 | } 93 | 94 | static void deinit() { 95 | window_destroy(s_main_window); 96 | } 97 | 98 | int main(void) { 99 | init(); 100 | app_event_loop(); 101 | deinit(); 102 | } 103 | -------------------------------------------------------------------------------- /wscript: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # This file is the default set of rules to compile a Pebble project. 4 | # 5 | # Feel free to customize this to your needs. 6 | # 7 | 8 | import os.path 9 | 10 | top = '.' 11 | out = 'build' 12 | 13 | def options(ctx): 14 | ctx.load('pebble_sdk') 15 | 16 | def configure(ctx): 17 | ctx.load('pebble_sdk') 18 | 19 | def build(ctx): 20 | ctx.load('pebble_sdk') 21 | 22 | build_worker = os.path.exists('worker_src') 23 | binaries = [] 24 | 25 | for p in ctx.env.TARGET_PLATFORMS: 26 | ctx.set_env(ctx.all_envs[p]) 27 | ctx.set_group(ctx.env.PLATFORM_NAME) 28 | app_elf='{}/pebble-app.elf'.format(ctx.env.BUILD_DIR) 29 | ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'), 30 | target=app_elf) 31 | 32 | if build_worker: 33 | worker_elf='{}/pebble-worker.elf'.format(ctx.env.BUILD_DIR) 34 | binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf}) 35 | ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/**/*.c'), 36 | target=worker_elf) 37 | else: 38 | binaries.append({'platform': p, 'app_elf': app_elf}) 39 | 40 | ctx.set_group('bundle') 41 | ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob('src/js/**/*.js')) 42 | --------------------------------------------------------------------------------