/// <summary>
        /// Handles commands for the Harmony published to MQTT.
        /// </summary>
        /// <param name="e">Event args.</param>
        protected override async void Mqtt_MqttMsgPublishReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            var message = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);

            _log.LogInformation("MQTT message received for topic " + e.ApplicationMessage.Topic + ": " + message);

            // Parse topic out
            var topicWithoutRoot = e.ApplicationMessage.Topic.Substring(TopicRoot.Length + 1);
            var thermostatId     = topicWithoutRoot.Substring(0, topicWithoutRoot.IndexOf('/'));
            var thermostatTopic  = topicWithoutRoot.Substring(topicWithoutRoot.IndexOf('/') + 1);

            // ONLY VALID OPTIONS
            // HvacMode (auto, auxHeatOnly, cool, heat, off) - hvacMode/set
            // Fan (on, off, auto) - desiredFanMode/set
            // SetHold ({ hold object }) - hold/set
            // Desired Heat - desiredHeat/set
            // Desired Cool - desiredCool/set
            var request = new ThermostatUpdateRequest
            {
                Selection = new Selection
                {
                    SelectionType  = "thermostats",
                    SelectionMatch = thermostatId
                }
            };

            _log.LogInformation($"Sending request to {request.Uri} with thermostat selection {thermostatId} for action {thermostatTopic}");

            switch (thermostatTopic)
            {
            case "desiredCool/set":
                if (int.TryParse(message, out int desiredCoolValue) && int.TryParse(_thermostatStatus[thermostatId].Status["desiredHeat"], out int currentDesiredHeatValue))
                {
                    request.Functions = new List <Function>
                    {
                        new SetHoldFunction
                        {
                            Params = new SetHoldParams
                            {
                                HoldType     = "nextTransition",
                                CoolHoldTemp = desiredCoolValue * 10,
                                HeatHoldTemp = currentDesiredHeatValue * 10
                            }
                        }
                    };
                    var desiredCoolResponse = await _client.PostAsync <ThermostatUpdateRequest, Response>(request)
                                              .ConfigureAwait(false);

                    _log.LogInformation($"{request.Uri} response: ({desiredCoolResponse.Status.Code}) {desiredCoolResponse.Status.Message}");

                    // Publish updates and cache new values
                    await GetInitialStatusAsync();
                }

                break;

            case "desiredFanMode/set":
                if (message == "auto" || message == "off" || message == "on")
                {
                    request.Functions = new List <Function>
                    {
                        new SetHoldFunction
                        {
                            Params = new SetHoldParams
                            {
                                HoldType = "nextTransition",
                                Fan      = message
                            }
                        }
                    };

                    var desiredFanModeResponse = await _client.PostAsync <ThermostatUpdateRequest, Response>(request)
                                                 .ConfigureAwait(false);

                    _log.LogInformation($"{request.Uri} response: ({desiredFanModeResponse.Status.Code}) {desiredFanModeResponse.Status.Message}");

                    // Publish updates and cache new values
                    await GetInitialStatusAsync();
                }

                break;

            case "desiredHeat/set":
                if (int.TryParse(message, out int desiredHeatValue) && int.TryParse(_thermostatStatus[thermostatId].Status["desiredCool"], out int currentDesiredCoolValue))
                {
                    request.Functions = new List <Function>
                    {
                        new SetHoldFunction
                        {
                            Params = new SetHoldParams
                            {
                                HoldType     = "nextTransition",
                                CoolHoldTemp = currentDesiredCoolValue * 10,
                                HeatHoldTemp = desiredHeatValue * 10
                            }
                        }
                    };

                    var desiredHeatResponse = await _client.PostAsync <ThermostatUpdateRequest, Response>(request)
                                              .ConfigureAwait(false);

                    _log.LogInformation($"{request.Uri} response: ({desiredHeatResponse.Status.Code}) {desiredHeatResponse.Status.Message}");

                    // Publish updates and cache new values
                    await GetInitialStatusAsync();
                }

                break;

            case "hold/set":
                try
                {
                    if (message.Contains("resumeProgram"))
                    {
                        var resumeFunction = JsonSerializer <ResumeProgramFunction> .Deserialize(message);

                        request.Functions = new List <Function>
                        {
                            resumeFunction
                        };
                    }
                    else
                    {
                        var holdFunction = JsonSerializer <SetHoldFunction> .Deserialize(message);

                        request.Functions = new List <Function>
                        {
                            holdFunction
                        };
                    }

                    var setHoldResponse = await _client.PostAsync <ThermostatUpdateRequest, Response>(request)
                                          .ConfigureAwait(false);

                    _log.LogInformation($"{request.Uri} response: ({setHoldResponse.Status.Code}) {setHoldResponse.Status.Message}");

                    // Publish updates and cache new values
                    await GetInitialStatusAsync();
                }
                catch (JsonException ex)
                {
                    _log.LogWarning(ex, $"Could not deserialize payload: {message}");
                }

                break;

            case "hvacMode/set":
                if (message == "auto" || message == "auxHeatOnly" || message == "cool" || message == "heat" || message == "off")
                {
                    request.Thermostat = new { Settings = new { HvacMode = message } };
                    var hvacModeResponse = await _client.PostAsync <ThermostatUpdateRequest, Response>(request)
                                           .ConfigureAwait(false);

                    _log.LogInformation($"{request.Uri} response: ({hvacModeResponse.Status.Code}) {hvacModeResponse.Status.Message}");

                    // Publish updates and cache new values
                    await GetInitialStatusAsync();
                }

                break;

            default:
                _log.LogWarning($"Unknown command topic {thermostatTopic} for thermostat {thermostatId}");
                break;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Handles commands for the Harmony published to MQTT.
        /// </summary>
        /// <param name="e">Event args.</param>
        protected override async void Mqtt_MqttMsgPublishReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            var message = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);

            _log.LogInformation("MQTT message received for topic " + e.ApplicationMessage.Topic + ": " + message);

            // Parse topic out
            var topicWithoutRoot = e.ApplicationMessage.Topic.Substring(TopicRoot.Length + 1);
            var thermostatId     = topicWithoutRoot.Substring(0, topicWithoutRoot.IndexOf('/'));
            var thermostatTopic  = topicWithoutRoot.Substring(topicWithoutRoot.IndexOf('/') + 1);

            // ONLY VALID OPTIONS
            // HvacMode (auto, auxHeatOnly, cool, heat, off) - hvacMode/set
            // Fan (on, off, auto) - desiredFanMode/set
            // SetHold (hold, resume) - hold/set
            // Desired Heat - desiredHeat/set
            // Desired Cool - desiredCool/set
            var request = new ThermostatUpdateRequest
            {
                Selection = new Selection {
                    SelectionType = "thermostats", SelectionMatch = thermostatId
                }
            };

            _log.LogInformation($"Sending request to {request.Uri} with thermostat selection {thermostatId} for action {thermostatTopic}");

            switch (thermostatTopic)
            {
            case "hvacMode/set":
                request.Thermostat = new { Settings = new { HvacMode = message } };
                var hvacModeResponse = await _client.PostAsync <ThermostatUpdateRequest, Response>(request)
                                       .ConfigureAwait(false);

                _log.LogInformation($"{request.Uri} response: ({hvacModeResponse.Status.Code}) {hvacModeResponse.Status.Message}");
                break;

            case "desiredFanMode/set":
                request.Thermostat = new { Settings = new { Vent = message } };
                var desiredFanModeResponse = await _client.PostAsync <ThermostatUpdateRequest, Response>(request)
                                             .ConfigureAwait(false);

                _log.LogInformation($"{request.Uri} response: ({desiredFanModeResponse.Status.Code}) {desiredFanModeResponse.Status.Message}");
                break;

            case "hold/set":
                if (message == "hold")
                {
                    // TODO: Figure out how to pass both desired heat and cool values at same time
                    var holdFunc = new SetHoldFunction();
                    ((SetHoldParams)holdFunc.Params).HoldType     = "indefinite";
                    ((SetHoldParams)holdFunc.Params).CoolHoldTemp = 0;
                    ((SetHoldParams)holdFunc.Params).HeatHoldTemp = 0;
                    request.Functions.Add(holdFunc);
                    ////_client.Post<ThermostatUpdateRequest, Response>(request);
                }
                else
                {
                    var resumeFunc = new ResumeProgramFunction();
                    ((ResumeProgramParams)resumeFunc.Params).ResumeAll = true;
                    request.Functions.Add(resumeFunc);
                    await _client.PostAsync <ThermostatUpdateRequest, Response>(request)
                    .ConfigureAwait(false);
                }

                break;

            case "desiredHeat/set":
                if (int.TryParse(message, out int desiredHeatValue))
                {
                    request.Thermostat = new { Runtime = new { DesiredHeat = desiredHeatValue * 10 } };
                    var desiredHeatResponse = await _client.PostAsync <ThermostatUpdateRequest, Response>(request)
                                              .ConfigureAwait(false);

                    _log.LogInformation($"{request.Uri} response: ({desiredHeatResponse.Status.Code}) {desiredHeatResponse.Status.Message}");
                }

                break;

            case "desiredCool/set":
                if (int.TryParse(message, out int desiredCoolValue))
                {
                    request.Thermostat = new { Runtime = new { DesiredCool = desiredCoolValue * 10 } };
                    var desiredCoolResponse = await _client.PostAsync <ThermostatUpdateRequest, Response>(request)
                                              .ConfigureAwait(false);

                    _log.LogInformation($"{request.Uri} response: ({desiredCoolResponse.Status.Code}) {desiredCoolResponse.Status.Message}");
                }

                break;

            default:
                _log.LogWarning($"Unknown command topic {thermostatTopic} for thermostat {thermostatId}");
                break;
            }
        }