Compare commits

...

3 Commits

Author SHA1 Message Date
Philip Abbey
c1cddc54e4 Initial attempt
Lacking an end to end test on this code presently.
2025-08-08 11:40:13 +01:00
Philip Abbey
8a8d64bcab Update Wi-Fi.md
Videos only work when they are uploaded to https://github.com/user-attachments/assets/, so that means drag and drop the video into the markdown file rather than reference one already in your source tree.

Signed-off-by: Philip Abbey <philipabbey@users.noreply.github.com>
2025-07-25 18:42:37 +01:00
Philip Abbey
55bbb4901c Update HISTORY.md
Amended v3.0 change text.

Signed-off-by: Philip Abbey <philipabbey@users.noreply.github.com>
2025-07-25 12:32:27 +01:00
12 changed files with 81 additions and 29 deletions

View File

@@ -45,4 +45,4 @@
| 2.30 | <img src="images/Venu2_glance_default.png" width="200" title="Default Glance"/><br/>Extensive re-work of the [Glance](examples/Glance.md) view, including the ability to customise it with a user supplied template. |
| 2.31 | Adding [two new options](./examples/Actions.md#exit-on-tap) to the menu items: 1) The ability to disable a menu item, e.g. temporarily for seasonal changes, 2) The option to exit after a menu item has been select. |
| 2.32 | Bug fix for a breaking change extracting options caused by the need to rearrange function parameters for an [annoying compiler error](https://github.com/house-of-abbey/GarminHomeAssistant/issues/253). |
| 3.0 | First version with the ability to use [Wi-Fi](Wi-Fi.md) instead of Bluetooth but with limited functionality. |
| 3.0 | First version with the ability to use [Wi-Fi or LTE](Wi-Fi.md) instead of Bluetooth but with limited functionality, thanks to [@vincentezw](https://github.com/vincentezw). |

View File

@@ -20,9 +20,7 @@ With version 3.0 onwards the application now includes the ability to temporarily
This video using will hopefully make it obvious how slow it is to use the Wi-Fi option and illustrate the cautionary notes above.
<video width="100%" controls style="max-width:250px">
<source src="./images/wi-fi.mp4" type="video/mp4">
</video>
https://github.com/user-attachments/assets/269981e9-12dc-44f2-a28f-b8e844b2b2f8
### Please Note
@@ -30,4 +28,4 @@ We emphasize that the Wi-Fi/LTE functionality should be viewed as a 'last resort
## Credits
With thanks to [@vincentezw](https://github.com/vincentezw) for contributing this solution.
With thanks to [@vincentezw](https://github.com/vincentezw) for contributing this solution.

View File

@@ -94,6 +94,20 @@
-->
<property id="battery_level_refresh_rate" type="number">15</property>
<!--
A user specified HTTP header key to be used in all HTTP requests.
This is useful for some Home Assistant installations that require a
custom HTTP header.
-->
<property id="user_http_header_key" type="string"></property>
<!--
A user specified HTTP header value to be used in all HTTP requests.
This is useful for some Home Assistant installations that require a
custom HTTP header.
-->
<property id="user_http_header_value" type="string"></property>
<!--
The webhook ID is the last part of the webhook URL. It is secret and
should not be shared. It will not be set in settings but will be

View File

@@ -119,6 +119,22 @@
<settingConfig type="numeric" min="5" />
</setting>
<group id="userHttpHeader" title="@Strings.SettingsUserHttpHeader" description="@Strings.SettingsUserHttpHeaderDescription">
<setting
propertyKey="@Properties.user_http_header_key"
title="@Strings.SettingsUserHttpHeaderKey"
>
<settingConfig type="alphaNumeric" />
</setting>
<setting
propertyKey="@Properties.user_http_header_value"
title="@Strings.SettingsUserHttpHeaderValue"
>
<settingConfig type="alphaNumeric" />
</setting>
</group>
<setting
propertyKey="@Properties.webhook_id"
title="@Strings.WebhookId"

View File

@@ -57,6 +57,9 @@
<string id="SettingsConfigUrl">URL for menu configuration (JSON).</string>
<string id="SettingsCacheConfig">Should the application cache the menu configuration?</string>
<string id="SettingsClearCache">Should the application clear the existing cache next time it is started?</string>
<string id="WifiLteExecution">Wi-Fi/LTE execution mode.</string>
<string id="WifiLteExecutionEnable">Enable executing commands over Wi-Fi/LTE.</string>
<string id="WifiLteExecutionDescription">Allows the app to start without phone connection (when menu is cached), and prompt to execute command over Wi-Fi/LTE.</string>
<string id="SettingsVibration">Should the application provide feedback via vibrations?</string>
<string id="SettingsAppTimeout">Timeout in seconds. Exit the application after this period of inactivity to save the device battery.</string>
<string id="SettingsPollDelay">Additional poll delay (in seconds). Adds a delay between the status update of all menu items.</string>
@@ -69,8 +72,9 @@
<string id="SettingsWidgetStart">(Widget only) Automatically start the application from the widget without waiting for a tap.</string>
<string id="SettingsEnableBatteryLevel">Enable the background service to send the device battery level, location and (if supported) activity data to Home Assistant.</string>
<string id="SettingsBatteryLevelRefreshRate">The refresh rate (in minutes) at which the background service should repeat sending data.</string>
<string id="SettingsUserHttpHeader">User supplied HTTP header</string>
<string id="SettingsUserHttpHeaderDescription">Some Home Assistant installations require the specification of a custom HTTP header in order to function.</string>
<string id="SettingsUserHttpHeaderKey">User supplied HTTP header key.</string>
<string id="SettingsUserHttpHeaderValue">User supplied HTTP header value.</string>
<string id="WebhookId">(Read only) The Webhook ID created by the device for background service updates. You might require this for debugging.</string>
<string id="WifiLteExecution">Wi-Fi/LTE execution mode.</string>
<string id="WifiLteExecutionEnable">Enable executing commands over Wi-Fi/LTE.</string>
<string id="WifiLteExecutionDescription">Allows the app to start without phone connection (when menu is cached), and prompt to execute command over Wi-Fi/LTE.</string>
</strings>

View File

@@ -158,9 +158,9 @@ class BackgroundServiceDelegate extends System.ServiceDelegate {
},
{
:method => Communications.HTTP_REQUEST_METHOD_POST,
:headers => {
:headers => Settings.augmentHttpHeaders({
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON
},
}),
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
},
method(:onReturnDoUpdate)
@@ -244,9 +244,9 @@ class BackgroundServiceDelegate extends System.ServiceDelegate {
},
{
:method => Communications.HTTP_REQUEST_METHOD_POST,
:headers => {
:headers => Settings.augmentHttpHeaders({
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON
},
}),
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
},
method(:onReturnDoUpdate)

View File

@@ -287,7 +287,8 @@ class HomeAssistantApp extends Application.AppBase {
null,
{
:method => Communications.HTTP_REQUEST_METHOD_GET,
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON,
:headers => Settings.augmentHttpHeaders({})
},
method(:onReturnFetchMenuConfig)
);
@@ -501,9 +502,9 @@ class HomeAssistantApp extends Application.AppBase {
},
{
:method => Communications.HTTP_REQUEST_METHOD_POST,
:headers => {
:headers => Settings.augmentHttpHeaders({
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON
},
}),
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
},
method(:onReturnUpdateMenuItems)
@@ -619,9 +620,9 @@ class HomeAssistantApp extends Application.AppBase {
null,
{
:method => Communications.HTTP_REQUEST_METHOD_GET,
:headers => {
:headers => Settings.augmentHttpHeaders({
"Authorization" => "Bearer " + Settings.getApiKey()
},
}),
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
},
method(:onReturnFetchApiStatus)
@@ -714,9 +715,9 @@ class HomeAssistantApp extends Application.AppBase {
},
{
:method => Communications.HTTP_REQUEST_METHOD_POST,
:headers => {
:headers => Settings.augmentHttpHeaders({
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON
},
}),
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
},
method(:onReturnFetchGlanceContent)

View File

@@ -168,10 +168,10 @@ class HomeAssistantService {
data, // Includes {"entity_id": xxxx}
{
:method => Communications.HTTP_REQUEST_METHOD_POST,
:headers => {
:headers => Settings.augmentHttpHeaders({
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON,
"Authorization" => "Bearer " + Settings.getApiKey()
},
}),
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON,
:context => {
:entity_id => entity_id,

View File

@@ -81,10 +81,10 @@ class HomeAssistantSyncDelegate extends Communications.SyncDelegate {
data, // May include {"entity_id": xxxx} for service calls
{
:method => Communications.HTTP_REQUEST_METHOD_POST,
:headers => {
:headers => Settings.augmentHttpHeaders({
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON,
"Authorization" => "Bearer " + Settings.getApiKey()
},
}),
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON,
},
method(:haCallback)

View File

@@ -268,10 +268,10 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
mData,
{
:method => Communications.HTTP_REQUEST_METHOD_POST,
:headers => {
:headers => Settings.augmentHttpHeaders({
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON,
"Authorization" => "Bearer " + Settings.getApiKey()
},
}),
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
},
method(:onReturnSetState)

View File

@@ -47,6 +47,10 @@ class Settings {
private static var mIsSensorsLevelEnabled as Lang.Boolean = false;
//! minutes
private static var mBatteryRefreshRate as Lang.Number = 15;
//! Additional user configurable HTTP header key
private static var mUserHeaderKey as Lang.String = "";
//! Additional user configurable HTTP header value
private static var mUserHeaderValue as Lang.String = "";
private static var mIsApp as Lang.Boolean = false;
private static var mHasService as Lang.Boolean = false;
//! Must keep the object so it doesn't get garbage collected.
@@ -71,6 +75,8 @@ class Settings {
mMenuAlignment = Properties.getValue("menu_alignment");
mIsSensorsLevelEnabled = Properties.getValue("enable_battery_level");
mBatteryRefreshRate = Properties.getValue("battery_level_refresh_rate");
mUserHeaderKey = Properties.getValue("user_http_header_key");
mUserHeaderValue = Properties.getValue("user_http_header_value");
}
//! A webhook is required for non-privileged API calls.
@@ -284,4 +290,17 @@ class Settings {
}
}
//! Augment the HTTP header options passed in with the user configurable HTTP header key and value.
//!
//! @param options The HTTP header options to augment.
//!
//! @return The augmented HTTP header options.
//
static function augmentHttpHeaders(options as Lang.Dictionary) {
if (mUserHeaderKey != null && mUserHeaderKey != "" && mUserHeaderValue != null && mUserHeaderValue != "") {
options[mUserHeaderKey] = mUserHeaderValue;
}
return options;
}
}

View File

@@ -113,10 +113,10 @@ class WebhookManager {
},
{
:method => Communications.HTTP_REQUEST_METHOD_POST,
:headers => {
:headers => Settings.augmentHttpHeaders({
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON,
"Authorization" => "Bearer " + Settings.getApiKey()
},
}),
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
},
method(:onReturnRequestWebhookId)
@@ -230,9 +230,9 @@ class WebhookManager {
},
{
:method => Communications.HTTP_REQUEST_METHOD_POST,
:headers => {
:headers => Settings.augmentHttpHeaders({
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON
},
}),
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON,
:context => sensors.slice(1, null)
},