Skip to content

Commit

Permalink
New glance and widget views
Browse files Browse the repository at this point in the history
Added ability to test if we're a widget or a watch-app. Added troubleshooting documentation.
  • Loading branch information
philipabbey committed Dec 21, 2023
1 parent 4e739e9 commit 3934ca5
Show file tree
Hide file tree
Showing 61 changed files with 1,073 additions and 539 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ The application is designed around a simple scrollable menu where menu items hav

It is important to note that your Home Assistant instance will need to be accessible via HTTPS with public SSL or all requests from the Garmin will not work. This cannot be a self-signed certificate, it must be a public certificate (You can get one for free from [Let's Encrypt](https://letsencrypt.org/) or you can pay for [Home Assistant cloud](https://www.nabucasa.com/)).

**If you are struggling with getting the application to work, please consult the [trouble shooting](Troubleshooting.md) guide first.**

## Widget or Application?

As of version 2.0, there are now two installable versions. For older devices before applications supported 'glances', there is a now widget version.
Expand Down Expand Up @@ -168,8 +170,8 @@ This allows the `confirm` field to be accommodated in the `tap_action` along sid

You have options. The first is what we use.
1. **Best!** Use the [Studio Code Server](https://community.home-assistant.io/t/home-assistant-community-add-on-visual-studio-code/107863) addon for Home Assistant. You can then edit your JSON file in place.
2. Locally installed VSCode, or if not installed
3. try the on-line version at https://vscode.dev/
2. Locally installed VSCode, or if not installed,
3. try the on-line version at https://vscode.dev/.

Paste in your JSON (and change the file type to JSON if not saving), it will then verify your file format and schema for you, highlighting any errors for you to fix.

Expand Down
107 changes: 107 additions & 0 deletions Troubleshooting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Troubleshooting Guide

With either of the following setups, there are inevitably some problems along the way. GarminHomeAssistant is careful to rely only on having working URLs. Getting them working is the user's responsibility. However, we have developed some fault finding tools.

## Nabu Casa Setup

You can purchase cloud-based access to your Home Assistant from [Nabu Casa](https://www.nabucasa.com/), and then your setup will look something like this.

![Nabu Casa Setup](images/nabu_casa_setup.png)

* Your API URL would be of the format `https://<id>.ui.nabu.casa/api`
* Your Garmin Watch Menu would be of the format Menu: `https://<id>.ui.nabu.casa/local/garmin/menu.json`

Where `<id>` is your personal Nabu Casa account ID.

## Do It Yourself Setup

Before Nabu Casa, or if you wanted to manage your own infrastructure, you might have something like the following:

![Do It Yourself Setup](images/do_it_yourself_setup.png)

Now you have to manage:

* Dynamic DNS
* Public access via router port forwarding
* Security via HTTPS and URL forwarding
* Certificates for HTTPS via say [Let's Encrypt](https://letsencrypt.org/) (Nginx web server helps here)
* Proxy allow list in `configuration.yaml` as follows:

```yaml
http:
use_x_forwarded_for: true
trusted_proxies:
- 127.0.0.1
- 192.168.xx.xx # Server IP - AMEND THIS
- 172.30.32.0/23 # Docker IPs for NGINX
- 172.30.33.0/24 # SSL proxy server
- 172.16.0.0/12 #
```
## Menu Configuration URL
This URL is very simple, you should be able to read the contents returned in a standard web browser.
![Browser Address Bar URL](images/menu_url.png)
(Other browsers are available...)
The browser page should then display the JSON string you saved to the file on the web server. The point is this is a simple HTTP GET request with no bells and whistles.
The menu configuration can be hosted anywhere, it does not have to be on the Home Assistant web server. Just as long as it is reachable from your phone from which you Bluetooth connect to your watch, or you watch if it has direct Internet access.
## Home Assistant API URL
This is slightly trickier owning to the need to supply the API key. Here are three ways you can test your API URL is correctly configured. If successful, each of these should produce a JSON string output looking like:
```json
{"message":"API running."}
```

### Linux, MacOS, UNIX, Cygwin etc

Save the following as a file called `api_test.sh`, edit to include your personal values for the variables, `chmod +x api_test.sh` and then execute with `./api_test.sh`.

```shell
#!/bin/bash

API_KEY="<Your API key>"
URL="https://<Your Domain>/api"

curl -s -X GET \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
${URL}/
```

### MS Windows

Save the following as a file called `api_test.cmd`, edit to include your personal values for the variables and then double click.

```shell
@echo off

set API_KEY=<Your API key>
set URL=https://<Your Domain>/api

curl -s -X GET ^
-H "Authorization: Bearer %API_KEY%" ^
-H "Content-Type: application/json" ^
%URL%/

echo.
pause
```

![API Test MS-DOS Output](images/api_test_dos_output.png)

### On-line

There's an online way of testing the API URL too, thanks to [REQBIN](https://reqbin.com/post-online). This has less setup and it can be saved if you log into the web site.

![API Test MS-DOS Output](images/api_test_online.png)

## Top Problems

1. Failure to copy & paste keys and URLs leading to minor and hard to see errors in strings, even with protestations they are the same! (No they weren't...)
2. Accessibility of URLs, hence the above help guide.
6 changes: 6 additions & 0 deletions export.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ set JAVA_PATH=C:\Program Files (x86)\Common Files\Oracle\Java\javapath
rem SDK_PATH should work for all users
set /p SDK_PATH=<"%USERPROFILE%\AppData\Roaming\Garmin\ConnectIQ\current-sdk.cfg"
set SDK_PATH=%SDK_PATH:~0,-1%\bin
rem Assume we can create and use this directory
set DEST=export

rem C:\>java -jar %SDK_PATH%\monkeybrains.jar -h
rem usage: monkeyc [-a <arg>] [-b <arg>] [--build-stats <arg>] [-c <arg>] [-d <arg>]
Expand Down Expand Up @@ -69,6 +71,10 @@ set SRC=%~dp0
rem drop last character '\'
set SRC=%SRC:~0,-1%

if not exist %DEST% (
md %DEST%
)

if exist %SRC%\export\HomeAssistant*.iq (
del /f /q %SRC%\export\HomeAssistant*.iq
)
Expand Down
Binary file added images/Actual_Venu2_LeanUI_500.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Actual_Venu2_Theme_500.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/api_test_dos_output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/api_test_online.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/do_it_yourself_setup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/menu_url.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/nabu_casa_setup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/source/Network_Generic.pptx
Binary file not shown.
28 changes: 28 additions & 0 deletions include/app/WidgetApp.mc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//-----------------------------------------------------------------------------------
//
// 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, 20 December 2023
//
//
// Description:
//
// A tedious diversion intended to make it possible to have the same source code for
// both a widget and an application. This file provides a single constant to
// determine which, and then the source file is conditionally included by the each
// .jungle file.
//
//-----------------------------------------------------------------------------------

using Toybox.Lang;

class WidgetApp {
static const isWidget = false;
}
28 changes: 28 additions & 0 deletions include/widget/WidgetApp.mc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//-----------------------------------------------------------------------------------
//
// 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, 20 December 2023
//
//
// Description:
//
// A tedious diversion intended to make it possible to have the same source code for
// both a widget and an application. This file provides a single constant to
// determine which, and then the source file is conditionally included by the each
// .jungle file.
//
//-----------------------------------------------------------------------------------

using Toybox.Lang;

class WidgetApp {
static const isWidget = true;
}
7 changes: 7 additions & 0 deletions manifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,14 @@
Use "Monkey C: Edit Application" from the Visual Studio Code command palette
to update the application attributes.
-->
<!--
Testing in VSCode requires monkey.jungle, so for convenience, swap between
watch-app and widget by changing which of the next two lines are commented out
-->
<iq:application id="98c36259-498a-4458-9cef-74a273ad2bc3" type="watch-app" name="@Strings.AppName" entry="HomeAssistantApp" launcherIcon="@Drawables.LauncherIcon" minApiLevel="3.1.0">
<!--
<iq:application id="4901cdfb-b4a2-4f33-96c7-f5be5992809e" type="widget" name="@Strings.AppName" entry="HomeAssistantApp" launcherIcon="@Drawables.LauncherIcon" minApiLevel="3.1.0">
-->
<!--
Use the following from the Visual Studio Code comand palette to edit
the build targets:
Expand Down
2 changes: 2 additions & 0 deletions monkey-widget.jungle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

project.manifest = manifest-widget.xml

base.sourcePath = source;include/widget

# Device References
# * https://developer.garmin.com/connect-iq/compatible-devices/
# * https://developer.garmin.com/connect-iq/reference-guides/devices-reference/
Expand Down
5 changes: 5 additions & 0 deletions monkey.jungle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@

project.manifest = manifest.xml

# Testing in VSCode requires monkey.jungle, so for convenience, swap between
# watch-app and widget by changing which of the next two lines are commented out
base.sourcePath = source;include/app
#base.sourcePath = source;include/widget

# Device References
# * https://developer.garmin.com/connect-iq/compatible-devices/
# * https://developer.garmin.com/connect-iq/reference-guides/devices-reference/
Expand Down
17 changes: 9 additions & 8 deletions resources-ara/strings/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,22 @@
<string id="MenuItemTap">مقبض</string>
<string id="MenuItemMenu">قائمة طعام</string>
<string id="Confirm">بالتأكيد؟</string>
<string id="NoPhone">لا يوجد اتصال الهاتف</string>
<string id="NoPhone" scope="glance">لا يوجد اتصال الهاتف</string>
<string id="NoInternet">لا يوجد اتصال بالإنترنت</string>
<string id="NoResponse">لا توجد استجابة، تحقق من الاتصال بالإنترنت</string>
<string id="NoMenu">خطأ في إحضار القائمة</string>
<string id="NoAPIKey">لا يوجد مفتاح API في إعدادات التطبيق</string>
<string id="NoApiUrl">لا يوجد عنوان URL لواجهة برمجة التطبيقات في إعدادات التطبيق</string>
<string id="NoConfigUrl">لا يوجد عنوان URL للتكوين في إعدادات التطبيق</string>
<string id="NoAPIKey" scope="glance">لا يوجد مفتاح API في إعدادات التطبيق</string>
<string id="NoApiUrl" scope="glance">لا يوجد عنوان URL لواجهة برمجة التطبيقات في إعدادات التطبيق</string>
<string id="NoConfigUrl" scope="glance">لا يوجد عنوان URL للتكوين في إعدادات التطبيق</string>
<string id="ApiFlood">مكالمات API سريعة جدًا. يرجى إبطاء طلباتك.</string>
<string id="ApiUrlNotFound">لم يتم العثور على عنوان URL. خطأ محتمل في عنوان URL لواجهة برمجة التطبيقات في الإعدادات.</string>
<string id="ConfigUrlNotFound">لم يتم العثور على عنوان URL. خطأ محتمل في عنوان URL للتكوين في الإعدادات.</string>
<string id="NoJson">لم يتم إرجاع JSON من طلب HTTP.</string>
<string id="UnhandledHttpErr">قام طلب HTTP بإرجاع رمز الخطأ =</string>
<string id="TrailingSlashErr">يجب ألا يحتوي عنوان URL لواجهة برمجة التطبيقات على شرطة مائلة لاحقة '/'</string>
<string id="FetchingMenuConfig">جارٍ جلب تكوين القائمة..</string>
<string id="ExitViewTouch">مرّر سريعًا إلى اليمين للخروج\nانقر للبقاء</string>
<string id="ExitViewButtons">اضغط على "الرجوع للخروج"\nأدخل للبقاء</string>
<string id="Available" scope="glance">متاح</string>
<string id="Checking" scope="glance">تدقيق...</string>
<string id="Unavailable" scope="glance">غير متوفره</string>
<string id="GlanceMenu" scope="glance">قائمة طعام</string>
<!-- لإعدادات واجهة المستخدم الرسومية -->
<string id="SettingsApiKey">مفتاح API لـ HomeAssistant.</string>
<string id="SettingsApiKeyPrompt">رمز الوصول طويل الأمد.</string>
Expand Down
17 changes: 9 additions & 8 deletions resources-bul/strings/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,22 @@
<string id="MenuItemTap">Докоснете</string>
<string id="MenuItemMenu">Меню</string>
<string id="Confirm">Сигурен?</string>
<string id="NoPhone">Няма телефонна връзка</string>
<string id="NoPhone" scope="glance">Няма телефонна връзка</string>
<string id="NoInternet">Няма интернет връзка</string>
<string id="NoResponse">Няма отговор, проверете интернет връзката</string>
<string id="NoMenu">Грешка при извличане на менюто</string>
<string id="NoAPIKey">Няма API ключ в настройките на приложението</string>
<string id="NoApiUrl">Няма URL адрес на API в настройките на приложението</string>
<string id="NoConfigUrl">Няма конфигурационен URL адрес в настройките на приложението</string>
<string id="NoAPIKey" scope="glance">Няма API ключ в настройките на приложението</string>
<string id="NoApiUrl" scope="glance">Няма URL адрес на API в настройките на приложението</string>
<string id="NoConfigUrl" scope="glance">Няма конфигурационен URL адрес в настройките на приложението</string>
<string id="ApiFlood">Извикванията на API са твърде бързи. Моля, забавете вашите заявки.</string>
<string id="ApiUrlNotFound">URL не е намерен. Потенциална грешка в URL адреса на API в настройките.</string>
<string id="ConfigUrlNotFound">URL не е намерен. Потенциална грешка в URL адреса на конфигурацията в настройките.</string>
<string id="NoJson">Няма върнат JSON от HTTP заявка.</string>
<string id="UnhandledHttpErr">HTTP заявката върна код на грешка =</string>
<string id="TrailingSlashErr">URL адресът на API не трябва да има наклонена черта '/' в края</string>
<string id="FetchingMenuConfig">Извличане на конфигурацията на менюто..</string>
<string id="ExitViewTouch">Плъзнете надясно, за да излезете\nДокоснете, за да останете</string>
<string id="ExitViewButtons">Натиснете Назад, за да излезете\nВлезте, за да останете</string>
<string id="Available" scope="glance">На разположение</string>
<string id="Checking" scope="glance">Проверка...</string>
<string id="Unavailable" scope="glance">Недостъпен</string>
<string id="GlanceMenu" scope="glance">Меню</string>
<!-- За GUI за настройки -->
<string id="SettingsApiKey">API ключ за HomeAssistant.</string>
<string id="SettingsApiKeyPrompt">Токен за дълготраен достъп.</string>
Expand Down
17 changes: 9 additions & 8 deletions resources-ces/strings/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,22 @@
<string id="MenuItemTap">Klepněte</string>
<string id="MenuItemMenu">Jídelní lístek</string>
<string id="Confirm">Tak určitě?</string>
<string id="NoPhone">Žádné telefonní spojení</string>
<string id="NoPhone" scope="glance">Žádné telefonní spojení</string>
<string id="NoInternet">Žádné internetové připojení</string>
<string id="NoResponse">Žádná odpověď, zkontrolujte připojení k internetu</string>
<string id="NoMenu">Chyba načítání nabídky</string>
<string id="NoAPIKey">V nastavení aplikace není žádný klíč API</string>
<string id="NoApiUrl">V nastavení aplikace není žádná adresa URL API</string>
<string id="NoConfigUrl">V nastavení aplikace není žádná konfigurační URL</string>
<string id="NoAPIKey" scope="glance">V nastavení aplikace není žádný klíč API</string>
<string id="NoApiUrl" scope="glance">V nastavení aplikace není žádná adresa URL API</string>
<string id="NoConfigUrl" scope="glance">V nastavení aplikace není žádná konfigurační URL</string>
<string id="ApiFlood">Příliš rychlá volání API. Zpomalte prosím své požadavky.</string>
<string id="ApiUrlNotFound">Adresa URL nenalezena. Potenciální chyba adresy URL rozhraní API v nastavení.</string>
<string id="ConfigUrlNotFound">Adresa URL nenalezena. Potenciální chyba konfigurační adresy URL v nastavení.</string>
<string id="NoJson">Z požadavku HTTP se nevrátil žádný JSON.</string>
<string id="UnhandledHttpErr">Požadavek HTTP vrátil kód chyby =</string>
<string id="TrailingSlashErr">Adresa URL rozhraní API nesmí mít koncové lomítko „/“</string>
<string id="FetchingMenuConfig">Načítání konfigurace nabídky...</string>
<string id="ExitViewTouch">Přejetím prstem doprava ukončíte\nKlepnutím zůstanete</string>
<string id="ExitViewButtons">Stisknutím Zpět ukončíte\nVstupte a zůstanete</string>
<string id="Available" scope="glance">Dostupný</string>
<string id="Checking" scope="glance">Kontrola...</string>
<string id="Unavailable" scope="glance">Není k dispozici</string>
<string id="GlanceMenu" scope="glance">Jídelní lístek</string>
<!-- Pro nastavení GUI -->
<string id="SettingsApiKey">Klíč API pro HomeAssistant.</string>
<string id="SettingsApiKeyPrompt">Přístupový token s dlouhou životností.</string>
Expand Down
Loading

0 comments on commit 3934ca5

Please sign in to comment.