From 7ffbd84785dd92ce2a889038f9b05fb3bad1362d Mon Sep 17 00:00:00 2001 From: Philip Abbey Date: Wed, 17 Jan 2024 23:31:27 +0000 Subject: [PATCH 1/5] Initial working version --- resources-icons-18/drawables.xml | 1 + resources-icons-18/info_type.svg | 1 + resources-icons-21/drawables.xml | 1 + resources-icons-21/info_type.svg | 1 + resources-icons-24/drawables.xml | 1 + resources-icons-24/info_type.svg | 1 + resources-icons-26/drawables.xml | 1 + resources-icons-26/info_type.svg | 1 + resources-icons-28/drawables.xml | 1 + resources-icons-28/info_type.svg | 1 + resources-icons-30/drawables.xml | 1 + resources-icons-30/info_type.svg | 1 + resources-icons-32/drawables.xml | 1 + resources-icons-32/info_type.svg | 1 + resources-icons-38/drawables.xml | 1 + resources-icons-38/info_type.svg | 1 + resources-icons-42/drawables.xml | 1 + resources-icons-42/info_type.svg | 1 + resources-icons-46/drawables.xml | 1 + resources-icons-46/info_type.svg | 1 + resources-icons-48/drawables.xml | 1 + resources-icons-48/info_type.svg | 1 + resources-icons-53/drawables.xml | 1 + resources-icons-53/info_type.svg | 1 + source/HomeAssistantMenuItem.mc | 11 +++++-- source/HomeAssistantMenuItemFactory.mc | 39 +++++++++++++++++++++++-- source/HomeAssistantService.mc | 18 ++++++++---- source/HomeAssistantTemplateMenuItem.mc | 17 ++++++++--- source/HomeAssistantView.mc | 17 +++++++---- 29 files changed, 106 insertions(+), 20 deletions(-) create mode 100644 resources-icons-18/info_type.svg create mode 100644 resources-icons-21/info_type.svg create mode 100644 resources-icons-24/info_type.svg create mode 100644 resources-icons-26/info_type.svg create mode 100644 resources-icons-28/info_type.svg create mode 100644 resources-icons-30/info_type.svg create mode 100644 resources-icons-32/info_type.svg create mode 100644 resources-icons-38/info_type.svg create mode 100644 resources-icons-42/info_type.svg create mode 100644 resources-icons-46/info_type.svg create mode 100644 resources-icons-48/info_type.svg create mode 100644 resources-icons-53/info_type.svg diff --git a/resources-icons-18/drawables.xml b/resources-icons-18/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-18/drawables.xml +++ b/resources-icons-18/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-18/info_type.svg b/resources-icons-18/info_type.svg new file mode 100644 index 0000000..50db92a --- /dev/null +++ b/resources-icons-18/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-21/drawables.xml b/resources-icons-21/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-21/drawables.xml +++ b/resources-icons-21/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-21/info_type.svg b/resources-icons-21/info_type.svg new file mode 100644 index 0000000..d9d5806 --- /dev/null +++ b/resources-icons-21/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-24/drawables.xml b/resources-icons-24/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-24/drawables.xml +++ b/resources-icons-24/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-24/info_type.svg b/resources-icons-24/info_type.svg new file mode 100644 index 0000000..f8e316c --- /dev/null +++ b/resources-icons-24/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-26/drawables.xml b/resources-icons-26/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-26/drawables.xml +++ b/resources-icons-26/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-26/info_type.svg b/resources-icons-26/info_type.svg new file mode 100644 index 0000000..4e5492d --- /dev/null +++ b/resources-icons-26/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-28/drawables.xml b/resources-icons-28/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-28/drawables.xml +++ b/resources-icons-28/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-28/info_type.svg b/resources-icons-28/info_type.svg new file mode 100644 index 0000000..a2acf01 --- /dev/null +++ b/resources-icons-28/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-30/drawables.xml b/resources-icons-30/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-30/drawables.xml +++ b/resources-icons-30/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-30/info_type.svg b/resources-icons-30/info_type.svg new file mode 100644 index 0000000..65fc0b8 --- /dev/null +++ b/resources-icons-30/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-32/drawables.xml b/resources-icons-32/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-32/drawables.xml +++ b/resources-icons-32/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-32/info_type.svg b/resources-icons-32/info_type.svg new file mode 100644 index 0000000..427d108 --- /dev/null +++ b/resources-icons-32/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-38/drawables.xml b/resources-icons-38/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-38/drawables.xml +++ b/resources-icons-38/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-38/info_type.svg b/resources-icons-38/info_type.svg new file mode 100644 index 0000000..9aa14b3 --- /dev/null +++ b/resources-icons-38/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-42/drawables.xml b/resources-icons-42/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-42/drawables.xml +++ b/resources-icons-42/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-42/info_type.svg b/resources-icons-42/info_type.svg new file mode 100644 index 0000000..087960e --- /dev/null +++ b/resources-icons-42/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-46/drawables.xml b/resources-icons-46/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-46/drawables.xml +++ b/resources-icons-46/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-46/info_type.svg b/resources-icons-46/info_type.svg new file mode 100644 index 0000000..3c9329a --- /dev/null +++ b/resources-icons-46/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-48/drawables.xml b/resources-icons-48/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-48/drawables.xml +++ b/resources-icons-48/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-48/info_type.svg b/resources-icons-48/info_type.svg new file mode 100644 index 0000000..9825159 --- /dev/null +++ b/resources-icons-48/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources-icons-53/drawables.xml b/resources-icons-53/drawables.xml index d560ef6..33c0707 100644 --- a/resources-icons-53/drawables.xml +++ b/resources-icons-53/drawables.xml @@ -19,4 +19,5 @@ + diff --git a/resources-icons-53/info_type.svg b/resources-icons-53/info_type.svg new file mode 100644 index 0000000..d8ec47d --- /dev/null +++ b/resources-icons-53/info_type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/HomeAssistantMenuItem.mc b/source/HomeAssistantMenuItem.mc index ce0330f..5bcf623 100644 --- a/source/HomeAssistantMenuItem.mc +++ b/source/HomeAssistantMenuItem.mc @@ -26,6 +26,7 @@ class HomeAssistantMenuItem extends WatchUi.IconMenuItem { private var mHomeAssistantService as HomeAssistantService; private var mService as Lang.String; private var mConfirm as Lang.Boolean; + private var mData as Lang.Dictionary or Null; function initialize( label as Lang.String or Lang.Symbol, @@ -33,6 +34,7 @@ class HomeAssistantMenuItem extends WatchUi.IconMenuItem { identifier as Lang.Object or Null, service as Lang.String or Null, confirm as Lang.Boolean, + data as Lang.Dictionary or Null, icon as Graphics.BitmapType or WatchUi.Drawable, options as { :alignment as WatchUi.MenuItem.Alignment @@ -48,9 +50,14 @@ class HomeAssistantMenuItem extends WatchUi.IconMenuItem { ); mHomeAssistantService = haService; - mIdentifier = identifier; mService = service; mConfirm = confirm; + mData = data; + if (mData == null) { + mData = {"entity_id" => identifier}; + } else { + mData.put("entity_id", identifier); + } } function callService() as Void { @@ -66,7 +73,7 @@ class HomeAssistantMenuItem extends WatchUi.IconMenuItem { } function onConfirm() as Void { - mHomeAssistantService.call(mIdentifier as Lang.String, mService); + mHomeAssistantService.call(mIdentifier as Lang.String, mService, mData); } } diff --git a/source/HomeAssistantMenuItemFactory.mc b/source/HomeAssistantMenuItemFactory.mc index 2ff7fb0..76437a1 100644 --- a/source/HomeAssistantMenuItemFactory.mc +++ b/source/HomeAssistantMenuItemFactory.mc @@ -26,6 +26,7 @@ class HomeAssistantMenuItemFactory { private var mMenuItemOptions as Lang.Dictionary; private var mTapTypeIcon as WatchUi.Bitmap; private var mGroupTypeIcon as WatchUi.Bitmap; + private var mInfoTypeIcon as WatchUi.Bitmap; private var mHomeAssistantService as HomeAssistantService; private static var instance; @@ -47,6 +48,12 @@ class HomeAssistantMenuItemFactory { :locY => WatchUi.LAYOUT_VALIGN_CENTER }); + mInfoTypeIcon = new WatchUi.Bitmap({ + :rezId => $.Rez.Drawables.InfoTypeIcon, + :locX => WatchUi.LAYOUT_HALIGN_CENTER, + :locY => WatchUi.LAYOUT_VALIGN_CENTER + }); + mHomeAssistantService = new HomeAssistantService(); } @@ -67,12 +74,13 @@ class HomeAssistantMenuItemFactory { ); } - function template( + function template_tap( label as Lang.String or Lang.Symbol, identifier as Lang.Object or Null, template as Lang.String or Null, service as Lang.String or Null, - confirm as Lang.Boolean + confirm as Lang.Boolean, + data as Lang.Dictionary or Null ) as WatchUi.MenuItem { return new HomeAssistantTemplateMenuItem( label, @@ -80,6 +88,29 @@ class HomeAssistantMenuItemFactory { template, service, confirm, + data, + mTapTypeIcon, + mMenuItemOptions, + mHomeAssistantService + ); + } + + function template_notap( + label as Lang.String or Lang.Symbol, + identifier as Lang.Object or Null, + template as Lang.String or Null, + service as Lang.String or Null, + confirm as Lang.Boolean, + data as Lang.Dictionary or Null + ) as WatchUi.MenuItem { + return new HomeAssistantTemplateMenuItem( + label, + identifier, + template, + service, + confirm, + data, + mInfoTypeIcon, mMenuItemOptions, mHomeAssistantService ); @@ -89,7 +120,8 @@ class HomeAssistantMenuItemFactory { label as Lang.String or Lang.Symbol, identifier as Lang.Object or Null, service as Lang.String or Null, - confirm as Lang.Boolean + confirm as Lang.Boolean, + data as Lang.Dictionary or Null ) as WatchUi.MenuItem { return new HomeAssistantMenuItem( label, @@ -97,6 +129,7 @@ class HomeAssistantMenuItemFactory { identifier, service, confirm, + data, mTapTypeIcon, mMenuItemOptions, mHomeAssistantService diff --git a/source/HomeAssistantService.mc b/source/HomeAssistantService.mc index 77b4996..19af6d9 100644 --- a/source/HomeAssistantService.mc +++ b/source/HomeAssistantService.mc @@ -27,7 +27,7 @@ class HomeAssistantService { private var mHasToast as Lang.Boolean = false; private var mHasVibrate as Lang.Boolean = false; - function initialise() { + function initialize() { if (WatchUi has :showToast) { mHasToast = true; } @@ -38,7 +38,11 @@ class HomeAssistantService { // Callback function after completing the POST request to call a service. // - function onReturnCall(responseCode as Lang.Number, data as Null or Lang.Dictionary or Lang.String, context as Lang.Object) as Void { + function onReturnCall( + responseCode as Lang.Number, + data as Null or Lang.Dictionary or Lang.String, + context as Lang.Object + ) as Void { var identifier = context as Lang.String; if (Globals.scDebug) { System.println("HomeAssistantService onReturnCall() Response Code: " + responseCode); @@ -120,7 +124,11 @@ class HomeAssistantService { } } - function call(identifier as Lang.String, service as Lang.String) as Void { + function call( + identifier as Lang.String, + service as Lang.String, + data as Lang.Dictionary or Null + ) as Void { if (! System.getDeviceSettings().phoneConnected) { if (Globals.scDebug) { System.println("HomeAssistantService call(): No Phone connection, skipping API call."); @@ -140,9 +148,7 @@ class HomeAssistantService { } Communications.makeWebRequest( url, - { - "entity_id" => identifier - }, + data, // Includes {"entity_id": identifier} { :method => Communications.HTTP_REQUEST_METHOD_POST, :headers => { diff --git a/source/HomeAssistantTemplateMenuItem.mc b/source/HomeAssistantTemplateMenuItem.mc index c8ba460..f2a8555 100644 --- a/source/HomeAssistantTemplateMenuItem.mc +++ b/source/HomeAssistantTemplateMenuItem.mc @@ -26,11 +26,12 @@ using Toybox.Lang; using Toybox.WatchUi; using Toybox.Graphics; -class HomeAssistantTemplateMenuItem extends WatchUi.MenuItem { +class HomeAssistantTemplateMenuItem extends WatchUi.IconMenuItem { private var mHomeAssistantService as HomeAssistantService; private var mTemplate as Lang.String; private var mService as Lang.String or Null; private var mConfirm as Lang.Boolean; + private var mData as Lang.Dictionary or Null; function initialize( label as Lang.String or Lang.Symbol, @@ -38,16 +39,18 @@ class HomeAssistantTemplateMenuItem extends WatchUi.MenuItem { template as Lang.String, service as Lang.String or Null, confirm as Lang.Boolean, + data as Lang.Dictionary or Null, + icon as Graphics.BitmapType or WatchUi.Drawable, options as { :alignment as WatchUi.MenuItem.Alignment, - :icon as Graphics.BitmapType or WatchUi.Drawable or Lang.Symbol } or Null, haService as HomeAssistantService ) { - WatchUi.MenuItem.initialize( + WatchUi.IconMenuItem.initialize( label, null, identifier, + icon, options ); @@ -55,6 +58,12 @@ class HomeAssistantTemplateMenuItem extends WatchUi.MenuItem { mTemplate = template; mService = service; mConfirm = confirm; + mData = data; + if (mData == null) { + mData = {"entity_id" => identifier}; + } else { + mData.put("entity_id", identifier); + } } function callService() as Void { @@ -71,7 +80,7 @@ class HomeAssistantTemplateMenuItem extends WatchUi.MenuItem { function onConfirm() as Void { if (mService != null) { - mHomeAssistantService.call(mIdentifier as Lang.String, mService); + mHomeAssistantService.call(mIdentifier as Lang.String, mService, mData); } } diff --git a/source/HomeAssistantView.mc b/source/HomeAssistantView.mc index 1a65c98..df70ccd 100644 --- a/source/HomeAssistantView.mc +++ b/source/HomeAssistantView.mc @@ -51,11 +51,13 @@ class HomeAssistantView extends WatchUi.Menu2 { var content = items[i].get("content") as Lang.String or Null; var entity = items[i].get("entity") as Lang.String or Null; var tap_action = items[i].get("tap_action") as Lang.Dictionary or Null; - var service = items[i].get("service") as Lang.String or Null; - var confirm = false as Lang.Boolean; + var service = items[i].get("service") as Lang.String or Null; // Deprecated schema + var confirm = false as Lang.Boolean or Null; + var data = null as Lang.Dictionary or Null; if (tap_action != null) { service = tap_action.get("service"); - confirm = tap_action.get("confirm"); + confirm = tap_action.get("confirm"); // Optional + data = tap_action.get("data"); // Optional if (confirm == null) { confirm = false; } @@ -64,9 +66,14 @@ class HomeAssistantView extends WatchUi.Menu2 { if (type.equals("toggle") && entity != null) { addItem(HomeAssistantMenuItemFactory.create().toggle(name, entity)); } else if (type.equals("template") && content != null) { - addItem(HomeAssistantMenuItemFactory.create().template(name, entity, content, service, confirm)); + if (tap_action == null) { + addItem(HomeAssistantMenuItemFactory.create().template_notap(name, entity, content, service, confirm, data)); + } else { + addItem(HomeAssistantMenuItemFactory.create().template_tap(name, entity, content, service, confirm, data)); + } + } else if (type.equals("tap") && entity != null && service != null) { - addItem(HomeAssistantMenuItemFactory.create().tap(name, entity, service, confirm)); + addItem(HomeAssistantMenuItemFactory.create().tap(name, entity, service, confirm, data)); } else if (type.equals("group")) { addItem(HomeAssistantMenuItemFactory.create().group(items[i])); } From 4e96036d66b510e393c8f42bded7d674c8636880 Mon Sep 17 00:00:00 2001 From: Philip Abbey Date: Thu, 18 Jan 2024 21:15:59 +0000 Subject: [PATCH 2/5] Removed code to dismiss the ErrorView The automatic ErrorView.unShow() when the HTTP Request callback success was preventing errors being read. Removing to see if they are really required. --- source/HomeAssistantTemplateMenuItem.mc | 1 - source/HomeAssistantToggleMenuItem.mc | 1 - 2 files changed, 2 deletions(-) diff --git a/source/HomeAssistantTemplateMenuItem.mc b/source/HomeAssistantTemplateMenuItem.mc index f2a8555..71dc398 100644 --- a/source/HomeAssistantTemplateMenuItem.mc +++ b/source/HomeAssistantTemplateMenuItem.mc @@ -154,7 +154,6 @@ class HomeAssistantTemplateMenuItem extends WatchUi.IconMenuItem { status = RezStrings.getAvailable(); setSubLabel(data); requestUpdate(); - ErrorView.unShow(); // Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer. getApp().updateNextMenuItem(); break; diff --git a/source/HomeAssistantToggleMenuItem.mc b/source/HomeAssistantToggleMenuItem.mc index 497dd75..ee0f388 100644 --- a/source/HomeAssistantToggleMenuItem.mc +++ b/source/HomeAssistantToggleMenuItem.mc @@ -143,7 +143,6 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { setLabel((data.get("attributes") as Lang.Dictionary).get("friendly_name") as Lang.String); } setUiToggle(state); - ErrorView.unShow(); // Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer. getApp().updateNextMenuItem(); break; From a48c6a38fe6d688b756733026ba7ecbdd2c7e961 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Thu, 18 Jan 2024 21:17:54 +0000 Subject: [PATCH 3/5] Restyled by whitespace --- resources-icons-18/info_type.svg | 2 +- resources-icons-21/info_type.svg | 2 +- resources-icons-24/info_type.svg | 2 +- resources-icons-26/info_type.svg | 2 +- resources-icons-28/info_type.svg | 2 +- resources-icons-30/info_type.svg | 2 +- resources-icons-32/info_type.svg | 2 +- resources-icons-38/info_type.svg | 2 +- resources-icons-42/info_type.svg | 2 +- resources-icons-46/info_type.svg | 2 +- resources-icons-48/info_type.svg | 2 +- resources-icons-53/info_type.svg | 2 +- source/HomeAssistantView.mc | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/resources-icons-18/info_type.svg b/resources-icons-18/info_type.svg index 50db92a..3d05232 100644 --- a/resources-icons-18/info_type.svg +++ b/resources-icons-18/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-21/info_type.svg b/resources-icons-21/info_type.svg index d9d5806..4d21404 100644 --- a/resources-icons-21/info_type.svg +++ b/resources-icons-21/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-24/info_type.svg b/resources-icons-24/info_type.svg index f8e316c..cdab733 100644 --- a/resources-icons-24/info_type.svg +++ b/resources-icons-24/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-26/info_type.svg b/resources-icons-26/info_type.svg index 4e5492d..a52188f 100644 --- a/resources-icons-26/info_type.svg +++ b/resources-icons-26/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-28/info_type.svg b/resources-icons-28/info_type.svg index a2acf01..f8a23be 100644 --- a/resources-icons-28/info_type.svg +++ b/resources-icons-28/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-30/info_type.svg b/resources-icons-30/info_type.svg index 65fc0b8..d21f4cf 100644 --- a/resources-icons-30/info_type.svg +++ b/resources-icons-30/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-32/info_type.svg b/resources-icons-32/info_type.svg index 427d108..b62fabe 100644 --- a/resources-icons-32/info_type.svg +++ b/resources-icons-32/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-38/info_type.svg b/resources-icons-38/info_type.svg index 9aa14b3..c1a797a 100644 --- a/resources-icons-38/info_type.svg +++ b/resources-icons-38/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-42/info_type.svg b/resources-icons-42/info_type.svg index 087960e..bd0a6e7 100644 --- a/resources-icons-42/info_type.svg +++ b/resources-icons-42/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-46/info_type.svg b/resources-icons-46/info_type.svg index 3c9329a..7e28228 100644 --- a/resources-icons-46/info_type.svg +++ b/resources-icons-46/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-48/info_type.svg b/resources-icons-48/info_type.svg index 9825159..889ec4b 100644 --- a/resources-icons-48/info_type.svg +++ b/resources-icons-48/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/resources-icons-53/info_type.svg b/resources-icons-53/info_type.svg index d8ec47d..16b10d6 100644 --- a/resources-icons-53/info_type.svg +++ b/resources-icons-53/info_type.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/source/HomeAssistantView.mc b/source/HomeAssistantView.mc index df70ccd..36a3fb4 100644 --- a/source/HomeAssistantView.mc +++ b/source/HomeAssistantView.mc @@ -71,7 +71,7 @@ class HomeAssistantView extends WatchUi.Menu2 { } else { addItem(HomeAssistantMenuItemFactory.create().template_tap(name, entity, content, service, confirm, data)); } - + } else if (type.equals("tap") && entity != null && service != null) { addItem(HomeAssistantMenuItemFactory.create().tap(name, entity, service, confirm, data)); } else if (type.equals("group")) { From 67a5f0a14e910e68208f3380c5e32f03c3213a9d Mon Sep 17 00:00:00 2001 From: Philip Abbey Date: Fri, 19 Jan 2024 16:11:30 +0000 Subject: [PATCH 4/5] Amending naming convention Removing some inconsistencies --- ...ViewMenuItem.mc => HomeAssistantGroupMenuItem.mc} | 12 ++++++++---- source/HomeAssistantMenuItemFactory.mc | 4 ++-- ...istantMenuItem.mc => HomeAssistantTapMenuItem.mc} | 2 +- source/HomeAssistantTemplateMenuItem.mc | 2 +- source/HomeAssistantView.mc | 10 +++++----- 5 files changed, 17 insertions(+), 13 deletions(-) rename source/{HomeAssistantViewMenuItem.mc => HomeAssistantGroupMenuItem.mc} (79%) rename source/{HomeAssistantMenuItem.mc => HomeAssistantTapMenuItem.mc} (97%) diff --git a/source/HomeAssistantViewMenuItem.mc b/source/HomeAssistantGroupMenuItem.mc similarity index 79% rename from source/HomeAssistantViewMenuItem.mc rename to source/HomeAssistantGroupMenuItem.mc index 5a92d55..193a6dc 100644 --- a/source/HomeAssistantViewMenuItem.mc +++ b/source/HomeAssistantGroupMenuItem.mc @@ -14,20 +14,24 @@ // // Description: // -// Menu button with an icon that opens a sub-menu. +// Menu button with an icon that opens a sub-menu, i.e. group. // //----------------------------------------------------------------------------------- using Toybox.Lang; using Toybox.WatchUi; -class HomeAssistantViewMenuItem extends WatchUi.IconMenuItem { +class HomeAssistantGroupMenuItem extends WatchUi.IconMenuItem { private var mMenu as HomeAssistantView; - function initialize(definition as Lang.Dictionary, icon as WatchUi.Drawable, options as { + function initialize( + definition as Lang.Dictionary, + icon as WatchUi.Drawable, + options as { :alignment as WatchUi.MenuItem.Alignment } or Null) { - var label = definition.get("name") as Lang.String; + + var label = definition.get("name") as Lang.String; var identifier = definition.get("entity") as Lang.String; WatchUi.IconMenuItem.initialize( diff --git a/source/HomeAssistantMenuItemFactory.mc b/source/HomeAssistantMenuItemFactory.mc index 76437a1..c8e3114 100644 --- a/source/HomeAssistantMenuItemFactory.mc +++ b/source/HomeAssistantMenuItemFactory.mc @@ -123,7 +123,7 @@ class HomeAssistantMenuItemFactory { confirm as Lang.Boolean, data as Lang.Dictionary or Null ) as WatchUi.MenuItem { - return new HomeAssistantMenuItem( + return new HomeAssistantTapMenuItem( label, null, identifier, @@ -137,6 +137,6 @@ class HomeAssistantMenuItemFactory { } function group(definition as Lang.Dictionary) as WatchUi.MenuItem { - return new HomeAssistantViewMenuItem(definition, mGroupTypeIcon, mMenuItemOptions); + return new HomeAssistantGroupMenuItem(definition, mGroupTypeIcon, mMenuItemOptions); } } diff --git a/source/HomeAssistantMenuItem.mc b/source/HomeAssistantTapMenuItem.mc similarity index 97% rename from source/HomeAssistantMenuItem.mc rename to source/HomeAssistantTapMenuItem.mc index 5bcf623..23a9542 100644 --- a/source/HomeAssistantMenuItem.mc +++ b/source/HomeAssistantTapMenuItem.mc @@ -22,7 +22,7 @@ using Toybox.Lang; using Toybox.WatchUi; using Toybox.Graphics; -class HomeAssistantMenuItem extends WatchUi.IconMenuItem { +class HomeAssistantTapMenuItem extends WatchUi.IconMenuItem { private var mHomeAssistantService as HomeAssistantService; private var mService as Lang.String; private var mConfirm as Lang.Boolean; diff --git a/source/HomeAssistantTemplateMenuItem.mc b/source/HomeAssistantTemplateMenuItem.mc index 71dc398..e53c9c6 100644 --- a/source/HomeAssistantTemplateMenuItem.mc +++ b/source/HomeAssistantTemplateMenuItem.mc @@ -14,7 +14,7 @@ // // Description: // -// Rendering a Home Assistant Template. +// Menu button that renders a Home Assistant Template, and optionally triggers a service. // // Reference: // * https://developers.home-assistant.io/docs/api/rest/ diff --git a/source/HomeAssistantView.mc b/source/HomeAssistantView.mc index 36a3fb4..e31722f 100644 --- a/source/HomeAssistantView.mc +++ b/source/HomeAssistantView.mc @@ -87,7 +87,7 @@ class HomeAssistantView extends WatchUi.Menu2 { var lmi = mItems as Lang.Array; for(var i = 0; i < mItems.size(); i++) { var item = lmi[i]; - if (item instanceof HomeAssistantViewMenuItem) { + if (item instanceof HomeAssistantGroupMenuItem) { fullList.addAll(item.getMenuView().getItemsToUpdate()); } else if (item instanceof HomeAssistantToggleMenuItem) { fullList.add(item); @@ -150,8 +150,8 @@ class HomeAssistantViewDelegate extends WatchUi.Menu2InputDelegate { System.println(haToggleItem.getLabel() + " " + haToggleItem.getId() + " " + haToggleItem.isEnabled()); } haToggleItem.setState(haToggleItem.isEnabled()); - } else if (item instanceof HomeAssistantMenuItem) { - var haItem = item as HomeAssistantMenuItem; + } else if (item instanceof HomeAssistantTapMenuItem) { + var haItem = item as HomeAssistantTapMenuItem; if (Globals.scDebug) { System.println(haItem.getLabel() + " " + haItem.getId()); } @@ -162,8 +162,8 @@ class HomeAssistantViewDelegate extends WatchUi.Menu2InputDelegate { System.println(haItem.getLabel() + " " + haItem.getId()); } haItem.callService(); - } else if (item instanceof HomeAssistantViewMenuItem) { - var haMenuItem = item as HomeAssistantViewMenuItem; + } else if (item instanceof HomeAssistantGroupMenuItem) { + var haMenuItem = item as HomeAssistantGroupMenuItem; if (Globals.scDebug) { System.println("IconMenu: " + haMenuItem.getLabel() + " " + haMenuItem.getId()); } From 2be255bb71f63f735d9274324ba6306f119083eb Mon Sep 17 00:00:00 2001 From: Philip Abbey Date: Fri, 19 Jan 2024 18:04:55 +0000 Subject: [PATCH 5/5] Removal of menu identifiers as not actually required Toggle menu is now consistent with the use of data objects in tap and template. HA 'notify' actions now work. Co-Authored-By: Joseph Abbey --- source/HomeAssistantGroupMenuItem.mc | 7 ++--- source/HomeAssistantMenuItemFactory.mc | 42 ++++++++++++++----------- source/HomeAssistantService.mc | 19 ++++++----- source/HomeAssistantTapMenuItem.mc | 13 ++------ source/HomeAssistantTemplateMenuItem.mc | 12 ++----- source/HomeAssistantToggleMenuItem.mc | 33 +++++++++---------- source/HomeAssistantView.mc | 6 ++-- 7 files changed, 60 insertions(+), 72 deletions(-) diff --git a/source/HomeAssistantGroupMenuItem.mc b/source/HomeAssistantGroupMenuItem.mc index 193a6dc..bf52204 100644 --- a/source/HomeAssistantGroupMenuItem.mc +++ b/source/HomeAssistantGroupMenuItem.mc @@ -31,13 +31,10 @@ class HomeAssistantGroupMenuItem extends WatchUi.IconMenuItem { :alignment as WatchUi.MenuItem.Alignment } or Null) { - var label = definition.get("name") as Lang.String; - var identifier = definition.get("entity") as Lang.String; - WatchUi.IconMenuItem.initialize( - label, + definition.get("name") as Lang.String, + null, null, - identifier, icon, options ); diff --git a/source/HomeAssistantMenuItemFactory.mc b/source/HomeAssistantMenuItemFactory.mc index c8e3114..60cb49c 100644 --- a/source/HomeAssistantMenuItemFactory.mc +++ b/source/HomeAssistantMenuItemFactory.mc @@ -64,27 +64,31 @@ class HomeAssistantMenuItemFactory { return instance; } - function toggle(label as Lang.String or Lang.Symbol, identifier as Lang.Object or Null) as WatchUi.MenuItem { + function toggle(label as Lang.String or Lang.Symbol, entity_id as Lang.String or Null) as WatchUi.MenuItem { return new HomeAssistantToggleMenuItem( label, - null, - identifier, - false, + { "entity_id" => entity_id }, mMenuItemOptions ); } function template_tap( label as Lang.String or Lang.Symbol, - identifier as Lang.Object or Null, + entity as Lang.String or Null, template as Lang.String or Null, service as Lang.String or Null, confirm as Lang.Boolean, data as Lang.Dictionary or Null ) as WatchUi.MenuItem { + if (entity != null) { + if (data == null) { + data = { "entity_id" => entity }; + } else { + data.put("entity_id", entity); + } + } return new HomeAssistantTemplateMenuItem( label, - identifier, template, service, confirm, @@ -96,20 +100,15 @@ class HomeAssistantMenuItemFactory { } function template_notap( - label as Lang.String or Lang.Symbol, - identifier as Lang.Object or Null, - template as Lang.String or Null, - service as Lang.String or Null, - confirm as Lang.Boolean, - data as Lang.Dictionary or Null + label as Lang.String or Lang.Symbol, + template as Lang.String or Null ) as WatchUi.MenuItem { return new HomeAssistantTemplateMenuItem( label, - identifier, template, - service, - confirm, - data, + null, + false, + null, mInfoTypeIcon, mMenuItemOptions, mHomeAssistantService @@ -118,15 +117,20 @@ class HomeAssistantMenuItemFactory { function tap( label as Lang.String or Lang.Symbol, - identifier as Lang.Object or Null, + entity as Lang.String or Null, service as Lang.String or Null, confirm as Lang.Boolean, data as Lang.Dictionary or Null ) as WatchUi.MenuItem { + if (entity != null) { + if (data == null) { + data = { "entity_id" => entity }; + } else { + data.put("entity_id", entity); + } + } return new HomeAssistantTapMenuItem( label, - null, - identifier, service, confirm, data, diff --git a/source/HomeAssistantService.mc b/source/HomeAssistantService.mc index 19af6d9..02e1408 100644 --- a/source/HomeAssistantService.mc +++ b/source/HomeAssistantService.mc @@ -43,7 +43,7 @@ class HomeAssistantService { data as Null or Lang.Dictionary or Lang.String, context as Lang.Object ) as Void { - var identifier = context as Lang.String; + var entity_id = context as Lang.String or Null; if (Globals.scDebug) { System.println("HomeAssistantService onReturnCall() Response Code: " + responseCode); System.println("HomeAssistantService onReturnCall() Response Data: " + data); @@ -99,7 +99,7 @@ class HomeAssistantService { var d = data as Lang.Array; var toast = RezStrings.getExecuted(); for(var i = 0; i < d.size(); i++) { - if ((d[i].get("entity_id") as Lang.String).equals(identifier)) { + if ((d[i].get("entity_id") as Lang.String).equals(entity_id)) { toast = (d[i].get("attributes") as Lang.Dictionary).get("friendly_name") as Lang.String; } } @@ -125,9 +125,8 @@ class HomeAssistantService { } function call( - identifier as Lang.String, - service as Lang.String, - data as Lang.Dictionary or Null + service as Lang.String, + data as Lang.Dictionary or Null ) as Void { if (! System.getDeviceSettings().phoneConnected) { if (Globals.scDebug) { @@ -146,9 +145,15 @@ class HomeAssistantService { System.println("HomeAssistantService call() URL=" + url); System.println("HomeAssistantService call() service=" + service); } + + var entity_id = data.get("entity_id"); + if (entity_id == null) { + entity_id = ""; + } + Communications.makeWebRequest( url, - data, // Includes {"entity_id": identifier} + data, // Includes {"entity_id": xxxx} { :method => Communications.HTTP_REQUEST_METHOD_POST, :headers => { @@ -156,7 +161,7 @@ class HomeAssistantService { "Authorization" => "Bearer " + Settings.getApiKey() }, :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON, - :context => identifier + :context => entity_id }, method(:onReturnCall) ); diff --git a/source/HomeAssistantTapMenuItem.mc b/source/HomeAssistantTapMenuItem.mc index 23a9542..238cce5 100644 --- a/source/HomeAssistantTapMenuItem.mc +++ b/source/HomeAssistantTapMenuItem.mc @@ -30,8 +30,6 @@ class HomeAssistantTapMenuItem extends WatchUi.IconMenuItem { function initialize( label as Lang.String or Lang.Symbol, - subLabel as Lang.String or Lang.Symbol or Null, - identifier as Lang.Object or Null, service as Lang.String or Null, confirm as Lang.Boolean, data as Lang.Dictionary or Null, @@ -43,8 +41,8 @@ class HomeAssistantTapMenuItem extends WatchUi.IconMenuItem { ) { WatchUi.IconMenuItem.initialize( label, - subLabel, - identifier, + null, + null, icon, options ); @@ -53,11 +51,6 @@ class HomeAssistantTapMenuItem extends WatchUi.IconMenuItem { mService = service; mConfirm = confirm; mData = data; - if (mData == null) { - mData = {"entity_id" => identifier}; - } else { - mData.put("entity_id", identifier); - } } function callService() as Void { @@ -73,7 +66,7 @@ class HomeAssistantTapMenuItem extends WatchUi.IconMenuItem { } function onConfirm() as Void { - mHomeAssistantService.call(mIdentifier as Lang.String, mService, mData); + mHomeAssistantService.call(mService, mData); } } diff --git a/source/HomeAssistantTemplateMenuItem.mc b/source/HomeAssistantTemplateMenuItem.mc index e53c9c6..e617237 100644 --- a/source/HomeAssistantTemplateMenuItem.mc +++ b/source/HomeAssistantTemplateMenuItem.mc @@ -35,21 +35,20 @@ class HomeAssistantTemplateMenuItem extends WatchUi.IconMenuItem { function initialize( label as Lang.String or Lang.Symbol, - identifier as Lang.Object or Null, template as Lang.String, service as Lang.String or Null, confirm as Lang.Boolean, data as Lang.Dictionary or Null, icon as Graphics.BitmapType or WatchUi.Drawable, options as { - :alignment as WatchUi.MenuItem.Alignment, + :alignment as WatchUi.MenuItem.Alignment } or Null, haService as HomeAssistantService ) { WatchUi.IconMenuItem.initialize( label, null, - identifier, + null, icon, options ); @@ -59,11 +58,6 @@ class HomeAssistantTemplateMenuItem extends WatchUi.IconMenuItem { mService = service; mConfirm = confirm; mData = data; - if (mData == null) { - mData = {"entity_id" => identifier}; - } else { - mData.put("entity_id", identifier); - } } function callService() as Void { @@ -80,7 +74,7 @@ class HomeAssistantTemplateMenuItem extends WatchUi.IconMenuItem { function onConfirm() as Void { if (mService != null) { - mHomeAssistantService.call(mIdentifier as Lang.String, mService, mData); + mHomeAssistantService.call(mService, mData); } } diff --git a/source/HomeAssistantToggleMenuItem.mc b/source/HomeAssistantToggleMenuItem.mc index ee0f388..9dd1d10 100644 --- a/source/HomeAssistantToggleMenuItem.mc +++ b/source/HomeAssistantToggleMenuItem.mc @@ -25,21 +25,18 @@ using Toybox.Application.Properties; using Toybox.Timer; class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { + private var mData as Lang.Dictionary; function initialize( label as Lang.String or Lang.Symbol, - subLabel as Lang.String or Lang.Symbol or { - :enabled as Lang.String or Lang.Symbol or Null, - :disabled as Lang.String or Lang.Symbol or Null - } or Null, - identifier, - enabled as Lang.Boolean, + data as Lang.Dictionary or Null, options as { :alignment as WatchUi.MenuItem.Alignment, :icon as Graphics.BitmapType or WatchUi.Drawable or Lang.Symbol } or Null ) { - WatchUi.ToggleMenuItem.initialize(label, subLabel, identifier, enabled, options); + WatchUi.ToggleMenuItem.initialize(label, null, null, false, options); + mData = data; } private function setUiToggle(state as Null or Lang.String) as Void { @@ -114,9 +111,9 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { if (msg != null) { // Should be an HTTP 404 according to curl queries if (Globals.scDebug) { - System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 404. " + mIdentifier + " " + msg); + System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 404. " + mData.get("entity_id") + " " + msg); } - ErrorView.show("HTTP 404, " + mIdentifier + ". " + data.get("message")); + ErrorView.show("HTTP 404, " + mData.get("entity_id") + ". " + data.get("message")); } else { if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 404, page not found. Check API URL setting."); @@ -127,9 +124,9 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { case 405: if (Globals.scDebug) { - System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 405. " + mIdentifier + " " + data.get("message")); + System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 405. " + mData.get("entity_id") + " " + data.get("message")); } - ErrorView.show("HTTP 405, " + mIdentifier + ". " + data.get("message")); + ErrorView.show("HTTP 405, " + mData.get("entity_id") + ". " + data.get("message")); break; @@ -170,7 +167,7 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { ErrorView.show(RezStrings.getNoInternet() + "."); getApp().setApiStatus(RezStrings.getUnavailable()); } else { - var url = Settings.getApiUrl() + "/states/" + mIdentifier; + var url = Settings.getApiUrl() + "/states/" + mData.get("entity_id"); if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem getState() URL=" + url); } @@ -239,7 +236,7 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { var state; var d = data as Lang.Array; for(var i = 0; i < d.size(); i++) { - if ((d[i].get("entity_id") as Lang.String).equals(mIdentifier)) { + if ((d[i].get("entity_id") as Lang.String).equals(mData.get("entity_id"))) { state = d[i].get("state") as Lang.String; if (Globals.scDebug) { System.println((d[i].get("attributes") as Lang.Dictionary).get("friendly_name") + " State=" + state); @@ -277,7 +274,7 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { } else { // Updated SDK and got a new error // ERROR: venu: Cannot find symbol ':substring' on type 'PolyType'. - var id = mIdentifier as Lang.String; + var id = mData.get("entity_id") as Lang.String; var url = Settings.getApiUrl() + "/services/"; if (s) { url = url + id.substring(0, id.find(".")) + "/turn_on"; @@ -285,14 +282,12 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { url = url + id.substring(0, id.find(".")) + "/turn_off"; } if (Globals.scDebug) { - System.println("HomeAssistantToggleMenuItem setState() URL=" + url); - System.println("HomeAssistantToggleMenuItem setState() mIdentifier=" + mIdentifier); + System.println("HomeAssistantToggleMenuItem setState() URL = " + url); + System.println("HomeAssistantToggleMenuItem setState() entity_id = " + id); } Communications.makeWebRequest( url, - { - "entity_id" => mIdentifier - }, + mData, { :method => Communications.HTTP_REQUEST_METHOD_POST, :headers => { diff --git a/source/HomeAssistantView.mc b/source/HomeAssistantView.mc index e31722f..12b1e5e 100644 --- a/source/HomeAssistantView.mc +++ b/source/HomeAssistantView.mc @@ -66,13 +66,13 @@ class HomeAssistantView extends WatchUi.Menu2 { if (type.equals("toggle") && entity != null) { addItem(HomeAssistantMenuItemFactory.create().toggle(name, entity)); } else if (type.equals("template") && content != null) { - if (tap_action == null) { - addItem(HomeAssistantMenuItemFactory.create().template_notap(name, entity, content, service, confirm, data)); + if (service == null) { + addItem(HomeAssistantMenuItemFactory.create().template_notap(name, content)); } else { addItem(HomeAssistantMenuItemFactory.create().template_tap(name, entity, content, service, confirm, data)); } - } else if (type.equals("tap") && entity != null && service != null) { + } else if (type.equals("tap") && service != null) { addItem(HomeAssistantMenuItemFactory.create().tap(name, entity, service, confirm, data)); } else if (type.equals("group")) { addItem(HomeAssistantMenuItemFactory.create().group(items[i]));