Ejemplo n.º 1
0
        /// <summary>
        /// Index.
        /// </summary>
        /// <returns>Response.</returns>
        public IActionResult Index()
        {
            var model = _deviceRepository.GetAll()
                        .OrderBy(device => device.Id)
                        .ToList();

            return(View(model));
        }
        /// <inheritdoc />
        protected override void Mqtt_MqttMsgPublishReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            var topic   = e.ApplicationMessage.Topic;
            var message = e.ApplicationMessage.ConvertPayloadToString();

            _log.LogInformation("MQTT message received for topic {Topic}: {Message}", topic, message);

            if (topic == TopicRoot + "/REQUEST_SYNC")
            {
                _messageHub.Publish(new RequestSyncEvent());
            }
            else if (_stateCache.TryGetValue(topic, out string currentState))
            {
                if (_stateCache.TryUpdate(topic, message, currentState))
                {
                    // Identify updated devices that handle reportState
                    var devices = _deviceRepository.GetAll()
                                  .Where(device => !device.Disabled)
                                  .Where(device => device.WillReportState)
                                  .Where(device => device.Traits.Any(trait => trait.State.Values.Any(state => state.Topic == topic)))
                                  .ToList();

                    // Trigger reportState
                    _messageHub.Publish(new ReportStateEvent {
                        Devices = devices
                    });
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Handles a <see cref="Models.Request.SyncIntent"/>.
        /// </summary>
        /// <param name="intent">Intent to process.</param>
        /// <returns>A <see cref="Models.Response.SyncResponsePayload"/>.</returns>
        public Models.Response.SyncResponsePayload Handle(Models.Request.SyncIntent intent)
        {
            _log.LogInformation("Received SYNC intent");

            // Convert to an event to publish
            var commandEvent = new SyncIntentReceivedEvent {
                Time = DateTimeOffset.Now
            };

            _messageHub.Publish(commandEvent);

            var syncResponsePayload = new Models.Response.SyncResponsePayload
            {
                AgentUserId = _config.GetValue <string>("googleHomeGraph:agentUserId"),
                Devices     = _deviceRepository.GetAll()
                              .Where(device => !device.Disabled)
                              .Select(x => new Models.Response.Device
                {
                    Id              = x.Id,
                    Type            = x.Type,
                    RoomHint        = x.RoomHint,
                    WillReportState = x.WillReportState,
                    Traits          = x.Traits.Select(trait => trait.Trait).ToList(),
                    Attributes      = x.Traits
                                      .Where(trait => trait.Attributes != null)
                                      .SelectMany(trait => trait.Attributes)
                                      .ToDictionary(kv => kv.Key, kv => kv.Value),
                    Name       = x.Name,
                    DeviceInfo = x.DeviceInfo,
                    CustomData = x.CustomData
                }).ToList()
            };

            return(syncResponsePayload);
        }
        /// <summary>
        /// Handles a <see cref="Models.Request.QueryIntent"/>.
        /// </summary>
        /// <param name="intent">Intent to process.</param>
        /// <returns>A <see cref="Models.Response.QueryResponsePayload"/>.</returns>
        public Models.Response.QueryResponsePayload Handle(Models.Request.QueryIntent intent)
        {
            _log.LogInformation("Received QUERY intent for devices: " + string.Join(", ", intent.Payload.Devices.Select(x => x.Id)));

            // Payload for disabled a or missing device
            var offlineDeviceState = new Dictionary <string, object>
            {
                { "errorCode", "deviceNotFound" },
                { "online", false }
            };

            // Get distinct devices
            var distinctRequestDeviceIds = intent.Payload.Devices
                                           .GroupBy(device => device.Id)
                                           .Select(group => group.First())
                                           .Select(device => device.Id);

            var devices = _deviceRepository.GetAll()
                          .Where(device => !device.Disabled)
                          .Where(device => distinctRequestDeviceIds.Contains(device.Id))
                          .ToList();

            // Build reponse payload
            var queryResponsePayload = new Models.Response.QueryResponsePayload
            {
                Devices = distinctRequestDeviceIds
                          .ToDictionary(
                    queryDeviceId => queryDeviceId,
                    queryDeviceId =>
                {
                    var device = devices.FirstOrDefault(x => x.Id == queryDeviceId);
                    return(device != null ? device.GetGoogleQueryState(_stateCache) : offlineDeviceState);
                })
            };

            // Trigger reportState before returning
            var reportStateDevices       = devices.Where(device => device.WillReportState).ToList();
            var shouldTriggerReportState = false;

            if (reportStateDevices.Any() && shouldTriggerReportState)
            {
                _messageHub.Publish(new ReportStateEvent {
                    Devices = reportStateDevices
                });
            }

            return(queryResponsePayload);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Handles a <see cref="Models.Request.QueryIntent"/>.
        /// </summary>
        /// <param name="intent">Intent to process.</param>
        /// <returns>A <see cref="Models.Response.QueryResponsePayload"/>.</returns>
        public Models.Response.QueryResponsePayload Handle(Models.Request.QueryIntent intent)
        {
            _log.LogInformation("Received QUERY intent for devices: " + string.Join(", ", intent.Payload.Devices.Select(x => x.Id)));

            // Payload for disabled a or missing device
            var offlineDeviceState = new Dictionary <string, object>
            {
                { "errorCode", "deviceNotFound" },
                { "online", false },
                { "status", "ERROR" }
            };

            // Get distinct devices
            var distinctRequestDeviceIds = intent.Payload.Devices
                                           .GroupBy(device => device.Id)
                                           .Select(group => group.First())
                                           .Select(device => device.Id);

            // Convert to an event to publish
            var commandEvent = new QueryIntentReceivedEvent {
                Devices = intent.Payload.Devices, Time = DateTimeOffset.Now
            };

            _messageHub.Publish(commandEvent);

            var devices = _deviceRepository.GetAll()
                          .Where(device => !device.Disabled)
                          .Where(device => distinctRequestDeviceIds.Contains(device.Id))
                          .ToList();

            // Build reponse payload
            var queryResponsePayload = new Models.Response.QueryResponsePayload
            {
                Devices = distinctRequestDeviceIds
                          .ToDictionary(
                    queryDeviceId => queryDeviceId,
                    queryDeviceId =>
                {
                    var device  = devices.FirstOrDefault(x => x.Id == queryDeviceId);
                    var results = device != null ? device.GetGoogleState(_stateCache) : offlineDeviceState;

                    // Add explicit status if not specified by state mappings
                    if (!results.ContainsKey("status"))
                    {
                        results.Add("status", "SUCCESS");
                    }

                    return(results);
                })
            };

            // Trigger reportState before returning
            var reportStateDevices       = devices.Where(device => device.WillReportState).ToList();
            var shouldTriggerReportState = false;

            if (reportStateDevices.Any() && shouldTriggerReportState)
            {
                _messageHub.Publish(new ReportStateEvent {
                    Devices = reportStateDevices
                });
            }

            return(queryResponsePayload);
        }