Merge branch 'main' into json-schema-update

This commit is contained in:
Philip Abbey
2025-11-01 19:03:34 +00:00
committed by GitHub
10 changed files with 66 additions and 16 deletions

View File

@@ -51,4 +51,4 @@
| 3.3 | Providing automatic detection for menu definition updates, but still requires an application restart. | | 3.3 | Providing automatic detection for menu definition updates, but still requires an application restart. |
| 3.4 | Fixed a bug where templates failed to display in toggle menu items (at least on some devices). Fixed a bug where a menu item requesting to exit on completion appeared to indicate failure when using Wi-Fi or LTE. The fix uses a delay in exiting the application modelled as sufficient for a Venu 2 device, so this might need tweaking for other devices. Attempt to fixed an "Out of Memory" bug caused by v3.3 by making automatic checking for menu updates both optional and automatically turned off when insufficient memory is available. This last bug is device dependent and may require another attempt. Internationalisation improvements with thanks to [@krzys_h](https://github.com/krzys-h) for a new automated translations script. | | 3.4 | Fixed a bug where templates failed to display in toggle menu items (at least on some devices). Fixed a bug where a menu item requesting to exit on completion appeared to indicate failure when using Wi-Fi or LTE. The fix uses a delay in exiting the application modelled as sufficient for a Venu 2 device, so this might need tweaking for other devices. Attempt to fixed an "Out of Memory" bug caused by v3.3 by making automatic checking for menu updates both optional and automatically turned off when insufficient memory is available. This last bug is device dependent and may require another attempt. Internationalisation improvements with thanks to [@krzys_h](https://github.com/krzys-h) for a new automated translations script. |
| 3.5 | Added support for Edge 550, 850 & MTB, Fenix 8 Pro 47mm, GPSMAP H1, Instinct Crossover AMOLED, Venu 4 41mm & 45mm, & Venu X1 devices which also required an SDK update to 8.3.0. The simulation of the Edge 850 device was off, as it failed to update the display and text was the wrong colour, but the buttons menu items operated HA correctly. The assumption is the simulation model is buggy until someone [reports](https://github.com/house-of-abbey/GarminHomeAssistant/issues) otherwise. | | 3.5 | Added support for Edge 550, 850 & MTB, Fenix 8 Pro 47mm, GPSMAP H1, Instinct Crossover AMOLED, Venu 4 41mm & 45mm, & Venu X1 devices which also required an SDK update to 8.3.0. The simulation of the Edge 850 device was off, as it failed to update the display and text was the wrong colour, but the buttons menu items operated HA correctly. The assumption is the simulation model is buggy until someone [reports](https://github.com/house-of-abbey/GarminHomeAssistant/issues) otherwise. |
| 3.6 | Added `numeric` menu item type thanks to [@thmichel](https://github.com/thmichel). This allows you to select a numeric value to set for an entity. | | 3.6 | Added `numeric` menu item type thanks to [@thmichel](https://github.com/thmichel). This allows you to select a numeric value to set for an entity. Confirmations can now display a user supplied message. |

View File

@@ -233,6 +233,7 @@ This allows the `confirm` and `pin` fields to be accommodated in the `tap_action
* [Switches](examples/Switches.md) * [Switches](examples/Switches.md)
* [Actions](examples/Actions.md) * [Actions](examples/Actions.md)
* [Templates](examples/Templates.md) * [Templates](examples/Templates.md)
* [Numeric](examples/Numeric.md)
## Editing the JSON file ## Editing the JSON file

View File

@@ -968,10 +968,10 @@
"type": "string" "type": "string"
}, },
"confirm": { "confirm": {
"type": "boolean", "type": ["boolean", "string"],
"default": false, "default": false,
"title": "Confirmation", "title": "Confirmation",
"description": "Optional confirmation of the action before execution as a precaution." "description": "Optional confirmation of the action before execution as a precaution. Use a Boolean for the default message. Specify a string to display a specific confirmation message."
}, },
"pin": { "pin": {
"type": "boolean", "type": "boolean",

View File

@@ -37,6 +37,14 @@ For example:
"confirm": true "confirm": true
} }
} }
```
The `confirm` field may contain a string instead of a Boolean in order to provide a custom message to display instead of the default "Sure?" text.
```json
"tap_action": {
"confirm": "Toggle the cover?"
}
``` ```
**The authors do not advise the use of this application for security sensitive devices. But we suspect users are taking that risk anyway, hence a PIN confirmation is provided that can be used for additional menu item security.** **The authors do not advise the use of this application for security sensitive devices. But we suspect users are taking that risk anyway, hence a PIN confirmation is provided that can be used for additional menu item security.**

View File

@@ -112,6 +112,30 @@ For copy and paste, the Jinja2 fields are as follows:
{{ not is_state('media_player.amplifier','unavailable') }} {{ not is_state('media_player.amplifier','unavailable') }}
``` ```
As an alternative to using the GUI, the following can be pasted into Home Assistant's `configuration.yaml`:
```yaml
template:
- number:
- name: "Amplifier dB"
unique_id: "<Generate Unique ID>"
unit_of_measurement: "dB"
state: "{{ state_attr('media_player.amplifier','volume_level') * 100 -80 }}"
availability: "{{ not is_state('media_player.amplifier','unavailable') }}"
set_value:
- action: media_player.volume_set
target:
entity_id: media_player.amplifier
data:
volume_level: "{{ (value+80)/100 }}"
step: 0.5
min: -60
max: -15
icon: mdi:audio-video
```
We noticed some schema checking errors when we tried this, but the YAML above is consistent with the HA [Template](https://www.home-assistant.io/integrations/template/#number) support pages, and this code does correctly create the number template as required.
The JSON menu definition can now use dB with the new template number as follows. The JSON menu definition can now use dB with the new template number as follows.
```json ```json
@@ -136,4 +160,4 @@ The JSON menu definition can now use dB with the new template number as follows.
Specific to this menu item: Specific to this menu item:
1. If the number picker does not initialise with the correct value, amend the `attribute` field. Just because your template renders does not mean the application has extracted the numeric valueas the `content` template is rendered on the Home Assistant server. 1. If the number picker does not initialise with the correct value, amend the `attribute` field. Just because your template renders does not mean the application has extracted the numeric value as the `content` template is rendered on the Home Assistant server.

View File

@@ -24,10 +24,13 @@ class HomeAssistantConfirmation extends WatchUi.Confirmation {
//! Class Constructor //! Class Constructor
// //
function initialize() { function initialize(message as Lang.String?) {
WatchUi.Confirmation.initialize(WatchUi.loadResource($.Rez.Strings.Confirm) as Lang.String); if (message == null) {
WatchUi.Confirmation.initialize(WatchUi.loadResource($.Rez.Strings.Confirm) as Lang.String);
} else {
WatchUi.Confirmation.initialize(message);
}
} }
} }
//! Delegate to respond to the confirmation request. //! Delegate to respond to the confirmation request.

View File

@@ -23,7 +23,7 @@ using Toybox.Graphics;
class HomeAssistantNumericMenuItem extends HomeAssistantMenuItem { class HomeAssistantNumericMenuItem extends HomeAssistantMenuItem {
private var mHomeAssistantService as HomeAssistantService?; private var mHomeAssistantService as HomeAssistantService?;
private var mService as Lang.String?; private var mService as Lang.String?;
private var mConfirm as Lang.Boolean; private var mConfirm as Lang.Boolean or Lang.String or Null;
private var mExit as Lang.Boolean; private var mExit as Lang.Boolean;
private var mPin as Lang.Boolean; private var mPin as Lang.Boolean;
private var mData as Lang.Dictionary?; private var mData as Lang.Dictionary?;
@@ -127,7 +127,12 @@ class HomeAssistantNumericMenuItem extends HomeAssistantMenuItem {
WatchUi.SLIDE_LEFT WatchUi.SLIDE_LEFT
); );
} else { } else {
var view = new HomeAssistantConfirmation(); var view;
if (mConfirm instanceof Lang.String) {
view = new HomeAssistantConfirmation(mConfirm as Lang.String?);
} else {
view = new HomeAssistantConfirmation(null);
}
WatchUi.pushView( WatchUi.pushView(
view, view,
new HomeAssistantConfirmationDelegate({ new HomeAssistantConfirmationDelegate({

View File

@@ -22,7 +22,7 @@ using Toybox.Graphics;
class HomeAssistantTapMenuItem extends HomeAssistantMenuItem { class HomeAssistantTapMenuItem extends HomeAssistantMenuItem {
private var mHomeAssistantService as HomeAssistantService; private var mHomeAssistantService as HomeAssistantService;
private var mService as Lang.String?; private var mService as Lang.String?;
private var mConfirm as Lang.Boolean; private var mConfirm as Lang.Boolean or Lang.String or Null;
private var mExit as Lang.Boolean; private var mExit as Lang.Boolean;
private var mPin as Lang.Boolean; private var mPin as Lang.Boolean;
private var mData as Lang.Dictionary?; private var mData as Lang.Dictionary?;
@@ -95,8 +95,7 @@ class HomeAssistantTapMenuItem extends HomeAssistantMenuItem {
if ((! System.getDeviceSettings().phoneConnected || if ((! System.getDeviceSettings().phoneConnected ||
! System.getDeviceSettings().connectionAvailable) && ! System.getDeviceSettings().connectionAvailable) &&
Settings.getWifiLteExecutionEnabled()) { Settings.getWifiLteExecutionEnabled()) {
var dialogMsg = WatchUi.loadResource($.Rez.Strings.WifiLtePrompt) as Lang.String; var dialog = new WatchUi.Confirmation(WatchUi.loadResource($.Rez.Strings.WifiLtePrompt) as Lang.String);
var dialog = new WatchUi.Confirmation(dialogMsg);
WatchUi.pushView( WatchUi.pushView(
dialog, dialog,
new WifiLteExecutionConfirmDelegate({ new WifiLteExecutionConfirmDelegate({
@@ -108,7 +107,12 @@ class HomeAssistantTapMenuItem extends HomeAssistantMenuItem {
WatchUi.SLIDE_LEFT WatchUi.SLIDE_LEFT
); );
} else { } else {
var view = new HomeAssistantConfirmation(); var view;
if (mConfirm instanceof Lang.String) {
view = new HomeAssistantConfirmation(mConfirm as Lang.String?);
} else {
view = new HomeAssistantConfirmation(null);
}
WatchUi.pushView( WatchUi.pushView(
view, view,
new HomeAssistantConfirmationDelegate({ new HomeAssistantConfirmationDelegate({

View File

@@ -25,7 +25,7 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
private var mData as Lang.Dictionary; private var mData as Lang.Dictionary;
private var mTemplate as Lang.String?; private var mTemplate as Lang.String?;
private var mExit as Lang.Boolean; private var mExit as Lang.Boolean;
private var mConfirm as Lang.Boolean; private var mConfirm as Lang.Boolean or Lang.String or Null;
private var mPin as Lang.Boolean; private var mPin as Lang.Boolean;
private var mHasVibrate as Lang.Boolean = false; private var mHasVibrate as Lang.Boolean = false;
@@ -324,7 +324,12 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
Settings.getWifiLteExecutionEnabled()) { Settings.getWifiLteExecutionEnabled()) {
wifiPrompt(b); wifiPrompt(b);
} else { } else {
var confirmationView = new HomeAssistantConfirmation(); var confirmationView;
if (mConfirm instanceof Lang.String) {
confirmationView = new HomeAssistantConfirmation(mConfirm as Lang.String?);
} else {
confirmationView = new HomeAssistantConfirmation(null);
}
WatchUi.pushView( WatchUi.pushView(
confirmationView, confirmationView,
new HomeAssistantConfirmationDelegate({ new HomeAssistantConfirmationDelegate({

View File

@@ -48,7 +48,7 @@ class HomeAssistantView extends WatchUi.Menu2 {
var entity = items[i].get("entity") as Lang.String?; var entity = items[i].get("entity") as Lang.String?;
var tap_action = items[i].get("tap_action") as Lang.Dictionary?; var tap_action = items[i].get("tap_action") as Lang.Dictionary?;
var service = items[i].get("service") as Lang.String?; // Deprecated schema var service = items[i].get("service") as Lang.String?; // Deprecated schema
var confirm = false as Lang.Boolean?; var confirm = false as Lang.Boolean or Lang.String or Null;
var pin = false as Lang.Boolean?; var pin = false as Lang.Boolean?;
var data = null as Lang.Dictionary?; var data = null as Lang.Dictionary?;
var enabled = true as Lang.Boolean?; var enabled = true as Lang.Boolean?;