예제 #1
0
        /// <summary>
        /// Hanlder for Google Home commands.
        /// </summary>
        /// <param name="command">The command to handle.</param>
        private async void HandleGoogleHomeCommand(Command command)
        {
            foreach (var commandDevice in command.Devices)
            {
                var device = _deviceRepository.Get(commandDevice.Id);
                if (device.Disabled)
                {
                    continue;
                }

                // Find all supported commands for the device
                var deviceSupportedCommands = device.Traits
                                              .SelectMany(x => x.Commands)
                                              .ToDictionary(x => x.Key, x => x.Value);

                foreach (var execution in command.Execution)
                {
                    // Check if device supports the requested command class
                    if (deviceSupportedCommands.ContainsKey(execution.Command))
                    {
                        // Find the specific commands supported parameters it can handle
                        var deviceSupportedCommandParams = deviceSupportedCommands[execution.Command];

                        // Flatten the parameters
                        var flattenedParams = execution.Params.ToFlatDictionary();

                        foreach (var parameter in flattenedParams)
                        {
                            // Check if device supports the requested parameter
                            if (deviceSupportedCommandParams.ContainsKey(parameter.Key))
                            {
                                // Handle remapping of Modes, Toggles and FanSpeed
                                var stateKey = CommandToStateKeyMapper.Map(parameter.Key);

                                // Find the DeviceState object that provides configuration for mapping state/command values
                                var deviceState = device.Traits
                                                  .Where(x => x.Commands.ContainsKey(execution.Command))
                                                  .SelectMany(x => x.State)
                                                  .Where(x => x.Key == stateKey)
                                                  .Select(x => x.Value)
                                                  .FirstOrDefault();

                                // Build the MQTT message
                                var    topic   = deviceSupportedCommandParams[parameter.Key];
                                string payload = null;
                                if (deviceState != null)
                                {
                                    payload = deviceState.MapValueToMqtt(parameter.Value);
                                }
                                else
                                {
                                    payload = parameter.Value.ToString();
                                    _log.LogWarning("Received supported command '{Command}' but cannot find matched state config, sending command value '{Payload}' without ValueMap", execution.Command, payload);
                                }

                                await MqttClient.PublishAsync(new MqttApplicationMessageBuilder()
                                                              .WithTopic(topic)
                                                              .WithPayload(payload)
                                                              .WithAtLeastOnceQoS()
                                                              .Build())
                                .ConfigureAwait(false);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Hanlder for Google Home commands.
        /// </summary>
        /// <param name="command">The command to handle.</param>
        private async void HandleGoogleHomeCommand(Command command)
        {
            foreach (var device in command.Devices)
            {
                // Find all supported commands for the device
                var deviceSupportedCommands = _deviceRepository.Get(device.Id).Traits
                                              .SelectMany(x => x.Commands)
                                              .ToDictionary(x => x.Key, x => x.Value);

                foreach (var execution in command.Execution)
                {
                    // Check if device supports the requested command class
                    if (deviceSupportedCommands.ContainsKey(execution.Command))
                    {
                        // Find the specific commands supported parameters it can handle
                        var deviceSupportedCommandParams = deviceSupportedCommands[execution.Command];

                        // Flatten the parameters
                        var flattenedParams = new Dictionary <string, object>();
                        foreach (var param in execution.Params)
                        {
                            var paramValueAsDictionary = param.Value as IDictionary <string, object>;
                            if (paramValueAsDictionary != null)
                            {
                                // Add each of the sub params as a flattened, prefixed parameter
                                foreach (var subParam in paramValueAsDictionary)
                                {
                                    flattenedParams.Add(param.Key + '.' + subParam.Key, subParam.Value);
                                }
                            }
                            else
                            {
                                // Pipe through original value
                                flattenedParams.Add(param.Key, param.Value);
                            }
                        }

                        foreach (var parameter in flattenedParams)
                        {
                            // Check if device supports the requested parameter
                            if (deviceSupportedCommandParams.ContainsKey(parameter.Key))
                            {
                                // Handle remapping of Modes and Toggles
                                var stateKey = parameter.Key;
                                if (parameter.Key.StartsWith("updateModeSettings."))
                                {
                                    stateKey = parameter.Key.Replace("updateModeSettings.", "currentModeSettings.");
                                }
                                else if (parameter.Key.StartsWith("updateToggleSettings."))
                                {
                                    stateKey = parameter.Key.Replace("updateToggleSettings.", "currentToggleSettings.");
                                }

                                // Find the DeviceState object that provides configuration for mapping state/command values
                                var deviceState = _deviceRepository.Get(device.Id).Traits
                                                  .Where(x => x.Commands.ContainsKey(execution.Command))
                                                  .SelectMany(x => x.State)
                                                  .Where(x => x.Key == stateKey)
                                                  .Select(x => x.Value)
                                                  .FirstOrDefault();

                                // Send the MQTT message
                                var topic   = deviceSupportedCommandParams[parameter.Key];
                                var payload = deviceState.MapValueToMqtt(parameter.Value);
                                await MqttClient.PublishAsync(new MqttApplicationMessageBuilder()
                                                              .WithTopic(topic)
                                                              .WithPayload(payload)
                                                              .WithAtLeastOnceQoS()
                                                              .Build())
                                .ConfigureAwait(false);
                            }
                        }
                    }
                }
            }
        }