From a6a2c0d317b98a1439b89d7400e6bfc6d7ce21ed Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Fri, 22 May 2026 22:43:47 +0200 Subject: [PATCH 1/8] Add battery reporting feature to remote endpoint - Add sendBatteryToEndpoint() function in index.js to POST battery data - Add configuration for remote endpoint URL and token with localStorage persistence - Add message keys for battery data in messaging.h - Implement messaging_sendBatteryData() in messaging.c - Send battery data from watch when battery state changes in main.c - Handle battery data in appmessage listener on phone side --- src/c/main.c | 2 ++ src/c/messaging.c | 10 +++++++ src/c/messaging.h | 36 +++++++++++++++++++++++ src/pkjs/index.js | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) diff --git a/src/c/main.c b/src/c/main.c index 41808e62..69f44c5a 100755 --- a/src/c/main.c +++ b/src/c/main.c @@ -148,6 +148,8 @@ void bluetoothStateChanged(bool newConnectionState) { // force the sidebar to redraw any time the battery state changes void batteryStateChanged(BatteryChargeState charge_state) { + // Send battery data to phone for remote reporting + messaging_sendBatteryData(charge_state.charge_percent, charge_state.is_charging); Sidebar_redraw(); } diff --git a/src/c/messaging.c b/src/c/messaging.c index 6350f6a7..cbc41f81 100755 --- a/src/c/messaging.c +++ b/src/c/messaging.c @@ -13,6 +13,16 @@ void messaging_requestNewWeatherData() { app_message_outbox_send(); } +void messaging_sendBatteryData(uint8_t batteryPercent, bool isCharging) { + DictionaryIterator *iter; + app_message_outbox_begin(&iter); + + dict_write_uint8(iter, MESSAGE_KEY_BatteryPercent, batteryPercent); + dict_write_uint8(iter, MESSAGE_KEY_IsCharging, isCharging ? 1 : 0); + + app_message_outbox_send(); +} + void messaging_init(void (*processed_callback)(void)) { // register my custom callback message_processed_callback = processed_callback; diff --git a/src/c/messaging.h b/src/c/messaging.h index 534513b9..edeb340d 100755 --- a/src/c/messaging.h +++ b/src/c/messaging.h @@ -1,7 +1,43 @@ #pragma once #include +// Message keys +enum { + MESSAGE_KEY_WeatherTemperature = 0, + MESSAGE_KEY_WeatherCondition, + MESSAGE_KEY_WeatherUVIndex, + MESSAGE_KEY_WeatherForecastCondition, + MESSAGE_KEY_WeatherForecastHighTemp, + MESSAGE_KEY_WeatherForecastLowTemp, + MESSAGE_KEY_SettingColorTime, + MESSAGE_KEY_SettingColorBG, + MESSAGE_KEY_SettingColorSidebar, + MESSAGE_KEY_SettingSidebarOnLeft, + MESSAGE_KEY_SettingSidebarTextColor, + MESSAGE_KEY_SettingUseMetric, + MESSAGE_KEY_SettingBluetoothVibe, + MESSAGE_KEY_SettingLanguageID, + MESSAGE_KEY_SettingShowLeadingZero, + MESSAGE_KEY_SettingShowBatteryPct, + MESSAGE_KEY_SettingClockFontId, + MESSAGE_KEY_SettingHourlyVibe, + MESSAGE_KEY_SettingUseLargeFonts, + MESSAGE_KEY_SettingWidget0ID, + MESSAGE_KEY_SettingWidget1ID, + MESSAGE_KEY_SettingWidget2ID, + MESSAGE_KEY_SettingAltClockName, + MESSAGE_KEY_SettingAltClockOffset, + MESSAGE_KEY_SettingDecimalSep, + MESSAGE_KEY_SettingHealthUseDistance, + MESSAGE_KEY_SettingHealthUseRestfulSleep, + MESSAGE_KEY_SettingDisableAutobattery, + MESSAGE_KEY_SettingDisconnectIcon, + MESSAGE_KEY_BatteryPercent, + MESSAGE_KEY_IsCharging +}; + void messaging_requestNewWeatherData(); +void messaging_sendBatteryData(uint8_t batteryPercent, bool isCharging); void messaging_init(void (*message_processed_callback)(void)); void inbox_received_callback(DictionaryIterator *iterator, void *context); diff --git a/src/pkjs/index.js b/src/pkjs/index.js index 670e37f4..e29a5652 100755 --- a/src/pkjs/index.js +++ b/src/pkjs/index.js @@ -5,6 +5,56 @@ var CONFIG_VERSION = 9; // var BASE_CONFIG_URL = 'http://localhost:3001/'; var BASE_CONFIG_URL = 'http://freakified.github.io/TimeStylePebble/'; +// Remote battery endpoint configuration +var remoteEndpointUrl = ''; +var remoteEndpointToken = ''; + +// Check if remote endpoint is configured +function isEndpointConfigured() { + return remoteEndpointUrl && remoteEndpointUrl.trim() !== ''; +} + +// Send battery data to remote endpoint via HTTP POST with Bearer token +function sendBatteryToEndpoint(batteryPercent, isCharging) { + if (!isEndpointConfigured()) { + console.log('Remote endpoint not configured, skipping battery sync'); + return; + } + + console.log('Sending battery data to remote endpoint: ' + batteryPercent + '% (charging: ' + isCharging + ')'); + + var req = new XMLHttpRequest(); + req.open('POST', remoteEndpointUrl, true); + req.setRequestHeader('Content-Type', 'application/json'); + + // Add Bearer token authorization if provided + if (remoteEndpointToken && remoteEndpointToken.trim() !== '') { + req.setRequestHeader('Authorization', 'Bearer ' + remoteEndpointToken.trim()); + } + + req.onload = function() { + if (req.readyState === 4) { + if (req.status >= 200 && req.status < 300) { + console.log('Battery data sent successfully to remote endpoint'); + } else { + console.log('Failed to send battery data to remote endpoint. Status: ' + req.status); + } + } + }; + + req.onerror = function() { + console.log('Network error sending battery data to remote endpoint'); + }; + + var payload = JSON.stringify({ + battery_percent: batteryPercent, + is_charging: isCharging, + timestamp: new Date().toISOString() + }); + + req.send(payload); +} + // Listen for when the watchface is opened Pebble.addEventListener('ready', function (e) { @@ -15,6 +65,14 @@ Pebble.addEventListener('ready', window.localStorage.setItem('disable_weather', 'no'); } + // Load remote endpoint configuration from localStorage + if (window.localStorage.getItem('remote_endpoint_url')) { + remoteEndpointUrl = window.localStorage.getItem('remote_endpoint_url'); + } + if (window.localStorage.getItem('remote_endpoint_token')) { + remoteEndpointToken = window.localStorage.getItem('remote_endpoint_token'); + } + console.log('the wdisabled value is: "' + window.localStorage.getItem('disable_weather') + '"'); // if applicable, get the weather data if (window.localStorage.getItem('disable_weather') != 'yes') { @@ -29,6 +87,11 @@ Pebble.addEventListener('appmessage', function (msg) { console.log('Recieved message: ' + JSON.stringify(msg.payload)); + // Check if this is a battery status update + if (msg.payload.battery_percent !== undefined && msg.payload.is_charging !== undefined) { + sendBatteryToEndpoint(msg.payload.battery_percent, msg.payload.is_charging); + } + // in the case of recieving this, we assume the watch does, in fact, need weather data window.localStorage.setItem('disable_weather', 'no'); weather.updateWeather(); @@ -244,6 +307,17 @@ Pebble.addEventListener('webviewclosed', function (e) { } } + // remote battery endpoint settings + if (configData.remote_endpoint_url) { + remoteEndpointUrl = configData.remote_endpoint_url; + window.localStorage.setItem('remote_endpoint_url', configData.remote_endpoint_url); + } + + if (configData.remote_endpoint_token) { + remoteEndpointToken = configData.remote_endpoint_token; + window.localStorage.setItem('remote_endpoint_token', configData.remote_endpoint_token); + } + // determine whether or not the weather checking should be enabled var disableWeather; From 4aa00316951981936f84513f4a64b60e4e83b206 Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Fri, 22 May 2026 22:46:38 +0200 Subject: [PATCH 2/8] Add config UI for remote battery endpoint - Create config directory with HTML files for different platforms - Add remote endpoint URL and token input fields - Update CONFIG_VERSION to 10 - Set BASE_CONFIG_URL to placeholder for custom hosting - Config files support: aplite, basalt, chalk, diorite, emery --- config/config_aplite.html | 60 ++++++++++++++++++++++++++++++++++++++ config/config_basalt.html | 60 ++++++++++++++++++++++++++++++++++++++ config/config_chalk.html | 60 ++++++++++++++++++++++++++++++++++++++ config/config_diorite.html | 60 ++++++++++++++++++++++++++++++++++++++ config/config_emery.html | 60 ++++++++++++++++++++++++++++++++++++++ src/pkjs/index.js | 6 ++-- 6 files changed, 304 insertions(+), 2 deletions(-) create mode 100644 config/config_aplite.html create mode 100644 config/config_basalt.html create mode 100644 config/config_chalk.html create mode 100644 config/config_diorite.html create mode 100644 config/config_emery.html diff --git a/config/config_aplite.html b/config/config_aplite.html new file mode 100644 index 00000000..f86ffc90 --- /dev/null +++ b/config/config_aplite.html @@ -0,0 +1,60 @@ + + + + + + TimeStyle Settings + + + + +

TimeStyle Settings

+
+

Remote Battery Sync

+
+ Send battery status updates to a remote HTTP endpoint (e.g., Home Assistant webhook). Leave empty to disable. +
+ + + + + + + +
+ +

Other Settings

+

For full configuration options, please use the official config page at freakified.github.io

+
+ + + + + + + diff --git a/config/config_basalt.html b/config/config_basalt.html new file mode 100644 index 00000000..f86ffc90 --- /dev/null +++ b/config/config_basalt.html @@ -0,0 +1,60 @@ + + + + + + TimeStyle Settings + + + + +

TimeStyle Settings

+
+

Remote Battery Sync

+
+ Send battery status updates to a remote HTTP endpoint (e.g., Home Assistant webhook). Leave empty to disable. +
+ + + + + + + +
+ +

Other Settings

+

For full configuration options, please use the official config page at freakified.github.io

+
+ + + + + + + diff --git a/config/config_chalk.html b/config/config_chalk.html new file mode 100644 index 00000000..f86ffc90 --- /dev/null +++ b/config/config_chalk.html @@ -0,0 +1,60 @@ + + + + + + TimeStyle Settings + + + + +

TimeStyle Settings

+
+

Remote Battery Sync

+
+ Send battery status updates to a remote HTTP endpoint (e.g., Home Assistant webhook). Leave empty to disable. +
+ + + + + + + +
+ +

Other Settings

+

For full configuration options, please use the official config page at freakified.github.io

+
+ + + + + + + diff --git a/config/config_diorite.html b/config/config_diorite.html new file mode 100644 index 00000000..f86ffc90 --- /dev/null +++ b/config/config_diorite.html @@ -0,0 +1,60 @@ + + + + + + TimeStyle Settings + + + + +

TimeStyle Settings

+
+

Remote Battery Sync

+
+ Send battery status updates to a remote HTTP endpoint (e.g., Home Assistant webhook). Leave empty to disable. +
+ + + + + + + +
+ +

Other Settings

+

For full configuration options, please use the official config page at freakified.github.io

+
+ + + + + + + diff --git a/config/config_emery.html b/config/config_emery.html new file mode 100644 index 00000000..f86ffc90 --- /dev/null +++ b/config/config_emery.html @@ -0,0 +1,60 @@ + + + + + + TimeStyle Settings + + + + +

TimeStyle Settings

+
+

Remote Battery Sync

+
+ Send battery status updates to a remote HTTP endpoint (e.g., Home Assistant webhook). Leave empty to disable. +
+ + + + + + + +
+ +

Other Settings

+

For full configuration options, please use the official config page at freakified.github.io

+
+ + + + + + + diff --git a/src/pkjs/index.js b/src/pkjs/index.js index e29a5652..f63cef14 100755 --- a/src/pkjs/index.js +++ b/src/pkjs/index.js @@ -1,9 +1,11 @@ var weather = require('./weather'); -var CONFIG_VERSION = 9; +var CONFIG_VERSION = 10; // var BASE_CONFIG_URL = 'http://localhost:3001/'; -var BASE_CONFIG_URL = 'http://freakified.github.io/TimeStylePebble/'; +// var BASE_CONFIG_URL = 'http://freakified.github.io/TimeStylePebble/'; +// Update this URL to point to your hosted config files (see /config/ directory) +var BASE_CONFIG_URL = 'http://YOUR_CONFIG_HOST_HERE/'; // Remote battery endpoint configuration var remoteEndpointUrl = ''; From 0ed3732b36a2cadef1eda52005ae1de029bc7b01 Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Fri, 22 May 2026 22:49:33 +0200 Subject: [PATCH 3/8] Add GitHub Actions workflow to deploy full config UI - Create workflow to sync config from freakified/TimeStylePebble - Automatically add battery sync fields to config_common_options.html - Deploy config to GitHub Pages - Update BASE_CONFIG_URL to use GitHub Pages - Remove simplified config files (now handled by workflow) --- .github/workflows/deploy-config.yml | 83 +++++++++++++++++++++++++++++ config/config_aplite.html | 60 --------------------- config/config_basalt.html | 60 --------------------- config/config_chalk.html | 60 --------------------- config/config_diorite.html | 60 --------------------- config/config_emery.html | 60 --------------------- src/pkjs/index.js | 4 +- 7 files changed, 85 insertions(+), 302 deletions(-) create mode 100644 .github/workflows/deploy-config.yml delete mode 100644 config/config_aplite.html delete mode 100644 config/config_basalt.html delete mode 100644 config/config_chalk.html delete mode 100644 config/config_diorite.html delete mode 100644 config/config_emery.html diff --git a/.github/workflows/deploy-config.yml b/.github/workflows/deploy-config.yml new file mode 100644 index 00000000..18db5905 --- /dev/null +++ b/.github/workflows/deploy-config.yml @@ -0,0 +1,83 @@ +name: Deploy Config UI + +on: + push: + branches: [ battery-reporting ] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build-and-deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout main repo + uses: actions/checkout@v4 + with: + path: main-repo + + - name: Checkout freakified config + uses: actions/checkout@v4 + with: + repository: freakified/TimeStylePebble + ref: gh-pages + path: config-source + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Copy and modify config files + run: | + mkdir -p main-repo/config + + # Copy all config files + cp config-source/config_*.html main-repo/config/ + cp -r config-source/_includes main-repo/config/ + cp -r config-source/_layouts main-repo/config/ + cp -r config-source/images main-repo/config/ + cp config-source/*.html main-repo/config/ 2>/dev/null || true + + # Add battery sync section to config_common_options.html + if [ -f "main-repo/config/_includes/config_common_options.html" ]; then + cat >> main-repo/config/_includes/config_common_options.html << 'EOF' +
+
+ + + +
+ + +EOF + fi + + - name: Update BASE_CONFIG_URL in index.js + run: | + # Update BASE_CONFIG_URL to point to this repo's GitHub Pages + sed -i "s|http://YOUR_CONFIG_HOST_HERE/|https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/|g" main-repo/src/pkjs/index.js + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: main-repo/config + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/config/config_aplite.html b/config/config_aplite.html deleted file mode 100644 index f86ffc90..00000000 --- a/config/config_aplite.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - TimeStyle Settings - - - - -

TimeStyle Settings

-
-

Remote Battery Sync

-
- Send battery status updates to a remote HTTP endpoint (e.g., Home Assistant webhook). Leave empty to disable. -
- - - - - - - -
- -

Other Settings

-

For full configuration options, please use the official config page at freakified.github.io

-
- - - - - - - diff --git a/config/config_basalt.html b/config/config_basalt.html deleted file mode 100644 index f86ffc90..00000000 --- a/config/config_basalt.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - TimeStyle Settings - - - - -

TimeStyle Settings

-
-

Remote Battery Sync

-
- Send battery status updates to a remote HTTP endpoint (e.g., Home Assistant webhook). Leave empty to disable. -
- - - - - - - -
- -

Other Settings

-

For full configuration options, please use the official config page at freakified.github.io

-
- - - - - - - diff --git a/config/config_chalk.html b/config/config_chalk.html deleted file mode 100644 index f86ffc90..00000000 --- a/config/config_chalk.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - TimeStyle Settings - - - - -

TimeStyle Settings

-
-

Remote Battery Sync

-
- Send battery status updates to a remote HTTP endpoint (e.g., Home Assistant webhook). Leave empty to disable. -
- - - - - - - -
- -

Other Settings

-

For full configuration options, please use the official config page at freakified.github.io

-
- - - - - - - diff --git a/config/config_diorite.html b/config/config_diorite.html deleted file mode 100644 index f86ffc90..00000000 --- a/config/config_diorite.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - TimeStyle Settings - - - - -

TimeStyle Settings

-
-

Remote Battery Sync

-
- Send battery status updates to a remote HTTP endpoint (e.g., Home Assistant webhook). Leave empty to disable. -
- - - - - - - -
- -

Other Settings

-

For full configuration options, please use the official config page at freakified.github.io

-
- - - - - - - diff --git a/config/config_emery.html b/config/config_emery.html deleted file mode 100644 index f86ffc90..00000000 --- a/config/config_emery.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - TimeStyle Settings - - - - -

TimeStyle Settings

-
-

Remote Battery Sync

-
- Send battery status updates to a remote HTTP endpoint (e.g., Home Assistant webhook). Leave empty to disable. -
- - - - - - - -
- -

Other Settings

-

For full configuration options, please use the official config page at freakified.github.io

-
- - - - - - - diff --git a/src/pkjs/index.js b/src/pkjs/index.js index f63cef14..0f0f8dd1 100755 --- a/src/pkjs/index.js +++ b/src/pkjs/index.js @@ -4,8 +4,8 @@ var weather = require('./weather'); var CONFIG_VERSION = 10; // var BASE_CONFIG_URL = 'http://localhost:3001/'; // var BASE_CONFIG_URL = 'http://freakified.github.io/TimeStylePebble/'; -// Update this URL to point to your hosted config files (see /config/ directory) -var BASE_CONFIG_URL = 'http://YOUR_CONFIG_HOST_HERE/'; +// Config files are deployed to GitHub Pages by workflow +var BASE_CONFIG_URL = 'https://caco3.github.io/TimeStylePebble/'; // Remote battery endpoint configuration var remoteEndpointUrl = ''; From f7cde6a8c5928e3faca3096134b09bc09c152f59 Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Fri, 22 May 2026 22:51:14 +0200 Subject: [PATCH 4/8] Fix YAML syntax error in workflow (heredoc delimiter) --- .github/workflows/deploy-config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-config.yml b/.github/workflows/deploy-config.yml index 18db5905..c6442c02 100644 --- a/.github/workflows/deploy-config.yml +++ b/.github/workflows/deploy-config.yml @@ -51,7 +51,7 @@ jobs: # Add battery sync section to config_common_options.html if [ -f "main-repo/config/_includes/config_common_options.html" ]; then - cat >> main-repo/config/_includes/config_common_options.html << 'EOF' + cat >> main-repo/config/_includes/config_common_options.html << 'ENDOFFILE'