瀏覽代碼

separate topic for full state (commands/deltas sent to updates topic)

Chris Mullins 8 年之前
父節點
當前提交
f5d16feae8

文件差異過大導致無法顯示
+ 2 - 2
dist/index.html.gz.h


+ 25 - 17
lib/MQTT/MqttClient.cpp

@@ -87,24 +87,11 @@ void MqttClient::handleClient() {
 }
 
 void MqttClient::sendUpdate(const MiLightRemoteConfig& remoteConfig, uint16_t deviceId, uint16_t groupId, const char* update) {
-  String topic = settings.mqttUpdateTopicPattern;
-
-  if (topic.length() == 0) {
-    return;
-  }
-
-  String deviceIdStr = String(deviceId, 16);
-  deviceIdStr.toUpperCase();
-
-  topic.replace(":device_id", String("0x") + deviceIdStr);
-  topic.replace(":group_id", String(groupId));
-  topic.replace(":device_type", remoteConfig.name);
-
-#ifdef MQTT_DEBUG
-  printf_P(PSTR("MqttClient - publishing update to %s: %s\n"), topic.c_str(), update);
-#endif
+  publish(settings.mqttUpdateTopicPattern, remoteConfig, deviceId, groupId, update);
+}
 
-  mqttClient->publish(topic.c_str(), update);
+void MqttClient::sendState(const MiLightRemoteConfig& remoteConfig, uint16_t deviceId, uint16_t groupId, const char* update) {
+  publish(settings.mqttStateTopicPattern, remoteConfig, deviceId, groupId, update);
 }
 
 void MqttClient::subscribe() {
@@ -121,6 +108,27 @@ void MqttClient::subscribe() {
   mqttClient->subscribe(topic.c_str());
 }
 
+void MqttClient::publish(const String& _topic, const MiLightRemoteConfig &remoteConfig, uint16_t deviceId, uint16_t groupId, const char* message) {
+  if (_topic.length() == 0) {
+    return;
+  }
+
+  String topic = _topic;
+
+  String deviceIdStr = String(deviceId, 16);
+  deviceIdStr.toUpperCase();
+
+  topic.replace(":device_id", String("0x") + deviceIdStr);
+  topic.replace(":group_id", String(groupId));
+  topic.replace(":device_type", remoteConfig.name);
+
+#ifdef MQTT_DEBUG
+  printf_P(PSTR("MqttClient - publishing update to %s: %s\n"), topic.c_str(), update);
+#endif
+
+  mqttClient->publish(topic.c_str(), message);
+}
+
 void MqttClient::publishCallback(char* topic, byte* payload, int length) {
   uint16_t deviceId = 0;
   uint8_t groupId = 0;

+ 2 - 0
lib/MQTT/MqttClient.h

@@ -20,6 +20,7 @@ public:
   void handleClient();
   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);
 
 private:
   WiFiClient tcpClient;
@@ -32,6 +33,7 @@ private:
   bool connect();
   void subscribe();
   void publishCallback(char* topic, byte* payload, int length);
+  void publish(const String& topic, const MiLightRemoteConfig& remoteConfig, uint16_t deviceId, uint16_t groupId, const char* update);
 };
 
 #endif

+ 6 - 2
lib/MiLight/MiLightClient.cpp

@@ -4,12 +4,14 @@
 #include <RGBConverter.h>
 #include <Units.h>
 
-MiLightClient::MiLightClient(MiLightRadioFactory* radioFactory)
+MiLightClient::MiLightClient(MiLightRadioFactory* radioFactory, GroupStateStore& stateStore)
   : resendCount(MILIGHT_DEFAULT_RESEND_COUNT),
     currentRadio(NULL),
     currentRemote(NULL),
     numRadios(MiLightRadioConfig::NUM_CONFIGS),
