コード例 #1
0
ファイル: MQTT.cs プロジェクト: Geving/BachelorPad
        private static async Task MqttClient_Connected(object sender, MqttClientConnectedEventArgs e)
        {
            try
            {
                ReconnectionFailures = 0; //Reset errorcounter

                // Suscribe to our default topics
                List <string> topics = new List <string>()
                {
                    $"{Program.Settings.MQTT_BASETOPIC}/$broadcast/#",      // Example: homie/$broadcast/alert ← "Intruder detected"
                    $"{BasePublishingTopic}/get/",                          // Used for get-/setting data that's not part of the Homie specs, like
                    $"{BasePublishingTopic}/set/",                          // config files, config and such.
                    $"{BasePublishingTopic}/RAW/in/",                       // Allows the user to send raw bytes to the CI
                    $"{BasePublishingTopic}/raw/in/",                       // Same as RAW, but the bytes are now human readable strings "06 C1 04 ..."
                    $"{BasePublishingTopic}/cmd/"                           // A way to receive simple commands like "exit"
                    //$"{BasePublishingTopic}/shell/#"                      // Runs shell commands on the system. Potensial SECURITY HOLE
                };

                // Time to tell everyone about our devices, and set up a subscription for that device if needed.
                foreach (Homie.Device device in Homie.devices)
                {
                    await MQTT.PublishDeviceAsync(device);                  // Publishes a LOT of information

                    foreach (Homie.Node node in device.Node)
                    {
                        foreach (Homie.Property property in node.PropertyList)
                        {
                            if (property.Settable == "true")                // If this is a settable value, we need to subscribe to a topic for it
                            {
                                //await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Program.Settings.MQTT_BASETOPIC}/{device.Name}/{node.PathName}/{property.PathName}/set".Replace("//","/")).Build());
                                topics.Add($"{Program.Settings.MQTT_BASETOPIC}/{device.Name}/{node.PathName}/{property.PathName}/set");
                            }
                            if (device.Datapoint.Class == 0)                // If this is a pollable value, we need to subscribe to a topic for that as well
                            {
                                //await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Program.Settings.MQTT_BASETOPIC}/{device.Name}/{node.PathName}/{property.PathName}/poll".Replace("//", "/")).Build());
                                topics.Add($"{Program.Settings.MQTT_BASETOPIC}/{device.Name}/{node.PathName}/{property.PathName}/poll");  // This will allow us to request an update from the device
                            }
                        }
                    }
                }

                foreach (string unsafetopic in topics)
                {
                    string topic = unsafetopic.Replace("//", "/");          // Depending on what the user has put in the settings file, this might contain //, so we remove them just in case.
                    await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic(topic).Build());

                    if (topic.EndsWith("/"))
                    {
                        await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic(topic.Remove(topic.Length - 1)).Build());
                    }                                                                                                                                      // This allows us to subscribe to both topics at once.
                    //if (Program.Settings.GENERAL_DEBUGMODE) DoLog($"Subscribing to {topic}", 2);
                }

                while (mqttClient.IsConnected && Program.StayAlive) // As long as we are connected, we need to send the stats periodically
                {
                    System.Threading.Thread.Sleep(Convert.ToInt32(Program.Settings.HOMIE_STATS_INTERVAL) * 1000);
                    await Homie.PublishStats();
                }
            }
            catch (Exception exception)
            {
                LogException(exception);
            }
        }