Procházet zdrojové kódy

Add ability to inject callback for when MQTT client connects

Christopher Mullins před 6 roky
rodič
revize
30f3f23090

+ 18 - 2
lib/MQTT/MqttClient.cpp

@@ -16,7 +16,8 @@ MqttClient::MqttClient(Settings& settings, MiLightClient*& milightClient)
   : mqttClient(tcpClient),
     milightClient(milightClient),
     settings(settings),
-    lastConnectAttempt(0)
+    lastConnectAttempt(0),
+    connected(false)
 {
   String strDomain = settings.mqttServer();
   this->domain = new char[strDomain.length() + 1];
@@ -30,6 +31,10 @@ MqttClient::~MqttClient() {
   delete this->domain;
 }
 
+void MqttClient::onConnect(OnConnectFn fn) {
+  this->onConnectFn = fn;
+}
+
 void MqttClient::begin() {
 #ifdef MQTT_DEBUG
   printf_P(
@@ -117,6 +122,13 @@ void MqttClient::reconnect() {
 void MqttClient::handleClient() {
   reconnect();
   mqttClient.loop();
+
+  if (!connected && mqttClient.connected()) {
+    this->connected = true;
+    this->onConnectFn();
+  } else if (!mqttClient.connected()) {
+    this->connected = false;
+  }
 }
 
 void MqttClient::sendUpdate(const MiLightRemoteConfig& remoteConfig, uint16_t deviceId, uint16_t groupId, const char* update) {
@@ -144,6 +156,10 @@ void MqttClient::subscribe() {
   mqttClient.subscribe(topic.c_str());
 }
 
+void MqttClient::send(const char* topic, const char* message, const bool retain) {
+  mqttClient.publish(topic, message, retain);
+}
+
 void MqttClient::publish(
   const String& _topic,
   const MiLightRemoteConfig &remoteConfig,
@@ -163,7 +179,7 @@ void MqttClient::publish(
   printf("MqttClient - publishing update to %s\n", topic.c_str());
 #endif
 
-  mqttClient.publish(topic.c_str(), message, retain);
+  send(topic.c_str(), message, retain);
 }
 
 void MqttClient::publishCallback(char* topic, byte* payload, int length) {

+ 6 - 0
lib/MQTT/MqttClient.h

@@ -13,6 +13,8 @@
 
 class MqttClient {
 public:
+  using OnConnectFn = std::function<void()>;
+
   MqttClient(Settings& settings, MiLightClient*& milightClient);
   ~MqttClient();
 
@@ -21,6 +23,8 @@ public:
   void reconnect();
   void sendUpdate(const MiLightRemoteConfig& remoteConfig, uint16_t deviceId, uint16_t groupId, const char* update);
   void sendState(const MiLightRemoteConfig& remoteConfig, uint16_t deviceId, uint16_t groupId, const char* update);
+  void send(const char* topic, const char* message, const bool retain = false);
+  void onConnect(OnConnectFn fn);
 
 private:
   WiFiClient tcpClient;
@@ -29,6 +33,8 @@ private:
   Settings& settings;
   char* domain;
   unsigned long lastConnectAttempt;
+  OnConnectFn onConnectFn;
+  bool connected;
 
   void sendBirthMessage();
   bool connect();

+ 7 - 0
src/main.cpp

@@ -239,6 +239,13 @@ void applySettings() {
   if (settings.mqttServer().length() > 0) {
     mqttClient = new MqttClient(settings, milightClient);
     mqttClient->begin();
+    mqttClient->onConnect([settings, mqttClient]() {
+      if (settings.homeAssistantDiscoveryPrefix.length() > 0) {
+        HomeAssistantDiscoveryClient discoveryClient(settings, mqttClient);
+        discoveryClient.sendDiscoverableDevices(settings.groupIdAliases);
+      }
+    });
+
     bulbStateUpdater = new BulbStateUpdater(settings, *mqttClient, *stateStore);
   }
 

+ 2 - 1
test/remote/spec/settings_spec.rb

@@ -27,7 +27,8 @@ RSpec.describe 'Settings' do
     it 'should persist known settings keys' do
       {
         'simple_mqtt_client_status' => [true, false],
-        'packet_repeats_per_loop' => [10]
+        'packet_repeats_per_loop' => [10],
+        'home_assistant_discovery_prefix' => ['', 'abc', 'a/b/c']
       }.each do |key, values|
         values.each do |v|
           @client.patch_settings({key => v})