-    packetSentHandler(NULL)
+    packetSentHandler(NULL),
+    stateStore(stateStore),
+    currentState(NULL)
 {
   radios = new MiLightRadio*[numRadios];
 
@@ -70,6 +72,8 @@ void MiLightClient::prepare(const MiLightRemoteConfig* config,
   if (deviceId >= 0 && groupId >= 0) {
     currentRemote->packetFormatter->prepare(deviceId, groupId);
   }
+
+  currentState = stateStore.get(GroupId(deviceId, groupId, config->type));
 }
 
 void MiLightClient::prepare(const MiLightRemoteType type,

+ 4 - 1
lib/MiLight/MiLightClient.h

@@ -5,6 +5,7 @@
 #include <MiLightButtons.h>
 #include <MiLightRemoteConfig.h>
 #include <Settings.h>
+#include <GroupStateStore.h>
 
 #ifndef _MILIGHTCLIENT_H
 #define _MILIGHTCLIENT_H
@@ -17,7 +18,7 @@
 
 class MiLightClient {
 public:
-  MiLightClient(MiLightRadioFactory* radioFactory);
+  MiLightClient(MiLightRadioFactory* radioFactory, GroupStateStore& stateStore);
 
   ~MiLightClient() {
     delete[] radios;
@@ -82,6 +83,8 @@ protected:
   const size_t numRadios;
   unsigned int resendCount;
   PacketSentHandler packetSentHandler;
+  GroupStateStore& stateStore;
+  const GroupState* currentState;
 
   MiLightRadio* switchRadio(const MiLightRemoteConfig* remoteConfig);
   uint8_t parseStatus(const JsonObject& object);

+ 2 - 0
lib/Settings/Settings.cpp

@@ -77,6 +77,7 @@ void Settings::patch(JsonObject& parsedSettings) {
     this->setIfPresent(parsedSettings, "mqtt_password", mqttPassword);
     this->setIfPresent(parsedSettings, "mqtt_topic_pattern", mqttTopicPattern);
     this->setIfPresent(parsedSettings, "mqtt_update_topic_pattern", mqttUpdateTopicPattern);
+    this->setIfPresent(parsedSettings, "mqtt_state_topic_pattern", mqttStateTopicPattern);
     this->setIfPresent(parsedSettings, "discovery_port", discoveryPort);
     this->setIfPresent(parsedSettings, "listen_repeats", listenRepeats);
 
@@ -143,6 +144,7 @@ void Settings::serialize(Stream& stream, const bool prettyPrint) {
   root["mqtt_password"] = this->mqttPassword;
   root["mqtt_topic_pattern"] = this->mqttTopicPattern;
   root["mqtt_update_topic_pattern"] = this->mqttUpdateTopicPattern;
+  root["mqtt_state_topic_pattern"] = this->mqttStateTopicPattern;
   root["discovery_port"] = this->discoveryPort;
   root["listen_repeats"] = this->listenRepeats;
 

+ 1 - 0
lib/Settings/Settings.h

@@ -113,6 +113,7 @@ public:
   String mqttPassword;
   String mqttTopicPattern;
   String mqttUpdateTopicPattern;
+  String mqttStateTopicPattern;
   uint16_t discoveryPort;
   uint8_t listenRepeats;
 

+ 6 - 2
src/main.cpp

@@ -87,14 +87,18 @@ void onPacketSentHandler(uint8_t* packet, const MiLightRemoteConfig& config) {
   GroupId bulbId(deviceId, groupId, remoteConfig->type);
   GroupState* groupState = stateStore.get(bulbId);
   groupState->patch(result);
-  groupState->applyState(result);
 
   char output[200];
   result.printTo(output);
 
   if (mqttClient) {
     mqttClient->sendUpdate(config, deviceId, groupId, output);
+
+    groupState->applyState(result);
+    result.printTo(output);
+    mqttClient->sendState(config, deviceId, groupId, output);
   }
+
   httpServer->handlePacketSent(packet, config);
 }
 
@@ -143,7 +147,7 @@ void applySettings() {
     Serial.println(F("ERROR: unable to construct radio factory"));
   }
 
-  milightClient = new MiLightClient(radioFactory);
+  milightClient = new MiLightClient(radioFactory, stateStore);
   milightClient->begin();
   milightClient->onPacketSent(onPacketSentHandler);
 

+ 5 - 2
web/src/js/script.js

@@ -1,8 +1,8 @@
 var FORM_SETTINGS = [
   "admin_username", "admin_password", "ce_pin", "csn_pin", "reset_pin","packet_repeats",
   "http_repeat_factor", "auto_restart_period", "discovery_port", "mqtt_server",
-  "mqtt_topic_pattern", "mqtt_update_topic_pattern", "mqtt_username", "mqtt_password",
-  "radio_interface_type", "listen_repeats"
+  "mqtt_topic_pattern", "mqtt_update_topic_pattern", "mqtt_state_topic_pattern",
+  "mqtt_username", "mqtt_password", "radio_interface_type", "listen_repeats"
 ];
 
 var FORM_SETTINGS_HELP = {
@@ -22,6 +22,9 @@ var FORM_SETTINGS_HELP = {
   mqtt_update_topic_pattern : "Pattern to publish MQTT updates. Packets that " +
     "are received from other devices, and packets that are sent from this device will " +
     "result in updates being sent.",
+  mqtt_state_topic_pattern : "Pattern for MQTT topic to publish state to. When a group " +
+    "changes state, the full known state of the group will be published to this topic " +
+    "pattern.",
   discovery_port : "UDP port to listen for discovery packets on. Defaults to " +
     "the same port used by MiLight devices, 48899. Use 0 to disable.",
   listen_repeats : "Increasing this increases the amount of time spent listening for " +