diff --git a/README.md b/README.md
index c020c42..8efdd90 100644
--- a/README.md
+++ b/README.md
@@ -117,7 +117,7 @@ Having created that token, before you dismiss the dialogue box with the value yo
1. Paste your API key you've just created into the top field.
-2. Add the URL for your Home Assistant API, e.g. `https:///api/`.
+2. Add the URL for your Home Assistant API, e.g. `https:///api`. (No trailing slash `/`` character as one gets appended when creating the URL and you do not want two.)
3. Add the URL of your JSON file, e.g. `https:///local/garmin/.json`.
You should now have a working application on your watch and be able to operate your Home Assistant devices for as long as your watch is within Bluetooth range of your phone.
diff --git a/manifest.xml b/manifest.xml
index 970fb57..1c5790f 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -21,7 +21,7 @@
Use "Monkey C: Edit Application" from the Visual Studio Code command palette
to update the application attributes.
-->
-
+
@@ -30,4 +30,8 @@
У налаштуваннях програми немає URL-адреси API
У налаштуваннях програми немає URL-адреси конфігурації
Надто швидкі виклики API. Будь ласка, сповільніть свої запити.
+ URL не знайдено. Потенційна помилка URL-адреси API в налаштуваннях.
+ URL не знайдено. Потенційна помилка URL-адреси конфігурації в налаштуваннях.
+ Запит HTTP повернув код помилки =
+ URL-адреса API не повинна містити косу риску '/'
\ No newline at end of file
diff --git a/resources-vie/strings/strings.xml b/resources-vie/strings/strings.xml
index ba6f840..20d15ff 100644
--- a/resources-vie/strings/strings.xml
+++ b/resources-vie/strings/strings.xml
@@ -30,4 +30,8 @@
Không có URL API trong cài đặt ứng dụng
Không có URL cấu hình trong cài đặt ứng dụng
Cuộc gọi API quá nhanh. Hãy làm chậm yêu cầu của bạn.
+ Không tìm thấy URL. Lỗi URL API tiềm ẩn trong cài đặt.
+ Không tìm thấy URL. Lỗi URL cấu hình tiềm ẩn trong cài đặt.
+ Yêu cầu HTTP trả về mã lỗi =
+ URL API không được có dấu gạch chéo ở cuối '/'
\ No newline at end of file
diff --git a/resources-zhs/strings/strings.xml b/resources-zhs/strings/strings.xml
index cdbdb69..dfdee43 100644
--- a/resources-zhs/strings/strings.xml
+++ b/resources-zhs/strings/strings.xml
@@ -30,4 +30,8 @@
应用程序设置中没有 API URL
应用程序设置中没有配置 URL
API 调用速度太快。请放慢您的请求。
+ 找不到网址。设置中可能存在 API URL 错误。
+ 找不到网址。设置中可能存在配置 URL 错误。
+ HTTP请求返回错误码=
+ API URL 不得有尾部斜杠“/”
\ No newline at end of file
diff --git a/resources-zht/strings/strings.xml b/resources-zht/strings/strings.xml
index dd5939e..8388437 100644
--- a/resources-zht/strings/strings.xml
+++ b/resources-zht/strings/strings.xml
@@ -30,4 +30,8 @@
應用程式設定中沒有 API URL
應用程式設定中沒有配置 URL
API 呼叫速度太快。請放慢您的請求。
+ 找不到網址。設定中可能存在 API URL 錯誤。
+ 找不到網址。設定中可能存在配置 URL 錯誤。
+ HTTP請求回傳錯誤碼=
+ API URL 不得有尾部斜線“/”
\ No newline at end of file
diff --git a/resources-zsm/strings/strings.xml b/resources-zsm/strings/strings.xml
index e4775f2..72fd875 100644
--- a/resources-zsm/strings/strings.xml
+++ b/resources-zsm/strings/strings.xml
@@ -30,4 +30,8 @@
Tiada URL API dalam tetapan aplikasi
Tiada URL konfigurasi dalam tetapan aplikasi
Panggilan API terlalu pantas. Sila perlahankan permintaan anda.
+ URL tidak ditemui. Ralat URL API yang berpotensi dalam tetapan.
+ URL tidak ditemui. Ralat URL Konfigurasi Potensi dalam tetapan.
+ Permintaan HTTP mengembalikan kod ralat =
+ URL API tidak boleh mempunyai garis miring '/'
\ No newline at end of file
diff --git a/resources/strings/strings.xml b/resources/strings/strings.xml
index bc91157..753dce2 100644
--- a/resources/strings/strings.xml
+++ b/resources/strings/strings.xml
@@ -24,4 +24,8 @@
No API URL in the application settings
No configuration URL in the application settings
API calls too rapid. Please slow down your requests.
+ URL not found. Potential API URL error in settings.
+ URL not found. Potential Configuration URL error in settings.
+ HTTP request returned error code =
+ API URL must not have a trailing slash '/'
diff --git a/source/HomeAssistantApp.mc b/source/HomeAssistantApp.mc
index 387ae37..334cfca 100644
--- a/source/HomeAssistantApp.mc
+++ b/source/HomeAssistantApp.mc
@@ -26,23 +26,29 @@ using Toybox.Timer;
class HomeAssistantApp extends Application.AppBase {
hidden var mHaMenu;
- hidden var strNoApiKey as Lang.String;
- hidden var strNoApiUrl as Lang.String;
- hidden var strNoConfigUrl as Lang.String;
- hidden var strNoInternet as Lang.String;
- hidden var strNoMenu as Lang.String;
- hidden var strApiFlood as Lang.String;
+ hidden var strNoApiKey as Lang.String;
+ hidden var strNoApiUrl as Lang.String;
+ hidden var strNoConfigUrl as Lang.String;
+ hidden var strNoInternet as Lang.String;
+ hidden var strNoMenu as Lang.String;
+ hidden var strApiFlood as Lang.String;
+ hidden var strConfigUrlNotFound as Lang.String;
+ hidden var strUnhandledHttpErr as Lang.String;
+ hidden var strTrailingSlashErr as Lang.String;
hidden var mItemsToUpdate; // Array initialised by onReturnFetchMenuConfig()
hidden var mNextItemToUpdate = 0; // Index into the above array
function initialize() {
AppBase.initialize();
- strNoApiKey = WatchUi.loadResource($.Rez.Strings.NoAPIKey);
- strNoApiUrl = WatchUi.loadResource($.Rez.Strings.NoApiUrl);
- strNoConfigUrl = WatchUi.loadResource($.Rez.Strings.NoConfigUrl);
- strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet);
- strNoMenu = WatchUi.loadResource($.Rez.Strings.NoMenu);
- strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood);
+ strNoApiKey = WatchUi.loadResource($.Rez.Strings.NoAPIKey);
+ strNoApiUrl = WatchUi.loadResource($.Rez.Strings.NoApiUrl);
+ strNoConfigUrl = WatchUi.loadResource($.Rez.Strings.NoConfigUrl);
+ strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet);
+ strNoMenu = WatchUi.loadResource($.Rez.Strings.NoMenu);
+ strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood);
+ strConfigUrlNotFound = WatchUi.loadResource($.Rez.Strings.ConfigUrlNotFound);
+ strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr);
+ strTrailingSlashErr = WatchUi.loadResource($.Rez.Strings.TrailingSlashErr);
}
// onStart() is called on application start up
@@ -54,19 +60,26 @@ class HomeAssistantApp extends Application.AppBase {
// Return the initial view of your application here
function getInitialView() as Lang.Array? {
+ var api_url = Properties.getValue("api_url") as Lang.String;
+
if ((Properties.getValue("api_key") as Lang.String).length() == 0) {
if (Globals.scDebug) {
- System.println("HomeAssistantMenuItem Note - execScript(): No API key in the application settings.");
+ System.println("HomeAssistantMenuItem execScript(): No API key in the application settings.");
}
return [new ErrorView(strNoApiKey + "."), new ErrorDelegate()] as Lang.Array;
- } else if ((Properties.getValue("api_url") as Lang.String).length() == 0) {
+ } else if (api_url.length() == 0) {
if (Globals.scDebug) {
- System.println("HomeAssistantMenuItem Note - execScript(): No API URL in the application settings.");
+ System.println("HomeAssistantMenuItem execScript(): No API URL in the application settings.");
}
return [new ErrorView(strNoApiUrl + "."), new ErrorDelegate()] as Lang.Array;
+ } else if (api_url.substring(-1, api_url.length()).equals("/")) {
+ if (Globals.scDebug) {
+ System.println("HomeAssistantMenuItem execScript(): API URL must not have a trailing slash '/'.");
+ }
+ return [new ErrorView(strTrailingSlashErr + "."), new ErrorDelegate()] as Lang.Array;
} else if ((Properties.getValue("config_url") as Lang.String).length() == 0) {
if (Globals.scDebug) {
- System.println("HomeAssistantMenuItem Note - execScript(): No configuration URL in the application settings.");
+ System.println("HomeAssistantMenuItem execScript(): No configuration URL in the application settings.");
}
return [new ErrorView(strNoConfigUrl + "."), new ErrorDelegate()] as Lang.Array;
} else if (System.getDeviceSettings().phoneConnected && System.getDeviceSettings().connectionAvailable) {
@@ -74,7 +87,7 @@ class HomeAssistantApp extends Application.AppBase {
return [new WatchUi.View(), new WatchUi.BehaviorDelegate()] as Lang.Array;
} else {
if (Globals.scDebug) {
- System.println("HomeAssistantApp Note - fetchMenuConfig(): No Internet connection, skipping API call.");
+ System.println("HomeAssistantApp fetchMenuConfig(): No Internet connection, skipping API call.");
}
return [new ErrorView(strNoInternet + "."), new ErrorDelegate()] as Lang.Array;
}
@@ -96,23 +109,30 @@ class HomeAssistantApp extends Application.AppBase {
// Avoid pushing multiple ErrorViews
WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
}
+ } else if (responseCode == 404) {
+ if (Globals.scDebug) {
+ System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Code: 404, page not found. Check Configuration URL setting.");
+ }
+ WatchUi.pushView(new ErrorView(strConfigUrlNotFound), new ErrorDelegate(), WatchUi.SLIDE_UP);
} else if (responseCode == 200) {
mHaMenu = new HomeAssistantView(data, null);
WatchUi.switchToView(mHaMenu, new HomeAssistantViewDelegate(), WatchUi.SLIDE_IMMEDIATE);
mItemsToUpdate = mHaMenu.getItemsToUpdate();
// Start the continuous update process that continues for as long as the application is running.
// The chain of functions from 'updateNextMenuItem()' calls 'updateNextMenuItem()' on completion.
- updateNextMenuItem();
- } else if (responseCode == -300) {
+ if (mItemsToUpdate.size() > 0) {
+ updateNextMenuItem();
+ }
+ } else if (responseCode == Communications.NETWORK_REQUEST_TIMED_OUT) {
if (Globals.scDebug) {
- System.println("HomeAssistantApp Note - onReturnFetchMenuConfig(): Network request timeout.");
+ System.println("HomeAssistantApp onReturnFetchMenuConfig(): Network request timeout.");
}
WatchUi.pushView(new ErrorView(strNoMenu + ". " + strNoInternet + "?"), new ErrorDelegate(), WatchUi.SLIDE_UP);
} else {
if (Globals.scDebug) {
- System.println("HomeAssistantApp Note - onReturnFetchMenuConfig(): Configuration not found or potential validation issue.");
+ System.println("HomeAssistantApp onReturnFetchMenuConfig(): Unhandled HTTP response code = " + responseCode);
}
- WatchUi.pushView(new ErrorView(strNoMenu + " code=" + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
+ WatchUi.pushView(new ErrorView(strUnhandledHttpErr + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
}
}
diff --git a/source/HomeAssistantMenuItem.mc b/source/HomeAssistantMenuItem.mc
index 5db50eb..bedcb82 100644
--- a/source/HomeAssistantMenuItem.mc
+++ b/source/HomeAssistantMenuItem.mc
@@ -24,10 +24,12 @@ using Toybox.Graphics;
using Toybox.Application.Properties;
class HomeAssistantMenuItem extends WatchUi.MenuItem {
- hidden var mApiKey = Properties.getValue("api_key");
- hidden var strNoInternet as Lang.String;
- hidden var strApiFlood as Lang.String;
- hidden var mService as Lang.String;
+ hidden var mApiKey as Lang.String;
+ hidden var strNoInternet as Lang.String;
+ hidden var strApiFlood as Lang.String;
+ hidden var strApiUrlNotFound as Lang.String;
+ hidden var strUnhandledHttpErr as Lang.String;
+ hidden var mService as Lang.String;
function initialize(
label as Lang.String or Lang.Symbol,
@@ -39,8 +41,11 @@ class HomeAssistantMenuItem extends WatchUi.MenuItem {
:icon as Graphics.BitmapType or WatchUi.Drawable or Lang.Symbol
} or Null
) {
- strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet);
- strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood);
+ strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet);
+ strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood);
+ strApiUrlNotFound = WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound);
+ strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr);
+ mApiKey = Properties.getValue("api_key");
mService = service;
WatchUi.MenuItem.initialize(
label,
@@ -66,12 +71,17 @@ class HomeAssistantMenuItem extends WatchUi.MenuItem {
// Avoid pushing multiple ErrorViews
WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
}
+ } else if (responseCode == 404) {
+ if (Globals.scDebug) {
+ System.println("HomeAssistantMenuItem onReturnExecScript() Response Code: 404, page not found. Check API URL setting.");
+ }
+ WatchUi.pushView(new ErrorView(strApiUrlNotFound), new ErrorDelegate(), WatchUi.SLIDE_UP);
} else if (responseCode == 200) {
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 (Globals.scDebug) {
- System.println("HomeAssistantMenuItem Note - onReturnExecScript(): Correct script executed.");
+ System.println("HomeAssistantMenuItem onReturnExecScript(): Correct script executed.");
}
if (WatchUi has :showToast) {
WatchUi.showToast(
@@ -97,6 +107,11 @@ class HomeAssistantMenuItem extends WatchUi.MenuItem {
}
}
}
+ } else {
+ if (Globals.scDebug) {
+ System.println("HomeAssistantMenuItem onReturnExecScript(): Unhandled HTTP response code = " + responseCode);
+ }
+ WatchUi.pushView(new ErrorView(strUnhandledHttpErr + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
}
}
@@ -142,7 +157,7 @@ class HomeAssistantMenuItem extends WatchUi.MenuItem {
}
} else {
if (Globals.scDebug) {
- System.println("HomeAssistantMenuItem Note - execScript(): No Internet connection, skipping API call.");
+ System.println("HomeAssistantMenuItem execScript(): No Internet connection, skipping API call.");
}
WatchUi.pushView(new ErrorView(strNoInternet + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
}
diff --git a/source/HomeAssistantToggleMenuItem.mc b/source/HomeAssistantToggleMenuItem.mc
index 73e34dc..33f13a2 100644
--- a/source/HomeAssistantToggleMenuItem.mc
+++ b/source/HomeAssistantToggleMenuItem.mc
@@ -24,9 +24,11 @@ using Toybox.Graphics;
using Toybox.Application.Properties;
class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
- hidden var mApiKey = Properties.getValue("api_key");
- hidden var strNoInternet as Lang.String;
- hidden var strApiFlood as Lang.String;
+ hidden var mApiKey as Lang.String;
+ hidden var strNoInternet as Lang.String;
+ hidden var strApiFlood as Lang.String;
+ hidden var strApiUrlNotFound as Lang.String;
+ hidden var strUnhandledHttpErr as Lang.String;
function initialize(
label as Lang.String or Lang.Symbol,
@@ -41,10 +43,12 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
:icon as Graphics.BitmapType or WatchUi.Drawable or Lang.Symbol
} or Null
) {
- strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet);
- strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood);
+ strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet);
+ strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood);
+ strApiUrlNotFound = WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound);
+ strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr);
+ mApiKey = Properties.getValue("api_key");
WatchUi.ToggleMenuItem.initialize(label, subLabel, identifier, enabled, options);
- mApiKey = Properties.getValue("api_key");
}
private function setUiToggle(state as Null or Lang.String) as Void {
@@ -75,6 +79,17 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
// Avoid pushing multiple ErrorViews
WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
}
+ // Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer.
+ getApp().updateNextMenuItem();
+ } else if (responseCode == 404) {
+ if (Globals.scDebug) {
+ System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 404, page not found. Check API URL setting.");
+ }
+ var cw = WatchUi.getCurrentView();
+ if (!(cw[0] instanceof ErrorView)) {
+ // Avoid pushing multiple ErrorViews
+ WatchUi.pushView(new ErrorView(strApiUrlNotFound), new ErrorDelegate(), WatchUi.SLIDE_UP);
+ }
} else if (responseCode == 200) {
var state = data.get("state") as Lang.String;
if (Globals.scDebug) {
@@ -84,9 +99,14 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
setLabel((data.get("attributes") as Lang.Dictionary).get("friendly_name") as Lang.String);
}
setUiToggle(state);
+ // Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer.
+ getApp().updateNextMenuItem();
+ } else {
+ if (Globals.scDebug) {
+ System.println("HomeAssistantToggleMenuItem onReturnGetState(): Unhandled HTTP response code = " + responseCode);
+ }
+ WatchUi.pushView(new ErrorView(strUnhandledHttpErr + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
}
- // Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer.
- getApp().updateNextMenuItem();
}
function getState() as Void {
@@ -110,7 +130,7 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
);
} else {
if (Globals.scDebug) {
- System.println("HomeAssistantToggleMenuItem Note - getState(): No Internet connection, skipping API call.");
+ System.println("HomeAssistantToggleMenuItem getState(): No Internet connection, skipping API call.");
}
WatchUi.pushView(new ErrorView(strNoInternet + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
}
@@ -127,10 +147,15 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
if (Globals.scDebug) {
System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: BLE_QUEUE_FULL, API calls too rapid.");
}
+ WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
+ } else if (responseCode == 404) {
+ if (Globals.scDebug) {
+ System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: 404, page not found. Check API URL setting.");
+ }
var cw = WatchUi.getCurrentView();
if (!(cw[0] instanceof ErrorView)) {
// Avoid pushing multiple ErrorViews
- WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
+ WatchUi.pushView(new ErrorView(strApiUrlNotFound), new ErrorDelegate(), WatchUi.SLIDE_UP);
}
} else if (responseCode == 200) {
var state;
@@ -144,6 +169,11 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
setUiToggle(state);
}
}
+ } else {
+ if (Globals.scDebug) {
+ System.println("HomeAssistantToggleMenuItem onReturnSetState(): Unhandled HTTP response code = " + responseCode);
+ }
+ WatchUi.pushView(new ErrorView(strUnhandledHttpErr + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
}
}
@@ -180,7 +210,7 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
);
} else {
if (Globals.scDebug) {
- System.println("HomeAssistantToggleMenuItem Note - setState(): No Internet connection, skipping API call.");
+ System.println("HomeAssistantToggleMenuItem setState(): No Internet connection, skipping API call.");
}
WatchUi.pushView(new ErrorView(strNoInternet + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
}