diff --git a/source/HomeAssistantApp.mc b/source/HomeAssistantApp.mc index 3b4ba2b..bf9cd23 100644 --- a/source/HomeAssistantApp.mc +++ b/source/HomeAssistantApp.mc @@ -25,23 +25,8 @@ using Toybox.System; using Toybox.Application.Properties; using Toybox.Timer; -(:background) +(:glance, :background) class HomeAssistantApp extends Application.AppBase { - private var strNoApiKey as Lang.String or Null; - private var strNoApiUrl as Lang.String or Null; - private var strNoConfigUrl as Lang.String or Null; - private var strNoPhone as Lang.String or Null; - private var strNoInternet as Lang.String or Null; - private var strNoResponse as Lang.String or Null; - private var strApiFlood as Lang.String or Null; - private var strConfigUrlNotFound as Lang.String or Null; - private var strNoJson as Lang.String or Null; - private var strUnhandledHttpErr as Lang.String or Null; - private var strTrailingSlashErr as Lang.String or Null; - private var strAvailable as Lang.String or Null; - private var strUnavailable as Lang.String or Null; - private var strUnconfigured as Lang.String or Null; - private var mApiStatus as Lang.String or Null; private var mMenuStatus as Lang.String or Null; private var mHaMenu as HomeAssistantView or Null; @@ -99,63 +84,45 @@ class HomeAssistantApp extends Application.AppBase { // with "(:glance)". } - // These are required for the Application/Widget and the Glance view, but not for the background service. - function initResources() { - strAvailable = WatchUi.loadResource($.Rez.Strings.Available); - strUnavailable = WatchUi.loadResource($.Rez.Strings.Unavailable); - strUnconfigured = WatchUi.loadResource($.Rez.Strings.Unconfigured); - mApiStatus = WatchUi.loadResource($.Rez.Strings.Checking); - mMenuStatus = WatchUi.loadResource($.Rez.Strings.Checking); - } - // Return the initial view of your application here function getInitialView() as Lang.Array? { mIsApp = true; - strNoApiKey = WatchUi.loadResource($.Rez.Strings.NoAPIKey); - strNoApiUrl = WatchUi.loadResource($.Rez.Strings.NoApiUrl); - strNoConfigUrl = WatchUi.loadResource($.Rez.Strings.NoConfigUrl); - strNoPhone = WatchUi.loadResource($.Rez.Strings.NoPhone); - strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet); - strNoResponse = WatchUi.loadResource($.Rez.Strings.NoResponse); - strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood); - strConfigUrlNotFound = WatchUi.loadResource($.Rez.Strings.ConfigUrlNotFound); - strNoJson = WatchUi.loadResource($.Rez.Strings.NoJson); - strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr); - strTrailingSlashErr = WatchUi.loadResource($.Rez.Strings.TrailingSlashErr); mQuitTimer = new QuitTimer(); + RezStrings.update(); + mApiStatus = RezStrings.strChecking; + mMenuStatus = RezStrings.strChecking; Settings.update(); - initResources(); if (Settings.getApiKey().length() == 0) { if (Globals.scDebug) { System.println("HomeAssistantApp getInitialView(): No API key in the application Settings."); } - return ErrorView.create(strNoApiKey + "."); + return ErrorView.create(RezStrings.strNoApiKey + "."); } else if (Settings.getApiUrl().length() == 0) { if (Globals.scDebug) { System.println("HomeAssistantApp getInitialView(): No API URL in the application Settings."); } - return ErrorView.create(strNoApiUrl + "."); + return ErrorView.create(RezStrings.strNoApiUrl + "."); } else if (Settings.getApiUrl().substring(-1, Settings.getApiUrl().length()).equals("/")) { if (Globals.scDebug) { System.println("HomeAssistantApp getInitialView(): API URL must not have a trailing slash '/'."); } - return ErrorView.create(strTrailingSlashErr + "."); + return ErrorView.create(RezStrings.strTrailingSlashErr + "."); } else if (Settings.getConfigUrl().length() == 0) { if (Globals.scDebug) { System.println("HomeAssistantApp getInitialView(): No configuration URL in the application settings."); } - return ErrorView.create(strNoConfigUrl + "."); + return ErrorView.create(RezStrings.strNoConfigUrl + "."); } else if (! System.getDeviceSettings().phoneConnected) { if (Globals.scDebug) { System.println("HomeAssistantApp fetchMenuConfig(): No Phone connection, skipping API call."); } - return ErrorView.create(strNoPhone + "."); + return ErrorView.create(RezStrings.strNoPhone + "."); } else if (! System.getDeviceSettings().connectionAvailable) { if (Globals.scDebug) { System.println("HomeAssistantApp fetchMenuConfig(): No Internet connection, skipping API call."); } - return ErrorView.create(strNoInternet + "."); + return ErrorView.create(RezStrings.strNoInternet + "."); } else { fetchMenuConfig(); fetchApiStatus(); @@ -176,7 +143,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Data: " + data); } - mMenuStatus = strUnavailable; + mMenuStatus = RezStrings.strUnavailable; switch (responseCode) { case Communications.BLE_HOST_TIMEOUT: case Communications.BLE_CONNECTION_UNAVAILABLE: @@ -184,7 +151,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed."); } if (!mIsGlance) { - ErrorView.show(strNoPhone + "."); + ErrorView.show(RezStrings.strNoPhone + "."); } break; @@ -193,7 +160,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Code: BLE_QUEUE_FULL, API calls too rapid."); } if (!mIsGlance) { - ErrorView.show(strApiFlood); + ErrorView.show(RezStrings.strApiFlood); } break; @@ -202,7 +169,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection."); } if (!mIsGlance) { - ErrorView.show(strNoResponse); + ErrorView.show(RezStrings.strNoResponse); } break; @@ -211,7 +178,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Code: INVALID_HTTP_BODY_IN_NETWORK_RESPONSE, check JSON is returned."); } if (!mIsGlance) { - ErrorView.show(strNoJson); + ErrorView.show(RezStrings.strNoJson); } break; @@ -220,12 +187,12 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Code: 404, page not found. Check Configuration URL setting."); } if (!mIsGlance) { - ErrorView.show(strConfigUrlNotFound); + ErrorView.show(RezStrings.strConfigUrlNotFound); } break; case 200: - mMenuStatus = strAvailable; + mMenuStatus = RezStrings.strAvailable; if (!mIsGlance) { mHaMenu = new HomeAssistantView(data, null); mQuitTimer.begin(); @@ -252,7 +219,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchMenuConfig(): Unhandled HTTP response code = " + responseCode); } if (!mIsGlance) { - ErrorView.show(strUnhandledHttpErr + responseCode); + ErrorView.show(RezStrings.strUnhandledHttpErr + responseCode); } break; } @@ -262,7 +229,7 @@ class HomeAssistantApp extends Application.AppBase { (:glance) function fetchMenuConfig() as Void { if (Settings.getConfigUrl().equals("")) { - mMenuStatus = strUnconfigured; + mMenuStatus = RezStrings.strUnconfigured; WatchUi.requestUpdate(); } else { if (! System.getDeviceSettings().phoneConnected) { @@ -272,9 +239,9 @@ class HomeAssistantApp extends Application.AppBase { if (mIsGlance) { WatchUi.requestUpdate(); } else { - ErrorView.show(strNoPhone + "."); + ErrorView.show(RezStrings.strNoPhone + "."); } - mMenuStatus = strUnavailable; + mMenuStatus = RezStrings.strUnavailable; } else if (! System.getDeviceSettings().connectionAvailable) { if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem getState(): No Internet connection, skipping API call."); @@ -282,9 +249,9 @@ class HomeAssistantApp extends Application.AppBase { if (mIsGlance) { WatchUi.requestUpdate(); } else { - ErrorView.show(strNoInternet + "."); + ErrorView.show(RezStrings.strNoInternet + "."); } - mMenuStatus = strUnavailable; + mMenuStatus = RezStrings.strUnavailable; } else { Communications.makeWebRequest( Settings.getConfigUrl(), @@ -308,7 +275,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchApiStatus() Response Data: " + data); } - mApiStatus = strUnavailable; + mApiStatus = RezStrings.strUnavailable; switch (responseCode) { case Communications.BLE_HOST_TIMEOUT: case Communications.BLE_CONNECTION_UNAVAILABLE: @@ -316,7 +283,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchApiStatus() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed."); } if (!mIsGlance) { - ErrorView.show(strNoPhone + "."); + ErrorView.show(RezStrings.strNoPhone + "."); } break; @@ -325,7 +292,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchApiStatus() Response Code: BLE_QUEUE_FULL, API calls too rapid."); } if (!mIsGlance) { - ErrorView.show(strApiFlood); + ErrorView.show(RezStrings.strApiFlood); } break; @@ -334,7 +301,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchApiStatus() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection."); } if (!mIsGlance) { - ErrorView.show(strNoResponse); + ErrorView.show(RezStrings.strNoResponse); } break; @@ -343,7 +310,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchApiStatus() Response Code: INVALID_HTTP_BODY_IN_NETWORK_RESPONSE, check JSON is returned."); } if (!mIsGlance) { - ErrorView.show(strNoJson); + ErrorView.show(RezStrings.strNoJson); } break; @@ -352,7 +319,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchApiStatus() Response Code: 404, page not found. Check Configuration URL setting."); } if (!mIsGlance) { - ErrorView.show(strConfigUrlNotFound); + ErrorView.show(RezStrings.strConfigUrlNotFound); } break; @@ -362,7 +329,7 @@ class HomeAssistantApp extends Application.AppBase { msg = data.get("message"); } if (msg.equals("API running.")) { - mApiStatus = strAvailable; + mApiStatus = RezStrings.strAvailable; } else { if (!mIsGlance) { ErrorView.show("API " + mApiStatus + "."); @@ -375,7 +342,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp onReturnFetchApiStatus(): Unhandled HTTP response code = " + responseCode); } if (!mIsGlance) { - ErrorView.show(strUnhandledHttpErr + responseCode); + ErrorView.show(RezStrings.strUnhandledHttpErr + responseCode); } } WatchUi.requestUpdate(); @@ -384,28 +351,28 @@ class HomeAssistantApp extends Application.AppBase { (:glance) function fetchApiStatus() as Void { if (Settings.getApiUrl().equals("")) { - mApiStatus = strUnconfigured; + mApiStatus = RezStrings.strUnconfigured; WatchUi.requestUpdate(); } else { if (! System.getDeviceSettings().phoneConnected) { if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem getState(): No Phone connection, skipping API call."); } - mApiStatus = strUnavailable; + mApiStatus = RezStrings.strUnavailable; if (mIsGlance) { WatchUi.requestUpdate(); } else { - ErrorView.show(strNoPhone + "."); + ErrorView.show(RezStrings.strNoPhone + "."); } } else if (! System.getDeviceSettings().connectionAvailable) { if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem getState(): No Internet connection, skipping API call."); } - mApiStatus = strUnavailable; + mApiStatus = RezStrings.strUnavailable; if (mIsGlance) { WatchUi.requestUpdate(); } else { - ErrorView.show(strNoInternet + "."); + ErrorView.show(RezStrings.strNoInternet + "."); } } else { Communications.makeWebRequest( @@ -455,7 +422,7 @@ class HomeAssistantApp extends Application.AppBase { System.println("HomeAssistantApp updateNextMenuItem(): No menu items to update"); } if (!mIsGlance) { - ErrorView.show(WatchUi.loadResource($.Rez.Strings.ConfigUrlNotFound)); + ErrorView.show(RezStrings.strConfigUrlNotFound); } } else { itu[mNextItemToUpdate].getState(); @@ -469,7 +436,9 @@ class HomeAssistantApp extends Application.AppBase { function getGlanceView() as Lang.Array or Null { mIsGlance = true; - initResources(); + RezStrings.update_glance(); + mApiStatus = RezStrings.strChecking; + mMenuStatus = RezStrings.strChecking; updateGlance(); Settings.update(); mTimer = new Timer.Timer(); diff --git a/source/HomeAssistantConfirmation.mc b/source/HomeAssistantConfirmation.mc index b7f57b9..7695d34 100644 --- a/source/HomeAssistantConfirmation.mc +++ b/source/HomeAssistantConfirmation.mc @@ -28,7 +28,7 @@ using Toybox.Application.Properties; class HomeAssistantConfirmation extends WatchUi.Confirmation { function initialize() { - WatchUi.Confirmation.initialize(WatchUi.loadResource($.Rez.Strings.Confirm)); + WatchUi.Confirmation.initialize(RezStrings.strConfirm); } } diff --git a/source/HomeAssistantGlanceView.mc b/source/HomeAssistantGlanceView.mc index 51b8aad..a340ad7 100644 --- a/source/HomeAssistantGlanceView.mc +++ b/source/HomeAssistantGlanceView.mc @@ -39,13 +39,11 @@ class HomeAssistantGlanceView extends WatchUi.GlanceView { } function onLayout(dc as Graphics.Dc) as Void { - var strChecking = WatchUi.loadResource($.Rez.Strings.Checking); - var strGlanceMenu = WatchUi.loadResource($.Rez.Strings.GlanceMenu); - var h = dc.getHeight(); - var tw = dc.getTextWidthInPixels(strGlanceMenu, Graphics.FONT_XTINY); + var h = dc.getHeight(); + var tw = dc.getTextWidthInPixels(RezStrings.strGlanceMenu, Graphics.FONT_XTINY); mTitle = new WatchUi.Text({ - :text => WatchUi.loadResource($.Rez.Strings.AppName), + :text => RezStrings.strAppName, :color => Graphics.COLOR_WHITE, :font => Graphics.FONT_TINY, :justification => Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER, @@ -62,7 +60,7 @@ class HomeAssistantGlanceView extends WatchUi.GlanceView { :locY => 3 * h / 6 }); mApiStatus = new WatchUi.Text({ - :text => strChecking, + :text => RezStrings.strChecking, :color => Graphics.COLOR_WHITE, :font => Graphics.FONT_XTINY, :justification => Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER, @@ -70,7 +68,7 @@ class HomeAssistantGlanceView extends WatchUi.GlanceView { :locY => 3 * h / 6 }); mMenuText = new WatchUi.Text({ - :text => strGlanceMenu + ":", + :text => RezStrings.strGlanceMenu + ":", :color => Graphics.COLOR_WHITE, :font => Graphics.FONT_XTINY, :justification => Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER, @@ -78,7 +76,7 @@ class HomeAssistantGlanceView extends WatchUi.GlanceView { :locY => 5 * h / 6 }); mMenuStatus = new WatchUi.Text({ - :text => strChecking, + :text => RezStrings.strChecking, :color => Graphics.COLOR_WHITE, :font => Graphics.FONT_XTINY, :justification => Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER, diff --git a/source/HomeAssistantMenuItemFactory.mc b/source/HomeAssistantMenuItemFactory.mc index d9e46cc..9de4944 100644 --- a/source/HomeAssistantMenuItemFactory.mc +++ b/source/HomeAssistantMenuItemFactory.mc @@ -24,8 +24,6 @@ using Toybox.WatchUi; class HomeAssistantMenuItemFactory { private var mMenuItemOptions as Lang.Dictionary; - private var mLabelToggle as Lang.Dictionary; - private var strMenuItemTap as Lang.String; private var mTapTypeIcon as WatchUi.Bitmap; private var mGroupTypeIcon as WatchUi.Bitmap; private var mHomeAssistantService as HomeAssistantService; @@ -33,16 +31,10 @@ class HomeAssistantMenuItemFactory { private static var instance; private function initialize() { - mLabelToggle = { - :enabled => WatchUi.loadResource($.Rez.Strings.MenuItemOn) as Lang.String, - :disabled => WatchUi.loadResource($.Rez.Strings.MenuItemOff) as Lang.String - }; - mMenuItemOptions = { :alignment => Settings.getMenuAlignment() }; - strMenuItemTap = WatchUi.loadResource($.Rez.Strings.MenuItemTap); mTapTypeIcon = new WatchUi.Bitmap({ :rezId => $.Rez.Drawables.TapTypeIcon, :locX => WatchUi.LAYOUT_HALIGN_CENTER, @@ -67,7 +59,7 @@ class HomeAssistantMenuItemFactory { function toggle(label as Lang.String or Lang.Symbol, identifier as Lang.Object or Null) as WatchUi.MenuItem { return new HomeAssistantToggleMenuItem( label, - Settings.getMenuStyle() == Settings.MENU_STYLE_TEXT ? mLabelToggle : null, + Settings.getMenuStyle() == Settings.MENU_STYLE_TEXT ? RezStrings.strLabelToggle : null, identifier, false, mMenuItemOptions @@ -83,7 +75,7 @@ class HomeAssistantMenuItemFactory { if (Settings.getMenuStyle() == Settings.MENU_STYLE_TEXT) { return new HomeAssistantMenuItem( label, - strMenuItemTap, + RezStrings.strMenuItemTap, identifier, service, confirm, diff --git a/source/HomeAssistantService.mc b/source/HomeAssistantService.mc index ab7e6c6..8ba36e5 100644 --- a/source/HomeAssistantService.mc +++ b/source/HomeAssistantService.mc @@ -24,13 +24,6 @@ using Toybox.Graphics; using Toybox.Application.Properties; class HomeAssistantService { - private var strNoPhone = WatchUi.loadResource($.Rez.Strings.NoPhone); - private var strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet); - private var strNoResponse = WatchUi.loadResource($.Rez.Strings.NoResponse); - private var strNoJson = WatchUi.loadResource($.Rez.Strings.NoJson); - private var strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood); - private var strApiUrlNotFound = WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound); - private var strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr); // Callback function after completing the POST request to call a service. // @@ -47,21 +40,21 @@ class HomeAssistantService { if (Globals.scDebug) { System.println("HomeAssistantService onReturnCall() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed."); } - ErrorView.show(strNoPhone + "."); + ErrorView.show(RezStrings.strNoPhone + "."); break; case Communications.BLE_QUEUE_FULL: if (Globals.scDebug) { System.println("HomeAssistantService onReturnCall() Response Code: BLE_QUEUE_FULL, API calls too rapid."); } - ErrorView.show(strApiFlood); + ErrorView.show(RezStrings.strApiFlood); break; case Communications.NETWORK_REQUEST_TIMED_OUT: if (Globals.scDebug) { System.println("HomeAssistantService onReturnCall() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection."); } - ErrorView.show(strNoResponse); + ErrorView.show(RezStrings.strNoResponse); break; case Communications.NETWORK_RESPONSE_OUT_OF_MEMORY: @@ -74,14 +67,14 @@ class HomeAssistantService { if (Globals.scDebug) { System.println("HomeAssistantService onReturnCall() Response Code: INVALID_HTTP_BODY_IN_NETWORK_RESPONSE, check JSON is returned."); } - ErrorView.show(strNoJson); + ErrorView.show(RezStrings.strNoJson); break; case 404: if (Globals.scDebug) { System.println("HomeAssistantService onReturnCall() Response Code: 404, page not found. Check API URL setting."); } - ErrorView.show(strApiUrlNotFound); + ErrorView.show(RezStrings.strApiUrlNotFound); break; case 200: @@ -112,7 +105,7 @@ class HomeAssistantService { if (Globals.scDebug) { System.println("HomeAssistantService onReturnCall(): Unhandled HTTP response code = " + responseCode); } - ErrorView.show(strUnhandledHttpErr + responseCode); + ErrorView.show(RezStrings.strUnhandledHttpErr + responseCode); } } @@ -121,12 +114,12 @@ class HomeAssistantService { if (Globals.scDebug) { System.println("HomeAssistantService call(): No Phone connection, skipping API call."); } - ErrorView.show(strNoPhone + "."); + ErrorView.show(RezStrings.strNoPhone + "."); } else if (! System.getDeviceSettings().connectionAvailable) { if (Globals.scDebug) { System.println("HomeAssistantService call(): No Internet connection, skipping API call."); } - ErrorView.show(strNoInternet + "."); + ErrorView.show(RezStrings.strNoInternet + "."); } else { // Can't use null for substring() parameters due to API version level. var url = Settings.getApiUrl() + "/services/" + service.substring(0, service.find(".")) + "/" + service.substring(service.find(".")+1, service.length()); diff --git a/source/HomeAssistantToggleMenuItem.mc b/source/HomeAssistantToggleMenuItem.mc index 4502948..95bd404 100644 --- a/source/HomeAssistantToggleMenuItem.mc +++ b/source/HomeAssistantToggleMenuItem.mc @@ -25,15 +25,6 @@ using Toybox.Application.Properties; using Toybox.Timer; class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { - private var strNoPhone = WatchUi.loadResource($.Rez.Strings.NoPhone); - private var strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet); - private var strNoResponse = WatchUi.loadResource($.Rez.Strings.NoResponse); - private var strNoJson = WatchUi.loadResource($.Rez.Strings.NoJson); - private var strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood); - private var strApiUrlNotFound = WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound); - private var strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr); - private var strUnavailable = WatchUi.loadResource($.Rez.Strings.Unavailable); - private var strAvailable = WatchUi.loadResource($.Rez.Strings.Available); function initialize( label as Lang.String or Lang.Symbol, @@ -73,35 +64,35 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Data: " + data); } - var status = strUnavailable; + var status = RezStrings.strUnavailable; switch (responseCode) { case Communications.BLE_HOST_TIMEOUT: case Communications.BLE_CONNECTION_UNAVAILABLE: if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed."); } - ErrorView.show(strNoPhone + "."); + ErrorView.show(RezStrings.strNoPhone + "."); break; case Communications.BLE_QUEUE_FULL: if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: BLE_QUEUE_FULL, API calls too rapid."); } - ErrorView.show(strApiFlood); + ErrorView.show(RezStrings.strApiFlood); break; case Communications.NETWORK_REQUEST_TIMED_OUT: if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection."); } - ErrorView.show(strNoResponse); + ErrorView.show(RezStrings.strNoResponse); break; case Communications.INVALID_HTTP_BODY_IN_NETWORK_RESPONSE: if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: INVALID_HTTP_BODY_IN_NETWORK_RESPONSE, check JSON is returned."); } - ErrorView.show(strNoJson); + ErrorView.show(RezStrings.strNoJson); break; case Communications.NETWORK_RESPONSE_OUT_OF_MEMORY: @@ -128,7 +119,7 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 404, page not found. Check API URL setting."); } - ErrorView.show(strApiUrlNotFound); + ErrorView.show(RezStrings.strApiUrlNotFound); } break; @@ -141,7 +132,7 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { break; case 200: - status = strAvailable; + status = RezStrings.strAvailable; var state = data.get("state") as Lang.String; if (Globals.scDebug) { System.println((data.get("attributes") as Lang.Dictionary).get("friendly_name") + " State=" + state); @@ -159,7 +150,7 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnGetState(): Unhandled HTTP response code = " + responseCode); } - ErrorView.show(strUnhandledHttpErr + responseCode); + ErrorView.show(RezStrings.strUnhandledHttpErr + responseCode); } getApp().setApiStatus(status); } @@ -169,14 +160,14 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem getState(): No Phone connection, skipping API call."); } - ErrorView.show(strNoPhone + "."); - getApp().setApiStatus(strUnavailable); + ErrorView.show(RezStrings.strNoPhone + "."); + getApp().setApiStatus(RezStrings.strUnavailable); } else if (! System.getDeviceSettings().connectionAvailable) { if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem getState(): No Internet connection, skipping API call."); } - ErrorView.show(strNoInternet + "."); - getApp().setApiStatus(strUnavailable); + ErrorView.show(RezStrings.strNoInternet + "."); + getApp().setApiStatus(RezStrings.strUnavailable); } else { var url = Settings.getApiUrl() + "/states/" + mIdentifier; if (Globals.scDebug) { @@ -205,42 +196,42 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Data: " + data); } - var status = strUnavailable; + var status = RezStrings.strUnavailable; switch (responseCode) { case Communications.BLE_HOST_TIMEOUT: case Communications.BLE_CONNECTION_UNAVAILABLE: if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed."); } - ErrorView.show(strNoPhone + "."); + ErrorView.show(RezStrings.strNoPhone + "."); break; case Communications.BLE_QUEUE_FULL: if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: BLE_QUEUE_FULL, API calls too rapid."); } - ErrorView.show(strApiFlood); + ErrorView.show(RezStrings.strApiFlood); break; case Communications.NETWORK_REQUEST_TIMED_OUT: if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection."); } - ErrorView.show(strNoResponse); + ErrorView.show(RezStrings.strNoResponse); break; case Communications.INVALID_HTTP_BODY_IN_NETWORK_RESPONSE: if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: INVALID_HTTP_BODY_IN_NETWORK_RESPONSE, check JSON is returned."); } - ErrorView.show(strNoJson); + ErrorView.show(RezStrings.strNoJson); break; case 404: if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: 404, page not found. Check API URL setting."); } - ErrorView.show(strApiUrlNotFound); + ErrorView.show(RezStrings.strApiUrlNotFound); break; case 200: @@ -255,14 +246,14 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { setUiToggle(state); } } - status = strAvailable; + status = RezStrings.strAvailable; break; default: if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem onReturnSetState(): Unhandled HTTP response code = " + responseCode); } - ErrorView.show(strUnhandledHttpErr + responseCode); + ErrorView.show(RezStrings.strUnhandledHttpErr + responseCode); } getApp().setApiStatus(status); } @@ -274,14 +265,14 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem { } // Toggle the UI back setEnabled(!isEnabled()); - ErrorView.show(strNoPhone + "."); + ErrorView.show(RezStrings.strNoPhone + "."); } else if (! System.getDeviceSettings().connectionAvailable) { if (Globals.scDebug) { System.println("HomeAssistantToggleMenuItem getState(): No Internet connection, skipping API call."); } // Toggle the UI back setEnabled(!isEnabled()); - ErrorView.show(strNoInternet + "."); + ErrorView.show(RezStrings.strNoInternet + "."); } else { // Updated SDK and got a new error // ERROR: venu: Cannot find symbol ':substring' on type 'PolyType'. diff --git a/source/HomeAssistantView.mc b/source/HomeAssistantView.mc index 747adcb..78afe1b 100644 --- a/source/HomeAssistantView.mc +++ b/source/HomeAssistantView.mc @@ -49,11 +49,11 @@ class HomeAssistantView extends WatchUi.Menu2 { var items = definition.get("items") as Lang.Dictionary; for(var i = 0; i < items.size(); i++) { - var type = items[i].get("type") as Lang.String or Null; - var name = items[i].get("name") as Lang.String or Null; - var entity = items[i].get("entity") as Lang.String or Null; + var type = items[i].get("type") as Lang.String or Null; + var name = items[i].get("name") 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 service = items[i].get("service") as Lang.String or Null; var confirm = false as Lang.Boolean; if (tap_action != null) { service = tap_action.get("service"); diff --git a/source/HomeAssistantViewMenuItem.mc b/source/HomeAssistantViewMenuItem.mc index 7ed91ea..0b816ba 100644 --- a/source/HomeAssistantViewMenuItem.mc +++ b/source/HomeAssistantViewMenuItem.mc @@ -28,7 +28,7 @@ class HomeAssistantViewMenuItem extends WatchUi.MenuItem { // definitions.get(...) are Strings here as they have been checked by HomeAssistantView first WatchUi.MenuItem.initialize( definition.get("name") as Lang.String, - WatchUi.loadResource($.Rez.Strings.MenuItemMenu) as Lang.String, + RezStrings.strMenuItemMenu, definition.get("entity") as Lang.String, null ); diff --git a/source/RezStrings.mc b/source/RezStrings.mc new file mode 100644 index 0000000..21efd0c --- /dev/null +++ b/source/RezStrings.mc @@ -0,0 +1,106 @@ +//----------------------------------------------------------------------------------- +// +// 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. +// +// P A Abbey & J D Abbey & Someone0nEarth, 31 October 2023 +// +// +// Description: +// +// Load the strings centrally once rather than initialising locally within separate +// classes. This is to solve a problem with out of memory errors in some devices, +// e.g. Vivoactive 3. +// +//----------------------------------------------------------------------------------- + +using Toybox.Lang; +using Toybox.WatchUi; + +class RezStrings { + + (:glance) + static var strAppName as Lang.String or Null; + static var strMenuItemTap as Lang.String or Null; + static var strMenuItemMenu as Lang.String or Null; + static var strConfirm as Lang.String or Null; + (:glance) + static var strNoPhone as Lang.String or Null; + static var strNoInternet as Lang.String or Null; + static var strNoResponse as Lang.String or Null; + (:glance) + static var strNoApiKey as Lang.String or Null; + (:glance) + static var strNoApiUrl as Lang.String or Null; + (:glance) + static var strNoConfigUrl as Lang.String or Null; + static var strApiFlood as Lang.String or Null; + static var strApiUrlNotFound as Lang.String or Null; + static var strConfigUrlNotFound as Lang.String or Null; + static var strNoJson as Lang.String or Null; + static var strUnhandledHttpErr as Lang.String or Null; + static var strTrailingSlashErr as Lang.String or Null; + (:glance) + static var strAvailable as Lang.String or Null; + (:glance) + static var strChecking as Lang.String or Null; + (:glance) + static var strUnavailable as Lang.String or Null; + (:glance) + static var strUnconfigured as Lang.String or Null; + (:glance) + static var strGlanceMenu as Lang.String or Null; + static var strLabelToggle as Lang.Dictionary or Null; + + // Can't initialise a constant directly, have to be initialised via a function + // for 'WatchUi.loadResource' to be available. + (:glance) + static function update_glance() { + strAppName = WatchUi.loadResource($.Rez.Strings.AppName); + strNoPhone = WatchUi.loadResource($.Rez.Strings.NoPhone); + strNoApiKey = WatchUi.loadResource($.Rez.Strings.NoAPIKey); + strNoApiUrl = WatchUi.loadResource($.Rez.Strings.NoApiUrl); + strNoConfigUrl = WatchUi.loadResource($.Rez.Strings.NoConfigUrl); + strAvailable = WatchUi.loadResource($.Rez.Strings.Available); + strChecking = WatchUi.loadResource($.Rez.Strings.Checking); + strUnavailable = WatchUi.loadResource($.Rez.Strings.Unavailable); + strUnconfigured = WatchUi.loadResource($.Rez.Strings.Unconfigured); + strGlanceMenu = WatchUi.loadResource($.Rez.Strings.GlanceMenu); + } + + // Can't initialise a constant directly, have to be initialised via a function + // for 'WatchUi.loadResource' to be available. + static function update() { + strAppName = WatchUi.loadResource($.Rez.Strings.AppName); + strMenuItemTap = WatchUi.loadResource($.Rez.Strings.MenuItemTap); + strMenuItemMenu = WatchUi.loadResource($.Rez.Strings.MenuItemMenu); + strConfirm = WatchUi.loadResource($.Rez.Strings.Confirm); + strNoPhone = WatchUi.loadResource($.Rez.Strings.NoPhone); + strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet); + strNoResponse = WatchUi.loadResource($.Rez.Strings.NoResponse); + strNoApiKey = WatchUi.loadResource($.Rez.Strings.NoAPIKey); + strNoApiUrl = WatchUi.loadResource($.Rez.Strings.NoApiUrl); + strNoConfigUrl = WatchUi.loadResource($.Rez.Strings.NoConfigUrl); + strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood); + strApiUrlNotFound = WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound); + strConfigUrlNotFound = WatchUi.loadResource($.Rez.Strings.ConfigUrlNotFound); + strNoJson = WatchUi.loadResource($.Rez.Strings.NoJson); + strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr); + strTrailingSlashErr = WatchUi.loadResource($.Rez.Strings.TrailingSlashErr); + strAvailable = WatchUi.loadResource($.Rez.Strings.Available); + strChecking = WatchUi.loadResource($.Rez.Strings.Checking); + strUnavailable = WatchUi.loadResource($.Rez.Strings.Unavailable); + strUnconfigured = WatchUi.loadResource($.Rez.Strings.Unconfigured); + strGlanceMenu = WatchUi.loadResource($.Rez.Strings.GlanceMenu); + strLabelToggle = { + :enabled => WatchUi.loadResource($.Rez.Strings.MenuItemOn) as Lang.String, + :disabled => WatchUi.loadResource($.Rez.Strings.MenuItemOff) as Lang.String + }; + } +} diff --git a/source/RootView.mc b/source/RootView.mc index 1d412d5..96509f5 100644 --- a/source/RootView.mc +++ b/source/RootView.mc @@ -51,11 +51,10 @@ class RootView extends ScalableView { } function onLayout(dc as Graphics.Dc) as Void { - var strChecking = WatchUi.loadResource($.Rez.Strings.Checking); - var w = dc.getWidth(); + var w = dc.getWidth(); mTitle = new WatchUi.Text({ - :text => WatchUi.loadResource($.Rez.Strings.AppName), + :text => RezStrings.strAppName, :color => Graphics.COLOR_WHITE, :font => Graphics.FONT_TINY, :justification => Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER, @@ -72,7 +71,7 @@ class RootView extends ScalableView { :locY => pixelsForScreen(50.0) }); mApiStatus = new WatchUi.Text({ - :text => strChecking, + :text => RezStrings.strChecking, :color => Graphics.COLOR_WHITE, :font => Graphics.FONT_XTINY, :justification => Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER, @@ -80,7 +79,7 @@ class RootView extends ScalableView { :locY => pixelsForScreen(50.0) }); mMenuText = new WatchUi.Text({ - :text => WatchUi.loadResource($.Rez.Strings.GlanceMenu) + ":", + :text => RezStrings.strGlanceMenu + ":", :color => Graphics.COLOR_WHITE, :font => Graphics.FONT_XTINY, :justification => Graphics.TEXT_JUSTIFY_RIGHT | Graphics.TEXT_JUSTIFY_VCENTER, @@ -88,7 +87,7 @@ class RootView extends ScalableView { :locY => pixelsForScreen(70.0) }); mMenuStatus = new WatchUi.Text({ - :text => strChecking, + :text => RezStrings.strChecking, :color => Graphics.COLOR_WHITE, :font => Graphics.FONT_XTINY, :justification => Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER,