mirror of
https://github.com/house-of-abbey/GarminHomeAssistant.git
synced 2025-09-12 20:31:31 +00:00
Initial version
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">مؤكد</string>
|
||||
<string id="GlanceMenu" scope="glance">قائمة طعام</string>
|
||||
<string id="Memory" scope="glance">ذاكرة</string>
|
||||
<string id="MenuUpdated">محدثة القائمة ، إعادة التشغيل.</string>
|
||||
<string id="NoAPIKey" scope="glance">لا مفتاح API في إعدادات التطبيق.</string>
|
||||
<string id="NoApiUrl" scope="glance">لا عنوان URL API في إعدادات التطبيق.</string>
|
||||
<string id="NoConfigUrl" scope="glance">لا يوجد عنوان URL للتكوين في إعدادات التطبيق.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Потвърдено</string>
|
||||
<string id="GlanceMenu" scope="glance">Меню</string>
|
||||
<string id="Memory" scope="glance">Памет</string>
|
||||
<string id="MenuUpdated">Менюто актуализирано, рестартиране.</string>
|
||||
<string id="NoAPIKey" scope="glance">Няма ключ за API в настройките на приложението.</string>
|
||||
<string id="NoApiUrl" scope="glance">Няма URL адрес на API в настройките на приложението.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Няма URL адрес на конфигурация в настройките на приложението.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Potvrzeno</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Paměť</string>
|
||||
<string id="MenuUpdated">Aktualizováno nabídka, restartujte.</string>
|
||||
<string id="NoAPIKey" scope="glance">Žádný klíč API v nastavení aplikace.</string>
|
||||
<string id="NoApiUrl" scope="glance">Žádná URL API v nastavení aplikace.</string>
|
||||
<string id="NoConfigUrl" scope="glance">V nastavení aplikace není žádná konfigurační adresa URL.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Bekræftet</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Hukommelse</string>
|
||||
<string id="MenuUpdated">Menu opdateret, genstart.</string>
|
||||
<string id="NoAPIKey" scope="glance">Ingen API -nøgle i applikationsindstillingerne.</string>
|
||||
<string id="NoApiUrl" scope="glance">Ingen API -URL i applikationsindstillingerne.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Ingen konfigurations -URL i applikationsindstillingerne.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Bestätigt</string>
|
||||
<string id="GlanceMenu" scope="glance">Menü</string>
|
||||
<string id="Memory" scope="glance">Speicher</string>
|
||||
<string id="MenuUpdated">Menü aktualisiert, neu starten.</string>
|
||||
<string id="NoAPIKey" scope="glance">Kein API-Schlüssel in den App-Einstellungen hinterlegt.</string>
|
||||
<string id="NoApiUrl" scope="glance">Keine API-URL in den App-Einstellungen hinterlegt.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Keine Menükonfigurations-URL (JSON) in den App-Einstellungen hinterlegt.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Bevestigd</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Geheugen</string>
|
||||
<string id="MenuUpdated">Menu bijgewerkt, opnieuw opstarten.</string>
|
||||
<string id="NoAPIKey" scope="glance">Geen API -toets in de toepassingsinstellingen.</string>
|
||||
<string id="NoApiUrl" scope="glance">Geen API -URL in de toepassingsinstellingen.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Geen configuratie -URL in de toepassingsinstellingen.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Kinnitatud</string>
|
||||
<string id="GlanceMenu" scope="glance">Menüü</string>
|
||||
<string id="Memory" scope="glance">Mälu</string>
|
||||
<string id="MenuUpdated">Menüü värskendatud, taaskäivitage.</string>
|
||||
<string id="NoAPIKey" scope="glance">Rakenduse seadetes pole API -klahvi.</string>
|
||||
<string id="NoApiUrl" scope="glance">Rakenduse seadetes pole API URL -i.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Rakenduse sätetes pole konfiguratsiooni URL -i.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Vahvistettu</string>
|
||||
<string id="GlanceMenu" scope="glance">Valikko</string>
|
||||
<string id="Memory" scope="glance">Muisti</string>
|
||||
<string id="MenuUpdated">Valikko päivitetty, käynnistä uudelleen.</string>
|
||||
<string id="NoAPIKey" scope="glance">Ei sovellusliittymää avainta sovellusasetuksissa.</string>
|
||||
<string id="NoApiUrl" scope="glance">Ei sovellus -URL -osoitetta sovellusasetuksissa.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Ei määritys -URL -osoitetta sovellusasetuksissa.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Confirmé</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Mémoire</string>
|
||||
<string id="MenuUpdated">Menu mis à jour, redémarrer.</string>
|
||||
<string id="NoAPIKey" scope="glance">Aucune clé API dans les paramètres de l'application.</string>
|
||||
<string id="NoApiUrl" scope="glance">Aucune URL de l'API dans les paramètres de l'application.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Aucune URL de configuration dans les paramètres de l'application.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Επιβεβαιωμένος</string>
|
||||
<string id="GlanceMenu" scope="glance">Μενού</string>
|
||||
<string id="Memory" scope="glance">Μνήμη</string>
|
||||
<string id="MenuUpdated">Ενημερώθηκε μενού, επανεκκίνηση.</string>
|
||||
<string id="NoAPIKey" scope="glance">Δεν υπάρχει κλειδί API στις ρυθμίσεις εφαρμογής.</string>
|
||||
<string id="NoApiUrl" scope="glance">Δεν υπάρχει διεύθυνση URL API στις ρυθμίσεις εφαρμογής.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Χωρίς διευθύνσεις διαμόρφωσης στις ρυθμίσεις εφαρμογής.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">מְאוּשָׁר</string>
|
||||
<string id="GlanceMenu" scope="glance">תַפרִיט</string>
|
||||
<string id="Memory" scope="glance">זֵכֶר</string>
|
||||
<string id="MenuUpdated">מעודכן בתפריט, הפעל מחדש.</string>
|
||||
<string id="NoAPIKey" scope="glance">אין מפתח API בהגדרות היישום.</string>
|
||||
<string id="NoApiUrl" scope="glance">אין כתובת URL בהגדרות היישום.</string>
|
||||
<string id="NoConfigUrl" scope="glance">אין כתובת אתר תצורה בהגדרות היישום.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Potvrđen</string>
|
||||
<string id="GlanceMenu" scope="glance">Jelovnik</string>
|
||||
<string id="Memory" scope="glance">Memorija</string>
|
||||
<string id="MenuUpdated">Izbornik Ažurirano, ponovno pokrenite.</string>
|
||||
<string id="NoAPIKey" scope="glance">Nema API ključa u postavkama aplikacije.</string>
|
||||
<string id="NoApiUrl" scope="glance">Nema URL -a API -ja u postavkama aplikacije.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Nema URL -a konfiguracije u postavkama aplikacije.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Megerősített</string>
|
||||
<string id="GlanceMenu" scope="glance">Menü</string>
|
||||
<string id="Memory" scope="glance">Emlékezet</string>
|
||||
<string id="MenuUpdated">A menü frissítve, indítsa újra.</string>
|
||||
<string id="NoAPIKey" scope="glance">Nincs API -kulcs az alkalmazásbeállításokban.</string>
|
||||
<string id="NoApiUrl" scope="glance">Nincs API URL az alkalmazás beállításaiban.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Nincs konfigurációs URL az alkalmazásbeállításokban.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Dikonfirmasi</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Ingatan</string>
|
||||
<string id="MenuUpdated">Menu diperbarui, restart.</string>
|
||||
<string id="NoAPIKey" scope="glance">Tidak ada kunci API di pengaturan aplikasi.</string>
|
||||
<string id="NoApiUrl" scope="glance">Tidak ada URL API di pengaturan aplikasi.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Tidak ada URL konfigurasi di pengaturan aplikasi.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Confermato</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Memoria</string>
|
||||
<string id="MenuUpdated">Menu aggiornato, riavvio.</string>
|
||||
<string id="NoAPIKey" scope="glance">Nessuna chiave API nelle impostazioni dell'applicazione.</string>
|
||||
<string id="NoApiUrl" scope="glance">Nessun URL API nelle impostazioni dell'applicazione.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Nessun URL di configurazione nelle impostazioni dell'applicazione.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">確認済み</string>
|
||||
<string id="GlanceMenu" scope="glance">メニュー</string>
|
||||
<string id="Memory" scope="glance">メモリ</string>
|
||||
<string id="MenuUpdated">メニューの更新、再起動。</string>
|
||||
<string id="NoAPIKey" scope="glance">アプリケーション設定にAPIキーはありません。</string>
|
||||
<string id="NoApiUrl" scope="glance">アプリケーション設定にAPI URLはありません。</string>
|
||||
<string id="NoConfigUrl" scope="glance">アプリケーション設定に構成URLはありません。</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">확인</string>
|
||||
<string id="GlanceMenu" scope="glance">메뉴</string>
|
||||
<string id="Memory" scope="glance">메모리</string>
|
||||
<string id="MenuUpdated">메뉴가 업데이트되고 다시 시작됩니다.</string>
|
||||
<string id="NoAPIKey" scope="glance">응용 프로그램 설정에 API 키가 없습니다.</string>
|
||||
<string id="NoApiUrl" scope="glance">응용 프로그램 설정에 API URL이 없습니다.</string>
|
||||
<string id="NoConfigUrl" scope="glance">응용 프로그램 설정에 구성 URL이 없습니다.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Apstiprināts</string>
|
||||
<string id="GlanceMenu" scope="glance">Ēdienkarte</string>
|
||||
<string id="Memory" scope="glance">Atmiņa</string>
|
||||
<string id="MenuUpdated">Atjaunināta izvēlne, restartējiet.</string>
|
||||
<string id="NoAPIKey" scope="glance">Lietojumprogrammas iestatījumos nav API atslēgas.</string>
|
||||
<string id="NoApiUrl" scope="glance">Lietojumprogrammu iestatījumos nav API URL.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Lietojumprogrammas iestatījumos nav konfigurācijas URL.</string>
|
||||
@@ -54,7 +55,7 @@
|
||||
<string id="WifiLtePrompt">Izpildīt pār wi-fi/lte?</string>
|
||||
<string id="WifiLteExecutionTitle">Sūtot mājas palīgu.</string>
|
||||
<string id="WifiLteExecutionDataError">Dati nav saņemti.</string>
|
||||
<!-- Iestatījumi GUI stīgām jābūt tādā secībā, kādā tās tiek izmantotas. -->
|
||||
<!-- Iestatījumi GUI stīgām jābūt tādā secībā, kādu tie tiek izmantoti. -->
|
||||
<string id="SettingsSelect">Atlasiet ...</string>
|
||||
<string id="SettingsApiKey">API atslēga Homeassistant.</string>
|
||||
<string id="SettingsApiKeyPrompt">Ilgstoša piekļuves marķieris.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Patvirtinta</string>
|
||||
<string id="GlanceMenu" scope="glance">Meniu</string>
|
||||
<string id="Memory" scope="glance">Atmintis</string>
|
||||
<string id="MenuUpdated">Meniu Atnaujinta, paleiskite iš naujo.</string>
|
||||
<string id="NoAPIKey" scope="glance">Nėra API rakto programos nustatymuose.</string>
|
||||
<string id="NoApiUrl" scope="glance">Nėra API URL programos nustatymuose.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Nėra konfigūracijos URL programos nustatymuose.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Bekreftet</string>
|
||||
<string id="GlanceMenu" scope="glance">Meny</string>
|
||||
<string id="Memory" scope="glance">Hukommelse</string>
|
||||
<string id="MenuUpdated">Meny oppdatert, omstart.</string>
|
||||
<string id="NoAPIKey" scope="glance">Ingen API -nøkkel i applikasjonsinnstillingene.</string>
|
||||
<string id="NoApiUrl" scope="glance">Ingen API -URL i applikasjonsinnstillingene.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Ingen konfigurasjons -URL i applikasjonsinnstillingene.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Potwierdzony</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Pamięć</string>
|
||||
<string id="MenuUpdated">Zaktualizowano menu, uruchom ponownie.</string>
|
||||
<string id="NoAPIKey" scope="glance">Brak klucza API w ustawieniach aplikacji.</string>
|
||||
<string id="NoApiUrl" scope="glance">Brak adresu URL API w ustawieniach aplikacji.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Brak adresu URL konfiguracji w ustawieniach aplikacji.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Confirmado</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Memória</string>
|
||||
<string id="MenuUpdated">Menu Atualizado, reinicie.</string>
|
||||
<string id="NoAPIKey" scope="glance">Nenhuma chave da API nas configurações do aplicativo.</string>
|
||||
<string id="NoApiUrl" scope="glance">Nenhum URL da API nas configurações do aplicativo.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Nenhum URL de configuração nas configurações do aplicativo.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Confirmat</string>
|
||||
<string id="GlanceMenu" scope="glance">Meniu</string>
|
||||
<string id="Memory" scope="glance">Memorie</string>
|
||||
<string id="MenuUpdated">Meniu actualizat, reporniți.</string>
|
||||
<string id="NoAPIKey" scope="glance">Nici o cheie API în setările aplicației.</string>
|
||||
<string id="NoApiUrl" scope="glance">Fără URL API în setările aplicației.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Fără URL de configurare în setările aplicației.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Spustený</string>
|
||||
<string id="GlanceMenu" scope="glance">Ponuka</string>
|
||||
<string id="Memory" scope="glance">Pamiatka</string>
|
||||
<string id="MenuUpdated">Aktualizované menu, reštart.</string>
|
||||
<string id="NoAPIKey" scope="glance">V nastaveniach aplikácie chýba kľúč API</string>
|
||||
<string id="NoApiUrl" scope="glance">V nastaveniach aplikácie chýba adresa URL rozhrania API</string>
|
||||
<string id="NoConfigUrl" scope="glance">V nastaveniach aplikácie chýba konfiguračná adresa URL</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Potrjeno</string>
|
||||
<string id="GlanceMenu" scope="glance">Meni</string>
|
||||
<string id="Memory" scope="glance">Spomin</string>
|
||||
<string id="MenuUpdated">Meni posodobljen, znova zaženite.</string>
|
||||
<string id="NoAPIKey" scope="glance">V nastavitvah aplikacije ni ključa API -ja.</string>
|
||||
<string id="NoApiUrl" scope="glance">V nastavitvah aplikacije ni URL API -ja.</string>
|
||||
<string id="NoConfigUrl" scope="glance">V nastavitvah aplikacije ni URL konfiguracije.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Confirmado</string>
|
||||
<string id="GlanceMenu" scope="glance">Menú</string>
|
||||
<string id="Memory" scope="glance">Memoria</string>
|
||||
<string id="MenuUpdated">Menú actualizado, reiniciar.</string>
|
||||
<string id="NoAPIKey" scope="glance">No hay clave API en la configuración de la aplicación.</string>
|
||||
<string id="NoApiUrl" scope="glance">No hay URL de API en la configuración de la aplicación.</string>
|
||||
<string id="NoConfigUrl" scope="glance">No hay URL de configuración en la configuración de la aplicación.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Bekräftad</string>
|
||||
<string id="GlanceMenu" scope="glance">Meny</string>
|
||||
<string id="Memory" scope="glance">Minne</string>
|
||||
<string id="MenuUpdated">Meny Uppdaterad, omstart.</string>
|
||||
<string id="NoAPIKey" scope="glance">Ingen API -nyckel i applikationsinställningarna.</string>
|
||||
<string id="NoApiUrl" scope="glance">Ingen API -URL i applikationsinställningarna.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Ingen konfigurations -URL i applikationsinställningarna.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">ที่ได้ยืนยันแล้ว</string>
|
||||
<string id="GlanceMenu" scope="glance">เมนู</string>
|
||||
<string id="Memory" scope="glance">หน่วยความจำ</string>
|
||||
<string id="MenuUpdated">อัปเดตเมนูรีสตาร์ท</string>
|
||||
<string id="NoAPIKey" scope="glance">ไม่มีคีย์ API ในการตั้งค่าแอปพลิเคชัน</string>
|
||||
<string id="NoApiUrl" scope="glance">ไม่มี URL API ในการตั้งค่าแอปพลิเคชัน</string>
|
||||
<string id="NoConfigUrl" scope="glance">ไม่มี URL การกำหนดค่าในการตั้งค่าแอปพลิเคชัน</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Onaylanmış</string>
|
||||
<string id="GlanceMenu" scope="glance">Menü</string>
|
||||
<string id="Memory" scope="glance">Hafıza</string>
|
||||
<string id="MenuUpdated">Menü güncellendi, yeniden başlat.</string>
|
||||
<string id="NoAPIKey" scope="glance">Uygulama ayarlarında API anahtarı yok.</string>
|
||||
<string id="NoApiUrl" scope="glance">Uygulama ayarlarında API URL'si yok.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Uygulama ayarlarında yapılandırma URL'si yok.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Підтверджений</string>
|
||||
<string id="GlanceMenu" scope="glance">Меню</string>
|
||||
<string id="Memory" scope="glance">Пам'ять</string>
|
||||
<string id="MenuUpdated">Меню оновлено, перезапустіть.</string>
|
||||
<string id="NoAPIKey" scope="glance">Немає ключа API в налаштуваннях програми.</string>
|
||||
<string id="NoApiUrl" scope="glance">Немає URL -адреси API в налаштуваннях програми.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Немає URL -адреси конфігурації в налаштуваннях програми.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Xác nhận</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Ký ức</string>
|
||||
<string id="MenuUpdated">Menu được cập nhật, khởi động lại.</string>
|
||||
<string id="NoAPIKey" scope="glance">Không có khóa API trong cài đặt ứng dụng.</string>
|
||||
<string id="NoApiUrl" scope="glance">Không có URL API trong cài đặt ứng dụng.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Không có URL cấu hình trong cài đặt ứng dụng.</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">确认的</string>
|
||||
<string id="GlanceMenu" scope="glance">菜单</string>
|
||||
<string id="Memory" scope="glance">记忆</string>
|
||||
<string id="MenuUpdated">菜单更新,重新启动。</string>
|
||||
<string id="NoAPIKey" scope="glance">应用程序设置中没有API密钥。</string>
|
||||
<string id="NoApiUrl" scope="glance">应用程序设置中没有API URL。</string>
|
||||
<string id="NoConfigUrl" scope="glance">应用程序设置中没有配置URL。</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">確認的</string>
|
||||
<string id="GlanceMenu" scope="glance">菜單</string>
|
||||
<string id="Memory" scope="glance">記憶</string>
|
||||
<string id="MenuUpdated">菜單更新,重新啟動。</string>
|
||||
<string id="NoAPIKey" scope="glance">應用程序設置中沒有API密鑰。</string>
|
||||
<string id="NoApiUrl" scope="glance">應用程序設置中沒有API URL。</string>
|
||||
<string id="NoConfigUrl" scope="glance">應用程序設置中沒有配置URL。</string>
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<string id="Executed" scope="glance">Disahkan</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Ingatan</string>
|
||||
<string id="MenuUpdated">Menu dikemas kini, mulakan semula.</string>
|
||||
<string id="NoAPIKey" scope="glance">Tiada kunci API dalam tetapan aplikasi.</string>
|
||||
<string id="NoApiUrl" scope="glance">Tiada URL API dalam tetapan aplikasi.</string>
|
||||
<string id="NoConfigUrl" scope="glance">Tiada URL Konfigurasi dalam Tetapan Aplikasi.</string>
|
||||
|
@@ -25,6 +25,7 @@
|
||||
<string id="Executed" scope="glance">Confirmed</string>
|
||||
<string id="GlanceMenu" scope="glance">Menu</string>
|
||||
<string id="Memory" scope="glance">Memory</string>
|
||||
<string id="MenuUpdated">Menu updated, restart.</string>
|
||||
<string id="NoAPIKey" scope="glance">No API key in the application settings.</string>
|
||||
<string id="NoApiUrl" scope="glance">No API URL in the application settings.</string>
|
||||
<string id="NoConfigUrl" scope="glance">No configuration URL in the application settings.</string>
|
||||
|
@@ -16,6 +16,8 @@
|
||||
using Toybox.Application;
|
||||
using Toybox.Communications;
|
||||
using Toybox.Lang;
|
||||
// Required for callback method definition
|
||||
typedef Method as Toybox.Lang.Method;
|
||||
using Toybox.WatchUi;
|
||||
using Toybox.System;
|
||||
using Toybox.Application.Properties;
|
||||
@@ -40,6 +42,7 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
private var mUpdating as Lang.Boolean = false; // Don't start a second chain of updates
|
||||
private var mTemplates as Lang.Dictionary = {};
|
||||
private var mNotifiedNoBle as Lang.Boolean = false;
|
||||
private var mIsCacheChecked as Lang.Boolean = false;
|
||||
|
||||
//! Class Constructor
|
||||
//
|
||||
@@ -257,39 +260,14 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
} else {
|
||||
var menu = Storage.getValue("menu") as Lang.Dictionary;
|
||||
if (menu != null and (Settings.getClearCache() || !Settings.getCacheConfig())) {
|
||||
// System.println("HomeAssistantApp fetchMenuConfig(): Clearing cached menu on user request.");
|
||||
Storage.deleteValue("menu");
|
||||
menu = null;
|
||||
Settings.unsetClearCache();
|
||||
}
|
||||
if (menu == null) {
|
||||
var phoneConnected = System.getDeviceSettings().phoneConnected;
|
||||
var internetAvailable = System.getDeviceSettings().connectionAvailable;
|
||||
if (! phoneConnected or ! internetAvailable) {
|
||||
// System.println("HomeAssistantApp fetchMenuConfig(): No Phone connection, skipping API call.");
|
||||
var errorRez = $.Rez.Strings.NoPhone;
|
||||
if (Settings.getWifiLteExecutionEnabled()) {
|
||||
errorRez = $.Rez.Strings.NoPhoneNoCache;
|
||||
} else if (! internetAvailable) {
|
||||
errorRez = $.Rez.Strings.Unavailable;
|
||||
}
|
||||
if (!mIsApp) {
|
||||
WatchUi.requestUpdate();
|
||||
} else {
|
||||
ErrorView.show(WatchUi.loadResource(errorRez) as Lang.String);
|
||||
}
|
||||
mMenuStatus = WatchUi.loadResource(errorRez) as Lang.String;
|
||||
} else {
|
||||
Communications.makeWebRequest(
|
||||
Settings.getConfigUrl(),
|
||||
null,
|
||||
{
|
||||
:method => Communications.HTTP_REQUEST_METHOD_GET,
|
||||
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON,
|
||||
:headers => Settings.augmentHttpHeaders({})
|
||||
},
|
||||
method(:onReturnFetchMenuConfig)
|
||||
);
|
||||
}
|
||||
// System.println("HomeAssistantApp fetchMenuConfig(): Menu not cached, fetching.");
|
||||
fetchMenuConfigBasic(method(:onReturnFetchMenuConfig));
|
||||
} else {
|
||||
mMenuStatus = WatchUi.loadResource($.Rez.Strings.Cached) as Lang.String;
|
||||
WatchUi.requestUpdate();
|
||||
@@ -304,6 +282,56 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
//! The basic API call to fetch the menu configuration, with cache management issues managed by external supporting
|
||||
//! code. This is factored out separately so that it can be reused to check and validate the cached menu.
|
||||
//!
|
||||
//! @param responseCallback The method to call on completion of the GET request.
|
||||
//
|
||||
function fetchMenuConfigBasic(
|
||||
responseCallback as (
|
||||
Method(
|
||||
responseCode as Lang.Number,
|
||||
data as Lang.Dictionary or Lang.String or Null
|
||||
) as Void
|
||||
) or (
|
||||
Method(
|
||||
responseCode as Lang.Number,
|
||||
data as Lang.Dictionary or Lang.String or Null,
|
||||
context as Lang.Object
|
||||
) as Void
|
||||
)
|
||||
) {
|
||||
// System.println("HomeAssistantApp fetchMenuConfigBasic(): Fetching JSON menu.");
|
||||
var phoneConnected = System.getDeviceSettings().phoneConnected;
|
||||
var internetAvailable = System.getDeviceSettings().connectionAvailable;
|
||||
if (! phoneConnected or ! internetAvailable) {
|
||||
// System.println("HomeAssistantApp fetchMenuConfigBasic(): No Phone connection, skipping API call.");
|
||||
var errorRez = $.Rez.Strings.NoPhone;
|
||||
if (Settings.getWifiLteExecutionEnabled()) {
|
||||
errorRez = $.Rez.Strings.NoPhoneNoCache;
|
||||
} else if (! internetAvailable) {
|
||||
errorRez = $.Rez.Strings.Unavailable;
|
||||
}
|
||||
if (!mIsApp) {
|
||||
WatchUi.requestUpdate();
|
||||
} else {
|
||||
ErrorView.show(WatchUi.loadResource(errorRez) as Lang.String);
|
||||
}
|
||||
mMenuStatus = WatchUi.loadResource(errorRez) as Lang.String;
|
||||
} else {
|
||||
Communications.makeWebRequest(
|
||||
Settings.getConfigUrl(),
|
||||
null,
|
||||
{
|
||||
:method => Communications.HTTP_REQUEST_METHOD_GET,
|
||||
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON,
|
||||
:headers => Settings.augmentHttpHeaders({})
|
||||
},
|
||||
responseCallback
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//! Build the menu and store in `mHaMenu`. Then start updates if necessary.
|
||||
//!
|
||||
//! @param menu The dictionary derived from the JSON menu fetched by `fetchMenuConfig()`.
|
||||
@@ -342,6 +370,146 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
}
|
||||
}
|
||||
|
||||
//! Test if two dictionaries are structurally equal. Used to see if the JSON menu has been
|
||||
//! amended but yet to be updated in the application cache.
|
||||
//!
|
||||
//! @param a First dictionary in the comparison.
|
||||
//! @param b Second dictionary in the comparison.
|
||||
//
|
||||
function structuralEquals(
|
||||
a as Lang.Dictionary,
|
||||
b as Lang.Dictionary
|
||||
) as Lang.Boolean {
|
||||
if (a.size() != b.size()) {
|
||||
return false;
|
||||
}
|
||||
var keys = a.keys();
|
||||
for (var i = 0; i < keys.size(); i++) {
|
||||
var key = keys[i];
|
||||
if (!b.hasKey(key)) {
|
||||
return false;
|
||||
}
|
||||
var valA = a.get(key);
|
||||
var valB = b.get(key);
|
||||
if (valA instanceof Lang.Dictionary and valB instanceof Lang.Dictionary) {
|
||||
if (!structuralEquals(valA, valB)) {
|
||||
return false;
|
||||
}
|
||||
} else if (valA instanceof Lang.Array and valB instanceof Lang.Array) {
|
||||
var arrA = valA as Lang.Array;
|
||||
var arrB = valB as Lang.Array;
|
||||
if (arrA.size() != arrB.size()) {
|
||||
return false;
|
||||
}
|
||||
for (var j = 0; j < arrA.size(); j++) {
|
||||
var itemA = arrA[j];
|
||||
var itemB = arrB[j];
|
||||
if (itemA instanceof Lang.Dictionary and itemB instanceof Lang.Dictionary) {
|
||||
if (!structuralEquals(itemA, itemB)) {
|
||||
return false;
|
||||
}
|
||||
} else if (!itemA.equals(itemB)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (!valA.equals(valB)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Callback function for the menu check GET request.
|
||||
//!
|
||||
//! @param responseCode Response code.
|
||||
//! @param data Response data.
|
||||
//
|
||||
function onReturnCheckMenuConfig(
|
||||
responseCode as Lang.Number,
|
||||
data as Null or Lang.Dictionary
|
||||
) as Void {
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig() Response Code: " + responseCode);
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig() Response Data: " + data);
|
||||
|
||||
switch (responseCode) {
|
||||
case Communications.BLE_HOST_TIMEOUT:
|
||||
case Communications.BLE_CONNECTION_UNAVAILABLE:
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed.");
|
||||
ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoPhone) as Lang.String);
|
||||
break;
|
||||
|
||||
case Communications.BLE_QUEUE_FULL:
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig() Response Code: BLE_QUEUE_FULL, API calls too rapid.");
|
||||
ErrorView.show(WatchUi.loadResource($.Rez.Strings.ApiFlood) as Lang.String);
|
||||
break;
|
||||
|
||||
case Communications.NETWORK_REQUEST_TIMED_OUT:
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection.");
|
||||
ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoResponse) as Lang.String);
|
||||
break;
|
||||
|
||||
case Communications.INVALID_HTTP_BODY_IN_NETWORK_RESPONSE:
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig() Response Code: INVALID_HTTP_BODY_IN_NETWORK_RESPONSE, check JSON is returned.");
|
||||
ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoJson) as Lang.String);
|
||||
break;
|
||||
|
||||
case Communications.NETWORK_RESPONSE_OUT_OF_MEMORY:
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig() Response Code: NETWORK_RESPONSE_OUT_OF_MEMORY, are we going too fast?");
|
||||
var myTimer = new Timer.Timer();
|
||||
// Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer.
|
||||
myTimer.start(method(:updateMenuItems), Globals.scApiBackoffMs, false);
|
||||
break;
|
||||
|
||||
case 404:
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig() Response Code: 404, page not found. Check API URL setting.");
|
||||
ErrorView.show(WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound) as Lang.String);
|
||||
break;
|
||||
|
||||
case 400:
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig() Response Code: 400, bad request. Template error.");
|
||||
ErrorView.show(WatchUi.loadResource($.Rez.Strings.TemplateError) as Lang.String);
|
||||
break;
|
||||
|
||||
case 200:
|
||||
if (data != null) {
|
||||
// 'menu' will be null if caching has just been enabled, but not yet cached locally.
|
||||
var menu = Storage.getValue("menu") as Lang.Dictionary;
|
||||
if (menu == null || !structuralEquals(data, menu)) {
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig() New menu found.");
|
||||
Storage.setValue("menu", data as Lang.Dictionary);
|
||||
if (menu != null) {
|
||||
// Notify the the user we have just got a newer menu file
|
||||
var toast = WatchUi.loadResource($.Rez.Strings.MenuUpdated) as Lang.String;
|
||||
if (mHasToast) {
|
||||
WatchUi.showToast(toast, null);
|
||||
} else {
|
||||
new Alert({
|
||||
:timeout => Globals.scAlertTimeoutMs,
|
||||
:font => Graphics.FONT_MEDIUM,
|
||||
:text => toast,
|
||||
:fgcolor => Graphics.COLOR_WHITE,
|
||||
:bgcolor => Graphics.COLOR_BLACK
|
||||
}).pushView(WatchUi.SLIDE_IMMEDIATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Prevent checking the cache is up to date again
|
||||
mIsCacheChecked = true;
|
||||
var delay = Settings.getPollDelay();
|
||||
if (delay > 0) {
|
||||
mUpdateTimer.start(method(:updateMenuItems), delay, false);
|
||||
} else {
|
||||
updateMenuItems();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// System.println("HomeAssistantApp onReturnCheckMenuConfig(): Unhandled HTTP response code = " + responseCode);
|
||||
ErrorView.show(WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr) as Lang.String + responseCode);
|
||||
}
|
||||
}
|
||||
|
||||
//! Callback function for each menu update GET request.
|
||||
//!
|
||||
//! @param responseCode Response code.
|
||||
@@ -405,18 +573,23 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
} else {
|
||||
if (mItemsToUpdate != null) {
|
||||
for (var i = 0; i < mItemsToUpdate.size(); i++) {
|
||||
var item = mItemsToUpdate[i];
|
||||
var item = mItemsToUpdate[i];
|
||||
var state = data.get(i.toString());
|
||||
item.updateState(state);
|
||||
if (item instanceof HomeAssistantToggleMenuItem) {
|
||||
(item as HomeAssistantToggleMenuItem).updateToggleState(data.get(i.toString() + "t"));
|
||||
}
|
||||
}
|
||||
var delay = Settings.getPollDelay();
|
||||
if (delay > 0) {
|
||||
mUpdateTimer.start(method(:updateMenuItems), delay, false);
|
||||
if (Settings.getCacheConfig() && !mIsCacheChecked) {
|
||||
// We are caching the menu configuration, so let's fetch it and check if its been updated.
|
||||
fetchMenuConfigBasic(method(:onReturnCheckMenuConfig));
|
||||
} else {
|
||||
updateMenuItems();
|
||||
var delay = Settings.getPollDelay();
|
||||
if (delay > 0) {
|
||||
mUpdateTimer.start(method(:updateMenuItems), delay, false);
|
||||
} else {
|
||||
updateMenuItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -605,7 +778,6 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
if (!mIsApp) {
|
||||
WatchUi.requestUpdate();
|
||||
} else {
|
||||
System.println("we here");
|
||||
ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoPhone) as Lang.String);
|
||||
}
|
||||
} else if (! connectionAvailable) {
|
||||
|
@@ -14,8 +14,6 @@
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
using Toybox.Lang;
|
||||
// Required for callback method definition
|
||||
typedef Method as Toybox.Lang.Method;
|
||||
using Toybox.WatchUi;
|
||||
using Toybox.Timer;
|
||||
using Toybox.Application.Properties;
|
||||
|
@@ -128,18 +128,18 @@ class HomeAssistantService {
|
||||
data as Lang.Dictionary?,
|
||||
exit as Lang.Boolean
|
||||
) as Void {
|
||||
var phoneConnected = System.getDeviceSettings().phoneConnected;
|
||||
var phoneConnected = System.getDeviceSettings().phoneConnected;
|
||||
var internetAvailable = System.getDeviceSettings().connectionAvailable;
|
||||
if (Settings.getWifiLteExecutionEnabled() && (! phoneConnected || ! internetAvailable)) {
|
||||
var dialogMsg = WatchUi.loadResource($.Rez.Strings.WifiLtePrompt) as Lang.String;
|
||||
var dialog = new WatchUi.Confirmation(dialogMsg);
|
||||
var dialog = new WatchUi.Confirmation(dialogMsg);
|
||||
WatchUi.pushView(
|
||||
dialog,
|
||||
new WifiLteExecutionConfirmDelegate({
|
||||
:type => "service",
|
||||
:type => "service",
|
||||
:service => service,
|
||||
:data => data,
|
||||
:exit => exit,
|
||||
:data => data,
|
||||
:exit => exit,
|
||||
}, dialog),
|
||||
WatchUi.SLIDE_LEFT
|
||||
);
|
||||
|
Reference in New Issue
Block a user