public async Task ProcessStateChangeAsync(AquaConnect currentState, string attribute, string newState)
        {
            int    buttonPresses = 1;
            string key           = string.Empty;

            try
            {
                ProcessingStateChange = true;

                var startTime = DateTime.Now;

                logger.Log(LogLevel.Information, $"Processing state change STARTED(StartTime: {startTime}).");

                // also changes currentState to match the intended final state
                GetKeyToChangeState(currentState, attribute, newState, ref buttonPresses, ref key, out var message);

                currentState.Message = message;

                logger.Log(LogLevel.Information, $"Processing state change: {key} X {buttonPresses}.");

                //don't let anything change if in service mode, or menu locked
                if (!currentState.IsDisabled && key.Length > 0)
                {
                    //press the pool button
                    var success = await PostWebStrKeyAsync(key);

                    //press the pool button again to change to the
                    //next state since we want to skip the previous state
                    if (buttonPresses == 2 && success)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(Constants.PROCESS_CHANGE_DELAY_SEC));

                        await PostWebStrKeyAsync(key);
                    }
                }
                logger.Log(LogLevel.Information, $"Processing state change FINISHED(StartTime: {startTime}).");
            }
            finally
            {
                currentState.Message = string.Empty;

                ProcessingStateChange = false;
            }
        }
        private async Task GetWebStrResponse()
        {
            var result = await webStrService.GetWebStrReponseAsync();

            if (!webStrService.ProcessingStateChange)
            {
                var keyState = webStrService.ProcessRawLedData(result.LineThree);

                pool.KeyStates = keyState;
            }

            pool.IsDisabled     = result.IsConfigMenuLocked || result.IsServiceMode;
            pool.DisplayLineOne = result.LineOne;
            pool.DisplayLineTwo = result.LineTwo;

            if (result.AirTemp.HasValue)
            {
                pool.AirTemperature = result.AirTemp.Value;
            }

            if (result.PoolTemp.HasValue)
            {
                pool.PoolTemperature     = result.PoolTemp.Value;
                pool.PoolTemperatureAsOf = DateTime.Now;
            }

            if (result.SpaTemp.HasValue)
            {
                pool.SpaTemperature     = result.SpaTemp.Value;
                pool.SpaTemperatureAsOf = DateTime.Now;
            }

            if (result.IsHeaterInAutoControl.HasValue)
            {
                pool.IsHeaterInAutoControl = result.IsHeaterInAutoControl.Value;
            }

            AquaConnect.Searlize(pool);
        }
        private void GetKeyToChangeState(AquaConnect currentState, string attribute, string newState, ref int buttonPresses, ref string key, out string message)
        {
            message = "";

            switch (attribute.ToLower())
            {
            case "lights":
                //if the lights are off, turn them on
                //if the lights are on, turn them off
                //there is also colors, but not sure on the sequence yet
                if ((currentState.IsLightsOn == false && newState.Equals("on", StringComparison.InvariantCultureIgnoreCase)) ||
                    (currentState.IsLightsOn == true && newState.Equals("off", StringComparison.InvariantCultureIgnoreCase)))
                {
                    message = $"Ligths: {(currentState.IsLightsOn ? "on" : "off")} -> {newState}";

                    currentState.IsLightsOn = newState.Equals("on", StringComparison.InvariantCultureIgnoreCase);

                    key = "09";
                }
                logger.Log(LogLevel.Information, "Processing state change: Lights.");
                break;

            case "poolmode":
                var newPoolMode = Enum.Parse <PoolMode>(newState, true);

                //don't change anything if we are already in "new" state
                if (currentState.Mode == newPoolMode)
                {
                    break;
                }

                key = "07";

                message = $"Mode: {currentState.Mode}";

                switch (currentState.Mode)
                {
                case PoolMode.Pool:
                    message = $"{message} -> {PoolMode.Spa}";
                    if (newPoolMode == PoolMode.Spillover)
                    {
                        message       = $"{message} -> {newPoolMode}";
                        buttonPresses = 2;
                    }
                    break;

                case PoolMode.Spa:
                    message = $"{message} -> {PoolMode.Spillover}";
                    if (newPoolMode == PoolMode.Pool)
                    {
                        message       = $"{message} -> {newPoolMode}";
                        buttonPresses = 2;
                    }
                    break;

                case PoolMode.Spillover:
                    message = $"{message} -> {PoolMode.Pool}";
                    if (newPoolMode == PoolMode.Spillover)
                    {
                        message       = $"{message} -> {newPoolMode}";
                        buttonPresses = 2;
                    }
                    break;
                }

                logger.Log(LogLevel.Information, $"Processing state change: Mode - {currentState.Mode} -> {newPoolMode}.");

                //change cached state
                currentState.Mode = newPoolMode;

                break;

            case "filtermode":
                var newFilterMode = Enum.Parse <FilterMode>(newState, true);

                //don't change anything if we are already in "new" state
                if (currentState.FilterMode == newFilterMode)
                {
                    break;
                }

                key = "08";

                message = $"Speed: {currentState.FilterMode}";

                switch (currentState.FilterMode)
                {
                case FilterMode.High:
                    message = $"{message} -> {FilterMode.Low}";
                    if (newFilterMode == FilterMode.Off)
                    {
                        message       = $"{message} -> {newFilterMode}";
                        buttonPresses = 2;
                    }
                    break;

                case FilterMode.Low:
                    message = $"{message} -> {FilterMode.Off}";
                    if (newFilterMode == FilterMode.High)
                    {
                        message       = $"{message} -> {newFilterMode}";
                        buttonPresses = 2;
                    }
                    break;

                case FilterMode.Off:
                    message = $"{message} -> {FilterMode.High}";
                    if (newFilterMode == FilterMode.Low)
                    {
                        message       = $"{message} -> {newFilterMode}";
                        buttonPresses = 2;
                    }
                    break;
                }

                logger.Log(LogLevel.Information, $"Processing state change: Filter - {currentState.FilterMode} -> {newFilterMode}.");

                //change cached state
                currentState.FilterMode = newFilterMode;
                break;

            case "heater-auto":
                if ((currentState.IsHeaterInAutoControl == false && newState.Equals("on", StringComparison.InvariantCultureIgnoreCase)) ||
                    (currentState.IsHeaterInAutoControl == true && newState.Equals("off", StringComparison.InvariantCultureIgnoreCase)))
                {
                    message = $"Heater-Auto: {(currentState.IsHeaterInAutoControl ? "on" : "off")} -> {newState}";

                    currentState.IsHeaterInAutoControl = newState.Equals("on", StringComparison.InvariantCultureIgnoreCase);

                    key = "13";
                }
                logger.Log(LogLevel.Information, "Processing state change: Heater-Auto.");
                break;
            }
        }
 public WebStrBackgroundService(ILogger <WebStrBackgroundService> logger, WebStrService webStrService, AquaConnect pool)
 {
     this.logger        = logger;
     this.webStrService = webStrService;
     this.pool          = pool;
 }
 public AquaConnectController(ILogger <AquaConnectController> logger, WebStrService webStrService, AquaConnect pool)
 {
     this.logger        = logger;
     this.webStrService = webStrService;
     this.pool          = pool;
 }