mirror of
				https://github.com/house-of-abbey/GarminHomeAssistant.git
				synced 2025-11-04 00:48:14 +00:00 
			
		
		
		
	add Wifi LTE command execution
This commit is contained in:
		@@ -14,6 +14,7 @@
 | 
			
		||||
//-----------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
using Toybox.Application;
 | 
			
		||||
using Toybox.Communications;
 | 
			
		||||
using Toybox.Lang;
 | 
			
		||||
using Toybox.WatchUi;
 | 
			
		||||
using Toybox.System;
 | 
			
		||||
@@ -122,11 +123,14 @@ class HomeAssistantApp extends Application.AppBase {
 | 
			
		||||
        } else if (Settings.getPin() == null) {
 | 
			
		||||
            // System.println("HomeAssistantApp getInitialView(): Invalid PIN in application settings.");
 | 
			
		||||
            return ErrorView.create(WatchUi.loadResource($.Rez.Strings.SettingsPinError) as Lang.String);
 | 
			
		||||
        } else if (! System.getDeviceSettings().phoneConnected) {
 | 
			
		||||
            // System.println("HomeAssistantApp getInitialView(): No Phone connection, skipping API call.");
 | 
			
		||||
        } else if (! System.getDeviceSettings().phoneConnected and Settings.getWifiLteExecutionEnabled() and ! hasCachedMenu()) {
 | 
			
		||||
            // System.println("HomeAssistantApp getInitialView(): No Phone connection, no cached menu, skipping API call.");
 | 
			
		||||
            return ErrorView.create(WatchUi.loadResource($.Rez.Strings.NoPhoneNoCache) as Lang.String);
 | 
			
		||||
        } else if (! System.getDeviceSettings().phoneConnected and ! Settings.getWifiLteExecutionEnabled()) {
 | 
			
		||||
            // System.println("HomeAssistantApp getInitialView(): No Phone connection and wifi disabled, skipping API call.");
 | 
			
		||||
            return ErrorView.create(WatchUi.loadResource($.Rez.Strings.NoPhone) as Lang.String);
 | 
			
		||||
        } else if (! System.getDeviceSettings().connectionAvailable) {
 | 
			
		||||
            // System.println("HomeAssistantApp getInitialView(): No Internet connection, skipping API call.");
 | 
			
		||||
        } else if (! System.getDeviceSettings().connectionAvailable and ! Settings.getWifiLteExecutionEnabled()) {
 | 
			
		||||
            // System.println("HomeAssistantApp getInitialView(): No Internet connection and wifi disabled, skipping API call.");
 | 
			
		||||
            return ErrorView.create(WatchUi.loadResource($.Rez.Strings.NoInternet) as Lang.String);
 | 
			
		||||
        } else {
 | 
			
		||||
            var isCached = fetchMenuConfig();
 | 
			
		||||
@@ -227,6 +231,20 @@ class HomeAssistantApp extends Application.AppBase {
 | 
			
		||||
        WatchUi.requestUpdate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Can we use the cached menu?
 | 
			
		||||
    //!
 | 
			
		||||
    //! @return Return true if there's a menu in cache, and if the user has enabled the cache and 
 | 
			
		||||
    //! has not requested to have the cache busted.
 | 
			
		||||
    //
 | 
			
		||||
    function hasCachedMenu() as Lang.Boolean {
 | 
			
		||||
        if (Settings.getClearCache() || !Settings.getCacheConfig()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var menu = Storage.getValue("menu") as Lang.Dictionary;
 | 
			
		||||
        return menu != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Fetch the menu configuration over HTTPS, which might be locally cached.
 | 
			
		||||
    //!
 | 
			
		||||
    //! @return Return true if the menu came from the cache, otherwise false. This is because fetching
 | 
			
		||||
@@ -246,22 +264,22 @@ class HomeAssistantApp extends Application.AppBase {
 | 
			
		||||
                Settings.unsetClearCache();
 | 
			
		||||
            }
 | 
			
		||||
            if (menu == null) {
 | 
			
		||||
                if (! System.getDeviceSettings().phoneConnected) {
 | 
			
		||||
                var phoneConnected = System.getDeviceSettings().phoneConnected;
 | 
			
		||||
                var internetAvailable = System.getDeviceSettings().connectionAvailable;
 | 
			
		||||
                if (! phoneConnected or ! internetAvailable) {
 | 
			
		||||
                    var errorRez = $.Rez.Strings.NoPhone;
 | 
			
		||||
                    if (Settings.getWifiLteExecutionEnabled()) {
 | 
			
		||||
                        errorRez = $.Rez.Strings.NoPhoneNoCache;
 | 
			
		||||
                    } else if (! internetAvailable) {
 | 
			
		||||
                        errorRez = $.Rez.Strings.Unavailable;
 | 
			
		||||
                    }
 | 
			
		||||
                    // System.println("HomeAssistantApp fetchMenuConfig(): No Phone connection, skipping API call.");
 | 
			
		||||
                    if (mIsGlance) {
 | 
			
		||||
                        WatchUi.requestUpdate();
 | 
			
		||||
                    } else {
 | 
			
		||||
                        ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoPhone) as Lang.String);
 | 
			
		||||
                        ErrorView.show(WatchUi.loadResource(errorRez) as Lang.String);
 | 
			
		||||
                    }
 | 
			
		||||
                    mMenuStatus = WatchUi.loadResource($.Rez.Strings.Unavailable) as Lang.String;
 | 
			
		||||
                } else if (! System.getDeviceSettings().connectionAvailable) {
 | 
			
		||||
                    // System.println("HomeAssistantApp fetchMenuConfig(): No Internet connection, skipping API call.");
 | 
			
		||||
                    if (mIsGlance) {
 | 
			
		||||
                        WatchUi.requestUpdate();
 | 
			
		||||
                    } else {
 | 
			
		||||
                        ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoInternet) as Lang.String);
 | 
			
		||||
                    }
 | 
			
		||||
                    mMenuStatus = WatchUi.loadResource($.Rez.Strings.Unavailable) as Lang.String;
 | 
			
		||||
                    mMenuStatus = WatchUi.loadResource(errorRez) as Lang.String;
 | 
			
		||||
                } else {
 | 
			
		||||
                    Communications.makeWebRequest(
 | 
			
		||||
                        Settings.getConfigUrl(),
 | 
			
		||||
@@ -785,6 +803,13 @@ class HomeAssistantApp extends Application.AppBase {
 | 
			
		||||
        return mIsApp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Returns a SyncDelegate for this App
 | 
			
		||||
    //!
 | 
			
		||||
    //! @return a SyncDelegate or null
 | 
			
		||||
    //
 | 
			
		||||
    public function getSyncDelegate() as Communications.SyncDelegate? {
 | 
			
		||||
        return new HomeAssistantSyncDelegate();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Global function to return the application object.
 | 
			
		||||
 
 | 
			
		||||
@@ -129,10 +129,25 @@ class HomeAssistantService {
 | 
			
		||||
        data    as Lang.Dictionary or Null,
 | 
			
		||||
        exit    as Lang.Boolean
 | 
			
		||||
    ) as Void {
 | 
			
		||||
        if (! 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);
 | 
			
		||||
            WatchUi.pushView(
 | 
			
		||||
                dialog,
 | 
			
		||||
                new WifiLteExecutionConfirmDelegate({
 | 
			
		||||
                    :type => "service",
 | 
			
		||||
                    :service => service,
 | 
			
		||||
                    :data => data,
 | 
			
		||||
                    :exit => exit,
 | 
			
		||||
                }, null),
 | 
			
		||||
                WatchUi.SLIDE_LEFT
 | 
			
		||||
            );
 | 
			
		||||
        } else if (! phoneConnected) {
 | 
			
		||||
            // System.println("HomeAssistantService call(): No Phone connection, skipping API call.");
 | 
			
		||||
            ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoPhone) as Lang.String);
 | 
			
		||||
        } else if (! System.getDeviceSettings().connectionAvailable) {
 | 
			
		||||
        } else if (! internetAvailable) {
 | 
			
		||||
            // System.println("HomeAssistantService call(): No Internet connection, skipping API call.");
 | 
			
		||||
            ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoInternet) as Lang.String);
 | 
			
		||||
        } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -198,16 +198,8 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
 | 
			
		||||
            case 200:
 | 
			
		||||
                // System.println("HomeAssistantToggleMenuItem onReturnSetState(): Service executed.");
 | 
			
		||||
                getApp().forceStatusUpdates();
 | 
			
		||||
                var state;
 | 
			
		||||
                var d = data as Lang.Array;
 | 
			
		||||
                for(var i = 0; i < d.size(); i++) {
 | 
			
		||||
                    if ((d[i].get("entity_id") as Lang.String).equals(mData.get("entity_id"))) {
 | 
			
		||||
                        state = d[i].get("state") as Lang.String;
 | 
			
		||||
                        // System.println((d[i].get("attributes") as Lang.Dictionary).get("friendly_name") + " State=" + state);
 | 
			
		||||
                        setUiToggle(state);
 | 
			
		||||
                        WatchUi.requestUpdate();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                setToggleStateWithData(d);
 | 
			
		||||
                status = WatchUi.loadResource($.Rez.Strings.Available) as Lang.String;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
@@ -221,23 +213,41 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Handles the response from a Home Assistant service or state call and updates the toggle UI.
 | 
			
		||||
    //!
 | 
			
		||||
    //! @param data An array of dictionaries, each representing a Home Assistant entity state.
 | 
			
		||||
    //
 | 
			
		||||
    function setToggleStateWithData(data as Lang.Array) {
 | 
			
		||||
        for(var i = 0; i < data.size(); i++) {
 | 
			
		||||
            if ((data[i].get("entity_id") as Lang.String).equals(mData.get("entity_id"))) {
 | 
			
		||||
                var state = data[i].get("state") as Lang.String;
 | 
			
		||||
                 // System.println((d[i].get("attributes") as Lang.Dictionary).get("friendly_name") + " State=" + state);
 | 
			
		||||
                setUiToggle(state);
 | 
			
		||||
                WatchUi.requestUpdate();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Set the state of the toggle menu item.
 | 
			
		||||
    //!
 | 
			
		||||
    //! @param s Boolean indicating the desired state of the toggle switch.
 | 
			
		||||
    //
 | 
			
		||||
    function setState(s as Lang.Boolean) as Void {
 | 
			
		||||
        // Toggle the UI back, we'll wait for confirmation from the Home Assistant
 | 
			
		||||
        // Note: with Zigbee2MQTT a.o. we may not always get the state in the response.
 | 
			
		||||
        setEnabled(!isEnabled());
 | 
			
		||||
        if (! System.getDeviceSettings().phoneConnected) {
 | 
			
		||||
 | 
			
		||||
        var phoneConnected = System.getDeviceSettings().phoneConnected;
 | 
			
		||||
        var internetAvailable = System.getDeviceSettings().connectionAvailable;
 | 
			
		||||
        
 | 
			
		||||
        if (! phoneConnected && ! Settings.getWifiLteExecutionEnabled()) {
 | 
			
		||||
            // System.println("HomeAssistantToggleMenuItem getState(): No Phone connection, skipping API call.");
 | 
			
		||||
            ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoPhone) as Lang.String);
 | 
			
		||||
        } else if (! System.getDeviceSettings().connectionAvailable) {
 | 
			
		||||
        } else if (! internetAvailable && ! Settings.getWifiLteExecutionEnabled()) {
 | 
			
		||||
            // System.println("HomeAssistantToggleMenuItem getState(): No Internet connection, skipping API call.");
 | 
			
		||||
            // Toggle the UI back
 | 
			
		||||
            ErrorView.show(WatchUi.loadResource($.Rez.Strings.NoInternet) as Lang.String);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Updated SDK and got a new error
 | 
			
		||||
            // ERROR: venu: Cannot find symbol ':substring' on type 'PolyType<Null or $.Toybox.Lang.Object>'.
 | 
			
		||||
            var id  = mData.get("entity_id") as Lang.String;
 | 
			
		||||
            var url = Settings.getApiUrl() + "/services/";
 | 
			
		||||
            if (s) {
 | 
			
		||||
@@ -245,6 +255,28 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
 | 
			
		||||
            } else {
 | 
			
		||||
                url = url + id.substring(0, id.find(".")) + "/turn_off";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (! phoneConnected && ! internetAvailable && Settings.getWifiLteExecutionEnabled()) {
 | 
			
		||||
                var dialogMsg = WatchUi.loadResource($.Rez.Strings.WifiLtePrompt) as Lang.String;
 | 
			
		||||
                var dialog = new WatchUi.Confirmation(dialogMsg);
 | 
			
		||||
                WatchUi.pushView(
 | 
			
		||||
                    dialog,
 | 
			
		||||
                    new WifiLteExecutionConfirmDelegate({
 | 
			
		||||
                        :type => "entity",
 | 
			
		||||
                        :url => url,
 | 
			
		||||
                        :id => id,
 | 
			
		||||
                        :data => mData,
 | 
			
		||||
                        :callback => method(:setToggleStateWithData),
 | 
			
		||||
                        :exit => mExit,
 | 
			
		||||
                    }, {
 | 
			
		||||
                        :confirmMethod => method(:onConfirm),
 | 
			
		||||
                        :state => !isEnabled(),
 | 
			
		||||
                    }),
 | 
			
		||||
                    WatchUi.SLIDE_LEFT
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // System.println("HomeAssistantToggleMenuItem setState() URL       = " + url);
 | 
			
		||||
            // System.println("HomeAssistantToggleMenuItem setState() entity_id = " + id);
 | 
			
		||||
            Communications.makeWebRequest(
 | 
			
		||||
@@ -302,5 +334,5 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
 | 
			
		||||
    function onConfirm(b as Lang.Boolean) as Void {
 | 
			
		||||
        setState(b);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,7 @@ class Settings {
 | 
			
		||||
    private static var mCacheConfig           as Lang.Boolean = false;
 | 
			
		||||
    private static var mClearCache            as Lang.Boolean = false;
 | 
			
		||||
    private static var mVibrate               as Lang.Boolean = false;
 | 
			
		||||
    private static var mWifiLteExecution      as Lang.Boolean = false;
 | 
			
		||||
    //! seconds
 | 
			
		||||
    private static var mAppTimeout            as Lang.Number  = 0;
 | 
			
		||||
    //! seconds
 | 
			
		||||
@@ -69,6 +70,7 @@ class Settings {
 | 
			
		||||
        mMenuAlignment         = Properties.getValue("menu_alignment");
 | 
			
		||||
        mIsSensorsLevelEnabled = Properties.getValue("enable_battery_level");
 | 
			
		||||
        mBatteryRefreshRate    = Properties.getValue("battery_level_refresh_rate");
 | 
			
		||||
        mWifiLteExecution      = Properties.getValue("wifi_lte_execution");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! A webhook is required for non-privileged API calls.
 | 
			
		||||
@@ -270,4 +272,12 @@ class Settings {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Get the value of the WiFi/LTE toggle in settings.
 | 
			
		||||
    //!
 | 
			
		||||
    //! @return The state of the toggle.
 | 
			
		||||
    //
 | 
			
		||||
    static function getWifiLteExecutionEnabled() as Lang.Boolean {
 | 
			
		||||
        return mWifiLteExecution;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										236
									
								
								source/WifiLteExecution.mc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								source/WifiLteExecution.mc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,236 @@
 | 
			
		||||
using Toybox.WatchUi;
 | 
			
		||||
using Toybox.System;
 | 
			
		||||
using Toybox.Communications;
 | 
			
		||||
using Toybox.Lang;
 | 
			
		||||
using Toybox.Timer;
 | 
			
		||||
 | 
			
		||||
// Delegate to respond to a confirmation to execute command via bulk sync
 | 
			
		||||
//
 | 
			
		||||
class WifiLteExecutionConfirmDelegate extends WatchUi.ConfirmationDelegate {
 | 
			
		||||
    public static var mCommandData as {
 | 
			
		||||
        :type       as Lang.String,
 | 
			
		||||
        :service    as Lang.String or Null,
 | 
			
		||||
        :data       as Lang.Dictionary or Null,
 | 
			
		||||
        :url        as Lang.String or Null,
 | 
			
		||||
        :id         as Lang.Number or Null,
 | 
			
		||||
        :exit       as Lang.Boolean
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private var mToggleMethod   as Method(b as Lang.Boolean) as Void or Null;
 | 
			
		||||
    private var mToggleState    as Lang.Boolean or Null;
 | 
			
		||||
    private var mHasToast       as Lang.Boolean = false;
 | 
			
		||||
    private var mTimer          as Timer.Timer or Null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //! Initializes a confirmation delegate to confirm a Wi-Fi or LTE command exection
 | 
			
		||||
    //!
 | 
			
		||||
    //! @param options A dictionary describing the command to be executed:
 | 
			
		||||
    //!   - type:     The command type, either `"service"` or `"entity"`.
 | 
			
		||||
    //!   - service:  (For type `"service"`) The Home Assistant service to call (e.g., "light.turn_on").
 | 
			
		||||
    //!   - url:      (For type `"entity"`) The full Home Assistant entity API URL.
 | 
			
		||||
    //!   - callback: (For type `"entity"`) A callback method (Method<data as Dictionary>) to handle the response.
 | 
			
		||||
    //!   - data:     (Optional) A dictionary of data to send with the request.
 | 
			
		||||
    //!   = exit:     Boolean: true to exit after running command.
 | 
			
		||||
    //!
 | 
			
		||||
    //! @param toggleItem Optional toggle state information:
 | 
			
		||||
    //!   - confirmMethod: A method to call after confirmation.
 | 
			
		||||
    //!   - state:         The state (boolean) that will be passed to the confirmMethod.
 | 
			
		||||
    function initialize(cOptions as {
 | 
			
		||||
        :type     as Lang.String,
 | 
			
		||||
        :service  as Lang.String or Null,
 | 
			
		||||
        :data     as Lang.Dictionary or Null,
 | 
			
		||||
        :url      as Lang.String or Null,
 | 
			
		||||
        :callback as Lang.Method or Null,
 | 
			
		||||
        :exit     as Lang.Boolean,
 | 
			
		||||
    }, toggleItem as {
 | 
			
		||||
        :confirmMethod as Lang.Method,
 | 
			
		||||
        :state as Lang.Boolean
 | 
			
		||||
    } or Null) {
 | 
			
		||||
        if (WatchUi has :showToast) {
 | 
			
		||||
            mHasToast = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mCommandData = {
 | 
			
		||||
            :type => cOptions[:type],
 | 
			
		||||
            :service => cOptions[:service],
 | 
			
		||||
            :data => cOptions[:data],
 | 
			
		||||
            :url => cOptions[:url],
 | 
			
		||||
            :callback => cOptions[:callback],
 | 
			
		||||
            :exit => cOptions[:exit]
 | 
			
		||||
        };
 | 
			
		||||
        if (toggleItem != null) {
 | 
			
		||||
            mToggleMethod = toggleItem[:confirmMethod];
 | 
			
		||||
            mToggleState = toggleItem[:state];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var timeout = Settings.getConfirmTimeout(); // ms
 | 
			
		||||
        if (timeout > 0) {
 | 
			
		||||
            mTimer = new Timer.Timer();
 | 
			
		||||
            mTimer.start(method(:onTimeout), timeout, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ConfirmationDelegate.initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Handles the user's response to the confirmation dialog.
 | 
			
		||||
    //!
 | 
			
		||||
    //! @param response The user's confirmation response as `WatchUi.Confirm`
 | 
			
		||||
    //! @return Always returns `true` to indicate the response was handled.
 | 
			
		||||
    function onResponse(response) as Lang.Boolean {
 | 
			
		||||
        if (response == WatchUi.CONFIRM_YES) {
 | 
			
		||||
            if (mToggleMethod != null) {
 | 
			
		||||
                mToggleMethod.invoke(mToggleState);
 | 
			
		||||
            }
 | 
			
		||||
            trySync();
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Initiates a bulk sync process to execute a command, if connections are available
 | 
			
		||||
    private function trySync() as Void {
 | 
			
		||||
        WatchUi.popView(WatchUi.SLIDE_IMMEDIATE);
 | 
			
		||||
        var connectionInfo = System.getDeviceSettings().connectionInfo;
 | 
			
		||||
        var keys = connectionInfo.keys();
 | 
			
		||||
        var possibleConnection = false;
 | 
			
		||||
 | 
			
		||||
        for(var i = 0; i < keys.size(); i++) {
 | 
			
		||||
            if (keys[i] != :bluetooth) {
 | 
			
		||||
                var connection = connectionInfo[keys[i]];
 | 
			
		||||
                if (connection.state != System.CONNECTION_STATE_NOT_INITIALIZED) {
 | 
			
		||||
                    possibleConnection = true;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (possibleConnection) {
 | 
			
		||||
            var syncString = WatchUi.loadResource($.Rez.Strings.WifiLteExecutionTitle) as Lang.String;
 | 
			
		||||
            Communications.startSync2({:message => syncString});
 | 
			
		||||
        } else {
 | 
			
		||||
            var toast = WatchUi.loadResource($.Rez.Strings.WifiLteNotAvailable) as Lang.String;
 | 
			
		||||
            if (mHasToast) {
 | 
			
		||||
                WatchUi.showToast(toast, null);
 | 
			
		||||
            } else {
 | 
			
		||||
                new Alert({
 | 
			
		||||
                    :timeout => Globals.scAlertTimeout,
 | 
			
		||||
                    :font    => Graphics.FONT_MEDIUM,
 | 
			
		||||
                    :text    => toast,
 | 
			
		||||
                    :fgcolor => Graphics.COLOR_WHITE,
 | 
			
		||||
                    :bgcolor => Graphics.COLOR_BLACK
 | 
			
		||||
                }).pushView(WatchUi.SLIDE_IMMEDIATE);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Function supplied to a timer in order to limit the time for which the confirmation can be provided.
 | 
			
		||||
    function onTimeout() as Void {
 | 
			
		||||
        mTimer.stop();
 | 
			
		||||
        WatchUi.popView(WatchUi.SLIDE_RIGHT);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class HomeAssistantSyncDelegate extends Communications.SyncDelegate {
 | 
			
		||||
    private static var syncError as Lang.String or Null;
 | 
			
		||||
 | 
			
		||||
    // Initialize an instance of this delegate
 | 
			
		||||
    public function initialize() {
 | 
			
		||||
        SyncDelegate.initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Called by the system to determine if a sync is needed
 | 
			
		||||
    public function isSyncNeeded() as Lang.Boolean {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Called by the system when starting a bulk sync.
 | 
			
		||||
    public function onStartSync() as Void {
 | 
			
		||||
        syncError = null;
 | 
			
		||||
        
 | 
			
		||||
        if (WifiLteExecutionConfirmDelegate.mCommandData == null) {
 | 
			
		||||
            syncError = WatchUi.loadResource($.Rez.Strings.WifiLteExecutionDataError) as Lang.String;
 | 
			
		||||
            onStopSync();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        var type = WifiLteExecutionConfirmDelegate.mCommandData[:type];
 | 
			
		||||
        var data = WifiLteExecutionConfirmDelegate.mCommandData[:data];
 | 
			
		||||
        var url;
 | 
			
		||||
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case "service":
 | 
			
		||||
                var service = WifiLteExecutionConfirmDelegate.mCommandData[:service];
 | 
			
		||||
                url = Settings.getApiUrl() + "/services/" + service.substring(0, service.find(".")) + "/" + service.substring(service.find(".")+1, service.length());
 | 
			
		||||
                var entity_id = "";
 | 
			
		||||
                if (data != null) {
 | 
			
		||||
                    entity_id = data.get("entity_id");
 | 
			
		||||
                    if (entity_id == null) {
 | 
			
		||||
                        entity_id = "";
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                performRequest(url, data);
 | 
			
		||||
                break;
 | 
			
		||||
            case "entity":
 | 
			
		||||
                url = WifiLteExecutionConfirmDelegate.mCommandData[:url];
 | 
			
		||||
                performRequest(url, data);
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Performs a POST request to Hass with a given payload and URL, and calls haCallback
 | 
			
		||||
    private function performRequest(url as Lang.String, data as Lang.Dictionary or Null) {
 | 
			
		||||
        Communications.makeWebRequest(
 | 
			
		||||
            url,
 | 
			
		||||
            data, // May include {"entity_id": xxxx} for service calls
 | 
			
		||||
            {
 | 
			
		||||
                :method  => Communications.HTTP_REQUEST_METHOD_POST,
 | 
			
		||||
                :headers => {
 | 
			
		||||
                    "Content-Type"  => Communications.REQUEST_CONTENT_TYPE_JSON,
 | 
			
		||||
                    "Authorization" => "Bearer " + Settings.getApiKey()
 | 
			
		||||
                },
 | 
			
		||||
                :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
 | 
			
		||||
            },
 | 
			
		||||
            method(:haCallback)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Handle callback from request
 | 
			
		||||
    public function haCallback(code as Lang.Number, data as Null or Lang.Dictionary) as Void {
 | 
			
		||||
        if (code == 200) {
 | 
			
		||||
            syncError = null;
 | 
			
		||||
            if (WifiLteExecutionConfirmDelegate.mCommandData[:type].equals("entity")) {
 | 
			
		||||
                var callbackMethod = WifiLteExecutionConfirmDelegate.mCommandData[:callback];
 | 
			
		||||
                if (callbackMethod != null) {
 | 
			
		||||
                    var d = data as Lang.Array;
 | 
			
		||||
                    callbackMethod.invoke(d);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            onStopSync();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch(code) {
 | 
			
		||||
            case Communications.NETWORK_REQUEST_TIMED_OUT:
 | 
			
		||||
                syncError = WatchUi.loadResource($.Rez.Strings.TimedOut) as Lang.String;
 | 
			
		||||
                break;
 | 
			
		||||
            case Communications.INVALID_HTTP_BODY_IN_NETWORK_RESPONSE:
 | 
			
		||||
                syncError = WatchUi.loadResource($.Rez.Strings.NoJson) as Lang.String;
 | 
			
		||||
                syncError = "";
 | 
			
		||||
            default:
 | 
			
		||||
                var codeMsg = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr) as Lang.String;
 | 
			
		||||
                syncError = codeMsg + code;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        onStopSync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //! Clean up
 | 
			
		||||
    public function onStopSync() as Void {
 | 
			
		||||
        if (WifiLteExecutionConfirmDelegate.mCommandData[:exit]) {
 | 
			
		||||
            System.exit();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        Communications.cancelAllRequests();
 | 
			
		||||
        Communications.notifySyncComplete(syncError);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user