mirror of
				https://github.com/house-of-abbey/GarminHomeAssistant.git
				synced 2025-11-04 00:48:14 +00:00 
			
		
		
		
	Moved template status updates to webhooks
This seems to work for non-privileged users.
This commit is contained in:
		@@ -21,7 +21,7 @@ rem
 | 
				
			|||||||
rem -----------------------------------------------------------------------------------
 | 
					rem -----------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rem Check this path is correct for your Java installation
 | 
					rem Check this path is correct for your Java installation
 | 
				
			||||||
set JAVA_PATH=C:\Program Files (x86)\Common Files\Oracle\Java\javapath
 | 
					set JAVA_PATH=C:\Program Files\Java\jdk-22\bin
 | 
				
			||||||
rem SDK_PATH should work for all users
 | 
					rem SDK_PATH should work for all users
 | 
				
			||||||
set /p SDK_PATH=<"%USERPROFILE%\AppData\Roaming\Garmin\ConnectIQ\current-sdk.cfg"
 | 
					set /p SDK_PATH=<"%USERPROFILE%\AppData\Roaming\Garmin\ConnectIQ\current-sdk.cfg"
 | 
				
			||||||
set SDK_PATH=%SDK_PATH:~0,-1%\bin
 | 
					set SDK_PATH=%SDK_PATH:~0,-1%\bin
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -204,6 +204,7 @@ class HomeAssistantApp extends Application.AppBase {
 | 
				
			|||||||
    // asynchronous and affects how the views are managed.
 | 
					    // asynchronous and affects how the views are managed.
 | 
				
			||||||
    (:glance)
 | 
					    (:glance)
 | 
				
			||||||
    function fetchMenuConfig() as Lang.Boolean {
 | 
					    function fetchMenuConfig() as Lang.Boolean {
 | 
				
			||||||
 | 
					        // System.println("URL = " + Settings.getConfigUrl());
 | 
				
			||||||
        if (Settings.getConfigUrl().equals("")) {
 | 
					        if (Settings.getConfigUrl().equals("")) {
 | 
				
			||||||
            mMenuStatus = WatchUi.loadResource($.Rez.Strings.Unconfigured) as Lang.String;
 | 
					            mMenuStatus = WatchUi.loadResource($.Rez.Strings.Unconfigured) as Lang.String;
 | 
				
			||||||
            WatchUi.requestUpdate();
 | 
					            WatchUi.requestUpdate();
 | 
				
			||||||
@@ -257,6 +258,9 @@ class HomeAssistantApp extends Application.AppBase {
 | 
				
			|||||||
    private function buildMenu(menu as Lang.Dictionary) {
 | 
					    private function buildMenu(menu as Lang.Dictionary) {
 | 
				
			||||||
        mHaMenu = new HomeAssistantView(menu, null);
 | 
					        mHaMenu = new HomeAssistantView(menu, null);
 | 
				
			||||||
        mQuitTimer.begin();
 | 
					        mQuitTimer.begin();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function startUpdates() {
 | 
				
			||||||
        mItemsToUpdate = mHaMenu.getItemsToUpdate();
 | 
					        mItemsToUpdate = mHaMenu.getItemsToUpdate();
 | 
				
			||||||
        // Start the continuous update process that continues for as long as the application is running.
 | 
					        // 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.
 | 
					        // The chain of functions from 'updateNextMenuItem()' calls 'updateNextMenuItem()' on completion.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,7 +83,7 @@ class HomeAssistantTemplateMenuItem extends WatchUi.IconMenuItem {
 | 
				
			|||||||
    // Terminate updating the toggle menu items via the chain of calls for a permanent network
 | 
					    // Terminate updating the toggle menu items via the chain of calls for a permanent network
 | 
				
			||||||
    // error. The ErrorView cancellation will resume the call chain.
 | 
					    // error. The ErrorView cancellation will resume the call chain.
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    function onReturnGetState(responseCode as Lang.Number, data as Lang.String) as Void {
 | 
					    function onReturnGetState(responseCode as Lang.Number, data as Null or Lang.Dictionary) as Void {
 | 
				
			||||||
        // System.println("HomeAssistantTemplateMenuItem onReturnGetState() Response Code: " + responseCode);
 | 
					        // System.println("HomeAssistantTemplateMenuItem onReturnGetState() Response Code: " + responseCode);
 | 
				
			||||||
        // System.println("HomeAssistantTemplateMenuItem onReturnGetState() Response Data: " + data);
 | 
					        // System.println("HomeAssistantTemplateMenuItem onReturnGetState() Response Data: " + data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -131,7 +131,7 @@ class HomeAssistantTemplateMenuItem extends WatchUi.IconMenuItem {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            case 200:
 | 
					            case 200:
 | 
				
			||||||
                status = WatchUi.loadResource($.Rez.Strings.Available) as Lang.String;
 | 
					                status = WatchUi.loadResource($.Rez.Strings.Available) as Lang.String;
 | 
				
			||||||
                setSubLabel(data);
 | 
					                setSubLabel(data.get("request"));
 | 
				
			||||||
                requestUpdate();
 | 
					                requestUpdate();
 | 
				
			||||||
                // Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer.
 | 
					                // Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer.
 | 
				
			||||||
                getApp().updateNextMenuItem();
 | 
					                getApp().updateNextMenuItem();
 | 
				
			||||||
@@ -153,19 +153,28 @@ class HomeAssistantTemplateMenuItem extends WatchUi.IconMenuItem {
 | 
				
			|||||||
            // System.println("HomeAssistantTemplateMenuItem getState(): No Internet connection, skipping API call.");
 | 
					            // System.println("HomeAssistantTemplateMenuItem getState(): No Internet connection, skipping API call.");
 | 
				
			||||||
            ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoInternet) as Lang.String + ".");
 | 
					            ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoInternet) as Lang.String + ".");
 | 
				
			||||||
            getApp().setApiStatus(WatchUi.loadResource($.Rez.Strings.Unavailable) as Lang.String);
 | 
					            getApp().setApiStatus(WatchUi.loadResource($.Rez.Strings.Unavailable) as Lang.String);
 | 
				
			||||||
 | 
					        } else if (Settings.getWebhookId().equals("")) {
 | 
				
			||||||
 | 
					            getApp().updateNextMenuItem();
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            var url = Settings.getApiUrl() + "/template";
 | 
					            // https://developers.home-assistant.io/docs/api/native-app-integration/sending-data/#render-templates
 | 
				
			||||||
 | 
					            var url = Settings.getApiUrl() + "/webhook/" + Settings.getWebhookId();
 | 
				
			||||||
            // System.println("HomeAssistantTemplateMenuItem getState() URL=" + url + ", Template='" + mTemplate + "'");
 | 
					            // System.println("HomeAssistantTemplateMenuItem getState() URL=" + url + ", Template='" + mTemplate + "'");
 | 
				
			||||||
            Communications.makeWebRequest(
 | 
					            Communications.makeWebRequest(
 | 
				
			||||||
                url,
 | 
					                url,
 | 
				
			||||||
                { "template" => mTemplate },
 | 
					                {
 | 
				
			||||||
 | 
					                    "type" => "render_template",
 | 
				
			||||||
 | 
					                    "data" => {
 | 
				
			||||||
 | 
					                        "request" => {
 | 
				
			||||||
 | 
					                            "template" => mTemplate
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    :method       => Communications.HTTP_REQUEST_METHOD_POST,
 | 
					                    :method       => Communications.HTTP_REQUEST_METHOD_POST,
 | 
				
			||||||
                    :headers      => {
 | 
					                    :headers      => {
 | 
				
			||||||
                        "Content-Type"  => Communications.REQUEST_CONTENT_TYPE_JSON,
 | 
					                        "Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON
 | 
				
			||||||
                        "Authorization" => "Bearer " + Settings.getApiKey()
 | 
					 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN
 | 
					                    :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                method(:onReturnGetState)
 | 
					                method(:onReturnGetState)
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ class Settings {
 | 
				
			|||||||
    private static var mPollDelay             as Lang.Number  = 0;  // seconds
 | 
					    private static var mPollDelay             as Lang.Number  = 0;  // seconds
 | 
				
			||||||
    private static var mConfirmTimeout        as Lang.Number  = 3;  // seconds
 | 
					    private static var mConfirmTimeout        as Lang.Number  = 3;  // seconds
 | 
				
			||||||
    private static var mMenuAlignment         as Lang.Number  = WatchUi.MenuItem.MENU_ITEM_LABEL_ALIGN_LEFT;
 | 
					    private static var mMenuAlignment         as Lang.Number  = WatchUi.MenuItem.MENU_ITEM_LABEL_ALIGN_LEFT;
 | 
				
			||||||
    private static var mIsBatteryLevelEnabled as Lang.Boolean = false;
 | 
					    private static var mIsSensorsLevelEnabled as Lang.Boolean = false;
 | 
				
			||||||
    private static var mBatteryRefreshRate    as Lang.Number  = 15; // minutes
 | 
					    private static var mBatteryRefreshRate    as Lang.Number  = 15; // minutes
 | 
				
			||||||
    private static var mIsApp                 as Lang.Boolean = false;
 | 
					    private static var mIsApp                 as Lang.Boolean = false;
 | 
				
			||||||
    private static var mHasService            as Lang.Boolean = false;
 | 
					    private static var mHasService            as Lang.Boolean = false;
 | 
				
			||||||
@@ -60,7 +60,7 @@ class Settings {
 | 
				
			|||||||
        mPollDelay             = Properties.getValue("poll_delay");
 | 
					        mPollDelay             = Properties.getValue("poll_delay");
 | 
				
			||||||
        mConfirmTimeout        = Properties.getValue("confirm_timeout");
 | 
					        mConfirmTimeout        = Properties.getValue("confirm_timeout");
 | 
				
			||||||
        mMenuAlignment         = Properties.getValue("menu_alignment");
 | 
					        mMenuAlignment         = Properties.getValue("menu_alignment");
 | 
				
			||||||
        mIsBatteryLevelEnabled = Properties.getValue("enable_battery_level");
 | 
					        mIsSensorsLevelEnabled = Properties.getValue("enable_battery_level");
 | 
				
			||||||
        mBatteryRefreshRate    = Properties.getValue("battery_level_refresh_rate");
 | 
					        mBatteryRefreshRate    = Properties.getValue("battery_level_refresh_rate");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (System has :ServiceDelegate) {
 | 
					        if (System has :ServiceDelegate) {
 | 
				
			||||||
@@ -69,19 +69,40 @@ class Settings {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Manage this inside the application or widget only (not a glance or background service process)
 | 
					        // Manage this inside the application or widget only (not a glance or background service process)
 | 
				
			||||||
        if (mIsApp) {
 | 
					        if (mIsApp) {
 | 
				
			||||||
            if (mIsBatteryLevelEnabled and mHasService) {
 | 
					            if (mHasService) {
 | 
				
			||||||
                if (getWebhookId().equals("")) {
 | 
					 | 
				
			||||||
                mWebhookManager = new WebhookManager();
 | 
					                mWebhookManager = new WebhookManager();
 | 
				
			||||||
 | 
					                if (getWebhookId().equals("")) {
 | 
				
			||||||
 | 
					                    // System.println("Settings update(): Doing full webhook & sensor creation.");
 | 
				
			||||||
                    mWebhookManager.requestWebhookId();
 | 
					                    mWebhookManager.requestWebhookId();
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    // System.println("Settings update(): Doing just sensor creation.");
 | 
				
			||||||
 | 
					                    // We already have a Webhook ID, so just enable or disable the sensor in Home Assistant.
 | 
				
			||||||
 | 
					                    // Its a multiple step process, hence starting at step 0.
 | 
				
			||||||
 | 
					                    mWebhookManager.registerWebhookSensor({
 | 
				
			||||||
 | 
					                            "device_class"        => "battery",
 | 
				
			||||||
 | 
					                            "name"                => "Battery Level",
 | 
				
			||||||
 | 
					                            "state"               => System.getSystemStats().battery,
 | 
				
			||||||
 | 
					                            "type"                => "sensor",
 | 
				
			||||||
 | 
					                            "unique_id"           => "battery_level",
 | 
				
			||||||
 | 
					                            "unit_of_measurement" => "%",
 | 
				
			||||||
 | 
					                            "state_class"         => "measurement",
 | 
				
			||||||
 | 
					                            "entity_category"     => "diagnostic",
 | 
				
			||||||
 | 
					                            "disabled"            => !Settings.isSensorsLevelEnabled()
 | 
				
			||||||
 | 
					                        }, 0);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                if (mIsSensorsLevelEnabled) {
 | 
				
			||||||
 | 
					                    // Create the timed activity
 | 
				
			||||||
                    if ((Background.getTemporalEventRegisteredTime() == null) or
 | 
					                    if ((Background.getTemporalEventRegisteredTime() == null) or
 | 
				
			||||||
                        (Background.getTemporalEventRegisteredTime() != (mBatteryRefreshRate * 60))) {
 | 
					                        (Background.getTemporalEventRegisteredTime() != (mBatteryRefreshRate * 60))) {
 | 
				
			||||||
                        Background.registerForTemporalEvent(new Time.Duration(mBatteryRefreshRate * 60)); // Convert to seconds
 | 
					                        Background.registerForTemporalEvent(new Time.Duration(mBatteryRefreshRate * 60)); // Convert to seconds
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                } else if (Background.getTemporalEventRegisteredTime() != null) {
 | 
				
			||||||
 | 
					                    Background.deleteTemporalEvent();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                // Explicitly disable the background event which persists when the application closes.
 | 
					                // Explicitly disable the background event which persists when the application closes.
 | 
				
			||||||
                // If !mHasService disable the Settings option as user feedback
 | 
					                // If !mHasService disable the Settings option as user feedback
 | 
				
			||||||
                unsetIsBatteryLevelEnabled();
 | 
					                unsetIsSensorsLevelEnabled();
 | 
				
			||||||
                unsetWebhookId();
 | 
					                unsetWebhookId();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -152,9 +173,13 @@ class Settings {
 | 
				
			|||||||
        return mMenuAlignment; // Either WatchUi.MenuItem.MENU_ITEM_LABEL_ALIGN_RIGHT or WatchUi.MenuItem.MENU_ITEM_LABEL_ALIGN_LEFT
 | 
					        return mMenuAlignment; // Either WatchUi.MenuItem.MENU_ITEM_LABEL_ALIGN_RIGHT or WatchUi.MenuItem.MENU_ITEM_LABEL_ALIGN_LEFT
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static function unsetIsBatteryLevelEnabled() {
 | 
					    static function isSensorsLevelEnabled() as Lang.Boolean {
 | 
				
			||||||
        mIsBatteryLevelEnabled = false;
 | 
					        return mIsSensorsLevelEnabled;
 | 
				
			||||||
        Properties.setValue("enable_battery_level", mIsBatteryLevelEnabled);
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static function unsetIsSensorsLevelEnabled() {
 | 
				
			||||||
 | 
					        mIsSensorsLevelEnabled = false;
 | 
				
			||||||
 | 
					        Properties.setValue("enable_battery_level", mIsSensorsLevelEnabled);
 | 
				
			||||||
        if (mHasService and (Background.getTemporalEventRegisteredTime() != null)) {
 | 
					        if (mHasService and (Background.getTemporalEventRegisteredTime() != null)) {
 | 
				
			||||||
            Background.deleteTemporalEvent();
 | 
					            Background.deleteTemporalEvent();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@
 | 
				
			|||||||
using Toybox.Lang;
 | 
					using Toybox.Lang;
 | 
				
			||||||
using Toybox.Communications;
 | 
					using Toybox.Communications;
 | 
				
			||||||
using Toybox.System;
 | 
					using Toybox.System;
 | 
				
			||||||
 | 
					using Toybox.WatchUi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Can use push view so must never be run in a glance context
 | 
					// Can use push view so must never be run in a glance context
 | 
				
			||||||
class WebhookManager {
 | 
					class WebhookManager {
 | 
				
			||||||
@@ -52,13 +53,13 @@ class WebhookManager {
 | 
				
			|||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case Communications.INVALID_HTTP_BODY_IN_NETWORK_RESPONSE:
 | 
					            case Communications.INVALID_HTTP_BODY_IN_NETWORK_RESPONSE:
 | 
				
			||||||
                // System.println("WebhookManager onReturnRequestWebhookId() Response Code: INVALID_HTTP_BODY_IN_NETWORK_RESPONSE, check JSON is returned.");
 | 
					                // System.println("WebhookManager onReturnRequestWebhookId() Response Code: INVALID_HTTP_BODY_IN_NETWORK_RESPONSE, check JSON is returned.");
 | 
				
			||||||
                Settings.unsetIsBatteryLevelEnabled();
 | 
					                Settings.unsetIsSensorsLevelEnabled();
 | 
				
			||||||
                ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String + "\n" + WatchUi.loadResource($.Rez.Strings.NoJson) as Lang.String);
 | 
					                ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String + "\n" + WatchUi.loadResource($.Rez.Strings.NoJson) as Lang.String);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case 404:
 | 
					            case 404:
 | 
				
			||||||
                // System.println("WebhookManager onReturnRequestWebhookId() Response Code: 404, page not found. Check API URL setting.");
 | 
					                // System.println("WebhookManager onReturnRequestWebhookId() Response Code: 404, page not found. Check API URL setting.");
 | 
				
			||||||
                Settings.unsetIsBatteryLevelEnabled();
 | 
					                Settings.unsetIsSensorsLevelEnabled();
 | 
				
			||||||
                ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String + "\n" + WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound) as Lang.String);
 | 
					                ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String + "\n" + WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound) as Lang.String);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -77,25 +78,25 @@ class WebhookManager {
 | 
				
			|||||||
                        "unit_of_measurement" => "%",
 | 
					                        "unit_of_measurement" => "%",
 | 
				
			||||||
                        "state_class"         => "measurement",
 | 
					                        "state_class"         => "measurement",
 | 
				
			||||||
                        "entity_category"     => "diagnostic",
 | 
					                        "entity_category"     => "diagnostic",
 | 
				
			||||||
                        "disabled"            => false
 | 
					                        "disabled"            => !Settings.isSensorsLevelEnabled()
 | 
				
			||||||
                    }, 0);
 | 
					                    }, 0);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    // System.println("WebhookManager onReturnRequestWebhookId(): No webhook id in response data.");
 | 
					                    // System.println("WebhookManager onReturnRequestWebhookId(): No webhook id in response data.");
 | 
				
			||||||
                    Settings.unsetIsBatteryLevelEnabled();
 | 
					                    Settings.unsetIsSensorsLevelEnabled();
 | 
				
			||||||
                    ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String);
 | 
					                    ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                // System.println("WebhookManager onReturnRequestWebhookId(): Unhandled HTTP response code = " + responseCode);
 | 
					                // System.println("WebhookManager onReturnRequestWebhookId(): Unhandled HTTP response code = " + responseCode);
 | 
				
			||||||
                Settings.unsetIsBatteryLevelEnabled();
 | 
					                Settings.unsetIsSensorsLevelEnabled();
 | 
				
			||||||
                ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String + "\n" + WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr) as Lang.String + responseCode);
 | 
					                ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String + "\n" + WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr) as Lang.String + responseCode);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function requestWebhookId() {
 | 
					    function requestWebhookId() {
 | 
				
			||||||
        // System.println("WebhookManager requestWebhookId(): Requesting webhook id");
 | 
					 | 
				
			||||||
        var deviceSettings = System.getDeviceSettings();
 | 
					        var deviceSettings = System.getDeviceSettings();
 | 
				
			||||||
 | 
					        // System.println("WebhookManager requestWebhookId(): Requesting webhook id for device = " + deviceSettings.uniqueIdentifier);
 | 
				
			||||||
        Communications.makeWebRequest(
 | 
					        Communications.makeWebRequest(
 | 
				
			||||||
            Settings.getApiUrl() + "/mobile_app/registrations",
 | 
					            Settings.getApiUrl() + "/mobile_app/registrations",
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -153,21 +154,24 @@ class WebhookManager {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            case Communications.INVALID_HTTP_BODY_IN_NETWORK_RESPONSE:
 | 
					            case Communications.INVALID_HTTP_BODY_IN_NETWORK_RESPONSE:
 | 
				
			||||||
                // System.println("WebhookManager onReturnRegisterWebhookSensor() Response Code: INVALID_HTTP_BODY_IN_NETWORK_RESPONSE, check JSON is returned.");
 | 
					                // System.println("WebhookManager onReturnRegisterWebhookSensor() Response Code: INVALID_HTTP_BODY_IN_NETWORK_RESPONSE, check JSON is returned.");
 | 
				
			||||||
 | 
					                // Webhook ID might have been deleted on Home Assistant server
 | 
				
			||||||
                Settings.unsetWebhookId();
 | 
					                Settings.unsetWebhookId();
 | 
				
			||||||
                Settings.unsetIsBatteryLevelEnabled();
 | 
					                // System.println("WebhookManager onReturnRegisterWebhookSensor(): Webhook ID invalid, going full chain.");
 | 
				
			||||||
                ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String + "\n" + WatchUi.loadResource($.Rez.Strings.NoJson) as Lang.String);
 | 
					                requestWebhookId();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case 404:
 | 
					            case 404:
 | 
				
			||||||
                // System.println("WebhookManager onReturnRequestWebhookId() Response Code: 404, page not found. Check API URL setting.");
 | 
					                // System.println("WebhookManager onReturnRegisterWebhookSensor() Response Code: 404, page not found. Check API URL setting.");
 | 
				
			||||||
 | 
					                // Webhook ID might have been deleted on Home Assistant server
 | 
				
			||||||
                Settings.unsetWebhookId();
 | 
					                Settings.unsetWebhookId();
 | 
				
			||||||
                Settings.unsetIsBatteryLevelEnabled();
 | 
					                // System.println("WebhookManager onReturnRegisterWebhookSensor(): Webhook ID invalid, going full chain.");
 | 
				
			||||||
                ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String + "\n" + WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound) as Lang.String);
 | 
					                requestWebhookId();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case 200:
 | 
					            case 200:
 | 
				
			||||||
            case 201:
 | 
					            case 201:
 | 
				
			||||||
                if ((data.get("success") as Lang.Boolean or Null) != false) {
 | 
					                var d = data as Lang.Dictionary;
 | 
				
			||||||
 | 
					                if ((d.get("success") as Lang.Boolean or Null) != false) {
 | 
				
			||||||
                    // System.println("WebhookManager onReturnRegisterWebhookSensor(): Success");
 | 
					                    // System.println("WebhookManager onReturnRegisterWebhookSensor(): Success");
 | 
				
			||||||
                    switch (step) {
 | 
					                    switch (step) {
 | 
				
			||||||
                        case 0:
 | 
					                        case 0:
 | 
				
			||||||
@@ -179,7 +183,7 @@ class WebhookManager {
 | 
				
			|||||||
                                "type"            => "binary_sensor",
 | 
					                                "type"            => "binary_sensor",
 | 
				
			||||||
                                "unique_id"       => "battery_is_charging",
 | 
					                                "unique_id"       => "battery_is_charging",
 | 
				
			||||||
                                "entity_category" => "diagnostic",
 | 
					                                "entity_category" => "diagnostic",
 | 
				
			||||||
                                "disabled"        => false
 | 
					                                "disabled"        => !Settings.isSensorsLevelEnabled()
 | 
				
			||||||
                            }, 1);
 | 
					                            }, 1);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 1:
 | 
					                        case 1:
 | 
				
			||||||
@@ -198,12 +202,12 @@ class WebhookManager {
 | 
				
			|||||||
                                    "state"     => activity,
 | 
					                                    "state"     => activity,
 | 
				
			||||||
                                    "type"      => "sensor",
 | 
					                                    "type"      => "sensor",
 | 
				
			||||||
                                    "unique_id" => "activity",
 | 
					                                    "unique_id" => "activity",
 | 
				
			||||||
                                    "disabled"  => false
 | 
					                                    "disabled"  => !Settings.isSensorsLevelEnabled()
 | 
				
			||||||
                                }, 2);
 | 
					                                }, 2);
 | 
				
			||||||
                                break;
 | 
					                                break;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        case 2:
 | 
					                        case 2:
 | 
				
			||||||
                            // System.println("WebhookManager onReturnRegisterWebhookSensor(): Registering next sensor: Activity");
 | 
					                            // System.println("WebhookManager onReturnRegisterWebhookSensor(): Registering next sensor: Sub-Activity");
 | 
				
			||||||
                            if (Activity has :getProfileInfo) {
 | 
					                            if (Activity has :getProfileInfo) {
 | 
				
			||||||
                                var sub_activity = Activity.getProfileInfo().subSport;
 | 
					                                var sub_activity = Activity.getProfileInfo().subSport;
 | 
				
			||||||
                                if ((Activity.getActivityInfo() != null) and
 | 
					                                if ((Activity.getActivityInfo() != null) and
 | 
				
			||||||
@@ -218,16 +222,18 @@ class WebhookManager {
 | 
				
			|||||||
                                    "state"     => sub_activity,
 | 
					                                    "state"     => sub_activity,
 | 
				
			||||||
                                    "type"      => "sensor",
 | 
					                                    "type"      => "sensor",
 | 
				
			||||||
                                    "unique_id" => "sub_activity",
 | 
					                                    "unique_id" => "sub_activity",
 | 
				
			||||||
                                    "disabled"  => false
 | 
					                                    "disabled"  => !Settings.isSensorsLevelEnabled()
 | 
				
			||||||
                                }, 3);
 | 
					                                }, 3);
 | 
				
			||||||
                                break;
 | 
					                                break;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
 | 
					                        case 3:
 | 
				
			||||||
 | 
					                            getApp().startUpdates();
 | 
				
			||||||
                        default:
 | 
					                        default:
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    // System.println("WebhookManager onReturnRegisterWebhookSensor(): Failure");
 | 
					                    // System.println("WebhookManager onReturnRegisterWebhookSensor(): Failure");
 | 
				
			||||||
                    Settings.unsetWebhookId();
 | 
					                    Settings.unsetWebhookId();
 | 
				
			||||||
                    Settings.unsetIsBatteryLevelEnabled();
 | 
					                    Settings.unsetIsSensorsLevelEnabled();
 | 
				
			||||||
                    ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String);
 | 
					                    ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
@@ -235,15 +241,18 @@ class WebhookManager {
 | 
				
			|||||||
            default:
 | 
					            default:
 | 
				
			||||||
                // System.println("WebhookManager onReturnRequestWebhookId(): Unhandled HTTP response code = " + responseCode);
 | 
					                // System.println("WebhookManager onReturnRequestWebhookId(): Unhandled HTTP response code = " + responseCode);
 | 
				
			||||||
                Settings.unsetWebhookId();
 | 
					                Settings.unsetWebhookId();
 | 
				
			||||||
                Settings.unsetIsBatteryLevelEnabled();
 | 
					                Settings.unsetIsSensorsLevelEnabled();
 | 
				
			||||||
                ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String + "\n" + WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr) as Lang.String + responseCode);
 | 
					                ErrorView.show(WatchUi.loadResource($.Rez.Strings.WebhookFailed) as Lang.String + "\n" + WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr) as Lang.String + responseCode);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function registerWebhookSensor(sensor as Lang.Object, step as Lang.Number) {
 | 
					    function registerWebhookSensor(sensor as Lang.Object, step as Lang.Number) {
 | 
				
			||||||
 | 
					        var url = Settings.getApiUrl() + "/webhook/" + Settings.getWebhookId();
 | 
				
			||||||
        // System.println("WebhookManager registerWebhookSensor(): Registering webhook sensor: " + sensor.toString());
 | 
					        // System.println("WebhookManager registerWebhookSensor(): Registering webhook sensor: " + sensor.toString());
 | 
				
			||||||
 | 
					        // System.println("WebhookManager registerWebhookSensor(): URL=" + url);
 | 
				
			||||||
 | 
					        // https://developers.home-assistant.io/docs/api/native-app-integration/sensors/#registering-a-sensor
 | 
				
			||||||
        Communications.makeWebRequest(
 | 
					        Communications.makeWebRequest(
 | 
				
			||||||
            Settings.getApiUrl() + "/webhook/" + Settings.getWebhookId(),
 | 
					            url,
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                "type" => "register_sensor",
 | 
					                "type" => "register_sensor",
 | 
				
			||||||
                "data" => sensor
 | 
					                "data" => sensor
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user