mirror of
https://github.com/house-of-abbey/GarminHomeAssistant.git
synced 2025-06-16 11:28:40 +00:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
8c5aa820ef | |||
a13f04fa6c | |||
143bcf08a7 | |||
ee3b2abed2 | |||
44d5bf8e93 | |||
fae2241f01 | |||
42e89906f6 | |||
8c0540ee45 |
@ -222,3 +222,5 @@ When you change the JSON file defining your dashboard, you must exit the applica
|
||||
| 1.3 | Tap for scripts was working in emulation but not on some phones. Decision is to make the 'service' field in the JSON compulsory for 'tap' menu items. This is a breaking change, but for many might be a fix for something not working correctly. Improve language support, we can now accept language corrections and prevent the automated translation of strings from clobbering manually refined entries. Thank you to two new contributors. |
|
||||
| 1.4 | New lean user Interface with thanks to [SomeoneOnEarth](https://github.com/Someone0nEarth) for their contribution which is now the default. If you prefer the old style you can still select it in the settings. The provision of a 'service' tag is now not just heavily suggested by the JSON schema, it is enforced in code. With apologies to anyone suffering a breakage as a result. |
|
||||
| 1.5 | <img src="images/confirmation_view.jpg" width="200" title="Confirmation View" style="float:right"/> Added an optional confirmation dialogue view to prevent accidental execution of actions on mistaken tap. This also brings a change in the JSON schema to allow an optional field to specify that the confirmation should be used for a menu item. As we are now maturing and adding features we have decided to mitigate breaking changes to the JSON schema by being more careful to adopt the Home Assistant schema (noting there is a 1:1 mapping between YAML and JSON). This change does deprecate the top level `service` tag in favour of `tag_action` containing multiple fields including `service` & `confirm`. Users should migrate to the new format for the new functionality, but the timescale for actual deprecation are long and undecided. |
|
||||
| 1.6 | Added a user configurable 'timeout' in seconds so that when no action is taken the application automatically closes, stopping the continuous polling for changes of status and hence saving the drain on the battery. This can be disabled with timeout=0. |
|
||||
| 1.7 | Added timeout to confirmation views so that when used for security devices it does not linger when left unconfirmed. Thanks to [Jan Schneider](https://github.com/j-a-n) for the contribution. Known bug for devices not supporting [`WatchUi.getCurrentView()`](https://developer.garmin.com/connect-iq/api-docs/Toybox/WatchUi.html#getCurrentView-instance_function) API call which is only available on API Level 3.4.0, e.g. Vivoactive 4S. |
|
||||
|
@ -24,7 +24,20 @@
|
||||
<!-- Best be a public URL in order to work away from your home LAN and have a trusted HTTPS certificate -->
|
||||
<property id="config_url" type="string"></property>
|
||||
|
||||
<!--
|
||||
Application timeout in seconds, except 0 for no timeout (default). After this amount of elapsed time
|
||||
with no activity, exit the application.
|
||||
-->
|
||||
<property id="app_timeout" type="number">0</property>
|
||||
|
||||
<!--
|
||||
After this time (in seconds), a confirmation dialog for an action is automatically closed and the action is cancelled.
|
||||
Set to 0 to disable the timeout. The default value is 3 seconds.
|
||||
-->
|
||||
<property id="confirm_timeout" type="number">3</property>
|
||||
|
||||
<property id="types_representation" type="boolean"></property>
|
||||
|
||||
<property id="menu_alignment" type="boolean"></property>
|
||||
|
||||
</properties>
|
||||
|
@ -43,6 +43,26 @@
|
||||
/>
|
||||
</setting>
|
||||
|
||||
<setting
|
||||
propertyKey="@Properties.app_timeout"
|
||||
title="Timeout in seconds. Exit the application after this period of inactivity to save the device battery."
|
||||
>
|
||||
<settingConfig
|
||||
type="numeric"
|
||||
min="0"
|
||||
/>
|
||||
</setting>
|
||||
|
||||
<setting
|
||||
propertyKey="@Properties.confirm_timeout"
|
||||
title="After this time (in seconds), a confirmation dialog for an action is automatically closed and the action is cancelled. Set to 0 to disable the timeout."
|
||||
>
|
||||
<settingConfig
|
||||
type="numeric"
|
||||
min="0"
|
||||
/>
|
||||
</setting>
|
||||
|
||||
<setting
|
||||
propertyKey="@Properties.types_representation"
|
||||
title="Representing types with icons (off) or with labels (on)"
|
||||
@ -60,4 +80,5 @@
|
||||
type="boolean"
|
||||
/>
|
||||
</setting>
|
||||
|
||||
</settings>
|
||||
|
@ -132,11 +132,13 @@ class AlertDelegate extends WatchUi.InputDelegate {
|
||||
|
||||
function onKey(evt) {
|
||||
mView.dismiss();
|
||||
getApp().getQuitTimer().reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
function onTap(evt) {
|
||||
mView.dismiss();
|
||||
getApp().getQuitTimer().reset();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +82,7 @@ class ErrorDelegate extends WatchUi.BehaviorDelegate {
|
||||
WatchUi.BehaviorDelegate.initialize();
|
||||
}
|
||||
function onBack() {
|
||||
getApp().getQuitTimer().reset();
|
||||
WatchUi.popView(WatchUi.SLIDE_DOWN);
|
||||
return true;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ using Toybox.Application.Properties;
|
||||
|
||||
class HomeAssistantApp extends Application.AppBase {
|
||||
private var mHaMenu;
|
||||
private var quitTimer as QuitTimer;
|
||||
private var strNoApiKey as Lang.String;
|
||||
private var strNoApiUrl as Lang.String;
|
||||
private var strNoConfigUrl as Lang.String;
|
||||
@ -52,14 +53,18 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
strConfigUrlNotFound = WatchUi.loadResource($.Rez.Strings.ConfigUrlNotFound);
|
||||
strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr);
|
||||
strTrailingSlashErr = WatchUi.loadResource($.Rez.Strings.TrailingSlashErr);
|
||||
quitTimer = new QuitTimer();
|
||||
}
|
||||
|
||||
// onStart() is called on application start up
|
||||
function onStart(state as Lang.Dictionary?) as Void {
|
||||
quitTimer.begin();
|
||||
}
|
||||
|
||||
// onStop() is called when your application is exiting
|
||||
function onStop(state as Lang.Dictionary?) as Void {}
|
||||
function onStop(state as Lang.Dictionary?) as Void {
|
||||
quitTimer.stop();
|
||||
}
|
||||
|
||||
// Return the initial view of your application here
|
||||
function getInitialView() as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>? {
|
||||
@ -174,6 +179,10 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
mNextItemToUpdate = (mNextItemToUpdate + 1) % itu.size();
|
||||
}
|
||||
|
||||
function getQuitTimer() as QuitTimer{
|
||||
return quitTimer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getApp() as HomeAssistantApp {
|
||||
|
@ -22,9 +22,10 @@ using Toybox.Lang;
|
||||
// Required for callback method definition
|
||||
typedef Method as Toybox.Lang.Method;
|
||||
using Toybox.WatchUi;
|
||||
using Toybox.Timer;
|
||||
using Toybox.Application.Properties;
|
||||
|
||||
class HomeAssistantConfirmation extends WatchUi.Confirmation {
|
||||
|
||||
function initialize() {
|
||||
WatchUi.Confirmation.initialize(WatchUi.loadResource($.Rez.Strings.Confirm));
|
||||
}
|
||||
@ -33,16 +34,31 @@ class HomeAssistantConfirmation extends WatchUi.Confirmation {
|
||||
|
||||
class HomeAssistantConfirmationDelegate extends WatchUi.ConfirmationDelegate {
|
||||
private var confirmMethod;
|
||||
private var timeout;
|
||||
|
||||
function initialize(callback as Method() as Void) {
|
||||
WatchUi.ConfirmationDelegate.initialize();
|
||||
confirmMethod = callback;
|
||||
var timeoutSeconds = Properties.getValue("confirm_timeout") as Lang.Number;
|
||||
if (timeoutSeconds > 0) {
|
||||
timeout = new Timer.Timer();
|
||||
timeout.start(method(:onTimeout), timeoutSeconds * 1000, true);
|
||||
}
|
||||
}
|
||||
|
||||
function onResponse(response) as Lang.Boolean {
|
||||
getApp().getQuitTimer().reset();
|
||||
if (timeout) {
|
||||
timeout.stop();
|
||||
}
|
||||
if (response == WatchUi.CONFIRM_YES) {
|
||||
confirmMethod.invoke();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function onTimeout() as Void {
|
||||
timeout.stop();
|
||||
WatchUi.popView(WatchUi.SLIDE_RIGHT);
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,23 @@ class HomeAssistantViewDelegate extends WatchUi.Menu2InputDelegate {
|
||||
Menu2InputDelegate.initialize();
|
||||
}
|
||||
|
||||
function onBack() {
|
||||
getApp().getQuitTimer().reset();
|
||||
WatchUi.popView(WatchUi.SLIDE_RIGHT);
|
||||
}
|
||||
|
||||
// Only for CheckboxMenu
|
||||
function onDone() {
|
||||
getApp().getQuitTimer().reset();
|
||||
}
|
||||
|
||||
// Only for CustomMenu
|
||||
function onFooter() {
|
||||
getApp().getQuitTimer().reset();
|
||||
}
|
||||
|
||||
function onSelect(item as WatchUi.MenuItem) as Void {
|
||||
getApp().getQuitTimer().reset();
|
||||
if (item instanceof HomeAssistantToggleMenuItem) {
|
||||
var haToggleItem = item as HomeAssistantToggleMenuItem;
|
||||
if (Globals.scDebug) {
|
||||
@ -147,8 +163,9 @@ class HomeAssistantViewDelegate extends WatchUi.Menu2InputDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
function onBack() {
|
||||
WatchUi.popView(WatchUi.SLIDE_RIGHT);
|
||||
// Only for CustomMenu
|
||||
function onTitle() {
|
||||
getApp().getQuitTimer().reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
56
source/QuitTimer.mc
Normal file
56
source/QuitTimer.mc
Normal file
@ -0,0 +1,56 @@
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// Distributed under MIT Licence
|
||||
// See https://github.com/house-of-abbey/GarminHomeAssistant/blob/main/LICENSE.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// GarminHomeAssistant is a Garmin IQ application written in Monkey C and routinely
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// J D Abbey & P A Abbey, 28 December 2022
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Quit the application after a period of inactivity in order to save the battery.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
using Toybox.Lang;
|
||||
using Toybox.Timer;
|
||||
using Toybox.Application.Properties;
|
||||
using Toybox.WatchUi;
|
||||
|
||||
class QuitTimer extends Timer.Timer {
|
||||
private var api_timeout;
|
||||
|
||||
function initialize() {
|
||||
Timer.Timer.initialize();
|
||||
// Timer needs delay in milliseconds.
|
||||
api_timeout = (Properties.getValue("app_timeout") as Lang.Number) * 1000;
|
||||
}
|
||||
|
||||
function exitApp() as Void {
|
||||
if (Globals.scDebug) {
|
||||
System.println("QuitTimer exitApp(): Exiting");
|
||||
}
|
||||
// This will exit the system cleanly from any point within an app.
|
||||
System.exit();
|
||||
}
|
||||
|
||||
function begin() {
|
||||
if (api_timeout > 0) {
|
||||
start(method(:exitApp), api_timeout, false);
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
if (Globals.scDebug) {
|
||||
System.println("QuitTimer reset(): Restarted quit timer");
|
||||
}
|
||||
stop();
|
||||
begin();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user