Compare commits

...

3 Commits

Author SHA1 Message Date
Philip Abbey
46e44ada30 Update README.md
Added link to Github issues.
2025-09-08 21:43:05 +01:00
Philip Abbey
960a069d99 Fixes (#282)
Fixes
2025-09-07 16:56:37 +01:00
Philip Abbey
c78ca4c318 Fixes 2025-09-07 14:43:18 +01:00
3 changed files with 33 additions and 25 deletions

View File

@@ -327,6 +327,8 @@ The `id` attribute values are taken from the same names used in [`strings.xml`](
## Known Issues ## Known Issues
Check the latest unresolved [issues](https://github.com/house-of-abbey/GarminHomeAssistant/issues) on Github. Otherwise the following are persistent issues with no realistic resolution.
1. There are some cases where the file format may be valid JSON, but invalid against the schema, and the failure to catch this error could cause the application to crash. Whilst we have taken care to manage many issues, there may still be cases that are uncaught. Please verify your JSON schema, see the [trouble shooting guide](TroubleShooting.md). 1. There are some cases where the file format may be valid JSON, but invalid against the schema, and the failure to catch this error could cause the application to crash. Whilst we have taken care to manage many issues, there may still be cases that are uncaught. Please verify your JSON schema, see the [trouble shooting guide](TroubleShooting.md).
2. On some (old) devices (e.g. Vivoactive 3, Fenix 5s & Edge 520+), the menu does not update correctly to reflect changes in state effected by an external Home Assistant control. E.g. when the phone application changes the toggle status of a switch, the Garmin application does not reflect that change until the menu is touched or scrolled a little. This is a [known issue](https://forums.garmin.com/developer/connect-iq/i/bug-reports/menu2-doesn-t-allow-live-updates) already reported without a suggested software fix. 2. On some (old) devices (e.g. Vivoactive 3, Fenix 5s & Edge 520+), the menu does not update correctly to reflect changes in state effected by an external Home Assistant control. E.g. when the phone application changes the toggle status of a switch, the Garmin application does not reflect that change until the menu is touched or scrolled a little. This is a [known issue](https://forums.garmin.com/developer/connect-iq/i/bug-reports/menu2-doesn-t-allow-live-updates) already reported without a suggested software fix.

View File

@@ -38,11 +38,11 @@ class HomeAssistantApp extends Application.AppBase {
private var mUpdateTimer as Timer.Timer?; private var mUpdateTimer as Timer.Timer?;
// Array initialised by onReturnFetchMenuConfig() // Array initialised by onReturnFetchMenuConfig()
private var mItemsToUpdate as Lang.Array<HomeAssistantToggleMenuItem or HomeAssistantTapMenuItem or HomeAssistantGroupMenuItem>?; private var mItemsToUpdate as Lang.Array<HomeAssistantToggleMenuItem or HomeAssistantTapMenuItem or HomeAssistantGroupMenuItem>?;
private var mIsApp as Lang.Boolean = false; // Or Widget private var mIsApp as Lang.Boolean = false; // Or Widget
private var mUpdating as Lang.Boolean = false; // Don't start a second chain of updates private var mUpdating as Lang.Boolean = false; // Don't start a second chain of updates
private var mTemplates as Lang.Dictionary = {}; private var mTemplates as Lang.Dictionary? = null; // Cache of compiled templates
private var mNotifiedNoBle as Lang.Boolean = false; private var mNotifiedNoBle as Lang.Boolean = false;
private var mIsCacheChecked as Lang.Boolean = false; private var mIsCacheChecked as Lang.Boolean = false;
//! Class Constructor //! Class Constructor
// //
@@ -358,12 +358,12 @@ class HomeAssistantApp extends Application.AppBase {
// //
function glanceTemplate(menu as Lang.Dictionary) { function glanceTemplate(menu as Lang.Dictionary) {
if (menu != null) { if (menu != null) {
if (menu.get("glance") != null) { if (menu["glance"] != null) {
var glance = menu.get("glance") as Lang.Dictionary; var glance = menu["glance"] as Lang.Dictionary;
if (glance.get("type").equals("info")) { if (glance["type"].equals("info")) {
mGlanceTemplate = glance.get("content") as Lang.String; mGlanceTemplate = glance["content"] as Lang.String;
// System.println("HomeAssistantApp glanceTemplate() " + mGlanceTemplate); // System.println("HomeAssistantApp glanceTemplate() " + mGlanceTemplate);
} else { // if glance.get("type").equals("status") } else { // if glance["type"].equals("status")
mGlanceTemplate = null; mGlanceTemplate = null;
} }
} }
@@ -391,8 +391,8 @@ class HomeAssistantApp extends Application.AppBase {
if (!b.hasKey(key)) { if (!b.hasKey(key)) {
return false; return false;
} }
var valA = a.get(key); var valA = a[key];
var valB = b.get(key); var valB = b[key];
if (valA == null && valB == null) { if (valA == null && valB == null) {
// both null, consider true // both null, consider true
} else if (valA == null || valB == null) { } else if (valA == null || valB == null) {
@@ -425,25 +425,26 @@ class HomeAssistantApp extends Application.AppBase {
if (a.size() != b.size()) { if (a.size() != b.size()) {
return false; return false;
} }
for (var j = 0; j < a.size(); j++) { for (var i = 0; i < a.size(); i++) {
var itemA = a[j]; var itemA = a[i];
var itemB = b[j]; var itemB = b[i];
if (itemA == null && itemB == null) { if (itemA == null && itemB == null) {
// both null, consider true // Both null, consider true
} else if (itemA == null || itemB == null) { } else if (itemA == null || itemB == null) {
return false; return false;
} else if (itemA instanceof Lang.Dictionary and itemB instanceof Lang.Dictionary) { } else if (itemA instanceof Lang.Dictionary and itemB instanceof Lang.Dictionary) {
if (!structuralEquals(itemA, itemB)) { if (!structuralEquals(itemA, itemB)) {
return false; return false;
} }
} else if (valA instanceof Lang.Array and valB instanceof Lang.Array) { } else if (itemA instanceof Lang.Array and itemB instanceof Lang.Array) {
if (!arrayEquals(valA, valB)) { if (!arrayEquals(itemA, itemB)) {
return false; return false;
} }
} else if (!itemA.equals(itemB)) { } else if (!itemA.equals(itemB)) {
return false; return false;
} }
} }
return true;
} }
//! Callback function for the menu check GET request. //! Callback function for the menu check GET request.
@@ -601,10 +602,12 @@ class HomeAssistantApp extends Application.AppBase {
if (mItemsToUpdate != null) { if (mItemsToUpdate != null) {
for (var i = 0; i < mItemsToUpdate.size(); i++) { for (var i = 0; i < mItemsToUpdate.size(); i++) {
var item = mItemsToUpdate[i]; var item = mItemsToUpdate[i];
var state = data.get(i.toString()); var state = data[i.toString()];
item.updateState(state); if (item.getTemplate() != null) {
item.updateState(state);
}
if (item instanceof HomeAssistantToggleMenuItem) { if (item instanceof HomeAssistantToggleMenuItem) {
(item as HomeAssistantToggleMenuItem).updateToggleState(data.get(i.toString() + "t")); (item as HomeAssistantToggleMenuItem).updateToggleState(data[i.toString() + "t"]);
} }
} }
if (Settings.getCacheConfig() && !mIsCacheChecked) { if (Settings.getCacheConfig() && !mIsCacheChecked) {
@@ -681,7 +684,7 @@ class HomeAssistantApp extends Application.AppBase {
mItemsToUpdate = mHaMenu.getItemsToUpdate(); mItemsToUpdate = mHaMenu.getItemsToUpdate();
mTemplates = {}; mTemplates = {};
for (var i = 0; i < mItemsToUpdate.size(); i++) { for (var i = 0; i < mItemsToUpdate.size(); i++) {
var item = mItemsToUpdate[i]; var item = mItemsToUpdate[i];
var template = item.getTemplate(); var template = item.getTemplate();
if (template != null) { if (template != null) {
mTemplates.put(i.toString(), { mTemplates.put(i.toString(), {
@@ -767,7 +770,7 @@ class HomeAssistantApp extends Application.AppBase {
break; break;
case 200: case 200:
if ((data != null) && data.get("message").equals("API running.")) { if ((data != null) && (data instanceof Lang.Dictionary) && data["message"].equals("API running.")) {
mApiStatus = WatchUi.loadResource($.Rez.Strings.Available) as Lang.String; mApiStatus = WatchUi.loadResource($.Rez.Strings.Available) as Lang.String;
} else { } else {
if (mIsApp) { if (mIsApp) {
@@ -883,8 +886,8 @@ class HomeAssistantApp extends Application.AppBase {
break; break;
case 200: case 200:
if (data != null) { if ((data != null) && (data instanceof Lang.Dictionary)) {
mGlanceText = data.get("glanceTemplate"); mGlanceText = data["glanceTemplate"];
} }
break; break;

View File

@@ -136,6 +136,9 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
setUiToggle(data); setUiToggle(data);
if (mTemplate == null and data.equals("unavailable")) { if (mTemplate == null and data.equals("unavailable")) {
setSubLabel($.Rez.Strings.Unavailable); setSubLabel($.Rez.Strings.Unavailable);
} else {
// Needed to revert the sub-label when the entity becomes available again.
setSubLabel(null);
} }
} else if(data instanceof Lang.Dictionary) { } else if(data instanceof Lang.Dictionary) {
// System.println("HomeAssistantToggleMenuItem updateState() data = " + data); // System.println("HomeAssistantToggleMenuItem updateState() data = " + data);