Selaa lähdekoodia

Disable state updates until entire command has been processed

Christopher Mullins 8 vuotta sitten
vanhempi
commit
b972791c5d

+ 11 - 2
lib/MQTT/BulbStateUpdater.cpp

@@ -4,9 +4,18 @@ BulbStateUpdater::BulbStateUpdater(Settings& settings, MqttClient& mqttClient, G
   : settings(settings),
     mqttClient(mqttClient),
     stateStore(stateStore),
-    lastFlush(0)
+    lastFlush(0),
+    enabled(true)
 { }
 
+void BulbStateUpdater::enable() {
+  this->enabled = true;
+}
+
+void BulbStateUpdater::disable() {
+  this->enabled = false;
+}
+
 void BulbStateUpdater::enqueueUpdate(BulbId bulbId, GroupState& groupState) {
   // If can flush immediately, do so (avoids lookup of group state later).
   if (canFlush()) {
@@ -46,5 +55,5 @@ inline void BulbStateUpdater::flushGroup(BulbId bulbId, GroupState& state) {
 }
 
 inline bool BulbStateUpdater::canFlush() const {
-  return (millis() > (lastFlush + settings.mqttStateRateLimit));
+  return enabled && (millis() > (lastFlush + settings.mqttStateRateLimit));
 }

+ 3 - 0
lib/MQTT/BulbStateUpdater.h

@@ -16,6 +16,8 @@ public:
 
   void enqueueUpdate(BulbId bulbId, GroupState& groupState);
   void loop();
+  void enable();
+  void disable();
 
 private:
   Settings& settings;
@@ -23,6 +25,7 @@ private:
   GroupStateStore& stateStore;
   CircularBuffer<BulbId, MILIGHT_MAX_STALE_MQTT_GROUPS> staleGroups;
   unsigned long lastFlush;
+  bool enabled;
 
   inline void flushGroup(BulbId bulbId, GroupState& state);
   inline bool canFlush() const;

+ 3 - 3
lib/MQTT/MqttClient.cpp

@@ -124,7 +124,7 @@ void MqttClient::publish(
   MqttClient::bindTopicString(topic, remoteConfig, deviceId, groupId);
 
 #ifdef MQTT_DEBUG
-  printf_P(PSTR("MqttClient - publishing update to %s: %s\n"), topic.c_str(), update);
+  printf("MqttClient - publishing update to %s\n", topic.c_str());
 #endif
 
   mqttClient->publish(topic.c_str(), message, retain);
@@ -139,7 +139,7 @@ void MqttClient::publishCallback(char* topic, byte* payload, int length) {
   memcpy(cstrPayload, payload, sizeof(byte)*length);
 
 #ifdef MQTT_DEBUG
-  printf_P(PSTR("MqttClient - Got message on topic: %s\n%s\n"), topic, cstrPayload);
+  printf("MqttClient - Got message on topic: %s\n%s\n", topic, cstrPayload);
 #endif
 
   char topicPattern[settings.mqttTopicPattern.length()];
@@ -165,7 +165,7 @@ void MqttClient::publishCallback(char* topic, byte* payload, int length) {
   JsonObject& obj = buffer.parseObject(cstrPayload);
 
 #ifdef MQTT_DEBUG
-  printf_P(PSTR("MqttClient - device %04X, group %u\n"), deviceId, groupId);
+  printf("MqttClient - device %04X, group %u\n", deviceId, groupId);
 #endif
 
   milightClient->prepare(config, deviceId, groupId);

+ 23 - 0
lib/MiLight/MiLightClient.cpp

@@ -16,6 +16,8 @@ MiLightClient::MiLightClient(
     currentRemote(NULL),
     numRadios(MiLightRadioConfig::NUM_CONFIGS),
     packetSentHandler(NULL),
+    updateBeginHandler(NULL),
+    updateEndHandler(NULL),
     stateStore(stateStore),
     lastSend(0),
     throttleThreshold(throttleThreshold),
@@ -250,6 +252,15 @@ void MiLightClient::command(uint8_t command, uint8_t arg) {
 }
 
 void MiLightClient::update(const JsonObject& request) {
+  if (this->updateBeginHandler) {
+    this->updateBeginHandler();
+  }
+
+  String bb;
+  request.printTo(bb);
+  Serial.println("processing...");
+  Serial.println(bb);
+
   const uint8_t parsedStatus = this->parseStatus(request);
 
   // Always turn on first
@@ -338,6 +349,10 @@ void MiLightClient::update(const JsonObject& request) {
   if (parsedStatus == OFF) {
     this->updateStatus(OFF);
   }
+
+  if (this->updateEndHandler) {
+    this->updateEndHandler();
+  }
 }
 
 void MiLightClient::handleCommand(const String& command) {
@@ -418,3 +433,11 @@ void MiLightClient::flushPacket() {
 void MiLightClient::onPacketSent(PacketSentHandler handler) {
   this->packetSentHandler = handler;
 }
+
+void MiLightClient::onUpdateBegin(EventHandler handler) {
+  this->updateBeginHandler = handler;
+}
+
+void MiLightClient::onUpdateEnd(EventHandler handler) {
+  this->updateEndHandler = handler;
+}

+ 7 - 1
lib/MiLight/MiLightClient.h

@@ -30,6 +30,7 @@ public:
   }
 
   typedef std::function<void(uint8_t* packet, const MiLightRemoteConfig& config)> PacketSentHandler;
+  typedef std::function<void(void)> EventHandler;
 
   void begin();
   void prepare(const MiLightRemoteConfig* remoteConfig, const uint16_t deviceId = -1, const uint8_t groupId = -1);
@@ -75,6 +76,8 @@ public:
   void handleEffect(const String& effect);
 
   void onPacketSent(PacketSentHandler handler);
+  void onUpdateBegin(EventHandler handler);
+  void onUpdateEnd(EventHandler handler);
 
   size_t getNumRadios() const;
   MiLightRadio* switchRadio(size_t radioIx);
@@ -86,9 +89,12 @@ protected:
   MiLightRadio* currentRadio;
   const MiLightRemoteConfig* currentRemote;
   const size_t numRadios;
-  PacketSentHandler packetSentHandler;
   GroupStateStore& stateStore;
 
+  PacketSentHandler packetSentHandler;
+  EventHandler updateBeginHandler;
+  EventHandler updateEndHandler;
+
   // Used to track auto repeat limiting
   unsigned long lastSend;
   int currentResendCount;

+ 2 - 2
platformio.ini

@@ -10,7 +10,7 @@
 
 [common]
 framework = arduino
-platform = https://github.com/platformio/platform-espressif8266.git#feature/stage 
+platform = https://github.com/platformio/platform-espressif8266.git#feature/stage
 board_f_cpu = 160000000L
 lib_deps_builtin =
   SPI
@@ -25,7 +25,7 @@ lib_deps_external =
   CircularBuffer
 extra_scripts =
   pre:.build_web.py
-build_flags = !python .get_version.py -DMQTT_MAX_PACKET_SIZE=200 -Idist -Ilib/DataStructures
+build_flags = !python .get_version.py -DMQTT_MAX_PACKET_SIZE=200 -Idist -Ilib/DataStructures 
 # -D DEBUG_PRINTF
 # -D MQTT_DEBUG
 # -D MILIGHT_UDP_DEBUG

+ 27 - 0
src/main.cpp

@@ -147,6 +147,28 @@ void handleListen() {
 }
 
 /**
+ * Called when MqttClient#update is first being processed.  Stop sending updates
+ * and aggregate state changes until the update is finished.
+ */
+void onUpdateBegin() {
+  if (bulbStateUpdater) {
+    Serial.println("Dsiabling state updates");
+    bulbStateUpdater->disable();
+  }
+}
+
+/**
+ * Called when MqttClient#update is finished processing.  Re-enable state
+ * updates, which will flush accumulated state changes.
+ */
+void onUpdateEnd() {
+  if (bulbStateUpdater) {
+    Serial.println("Re-enabling state updates");
+    bulbStateUpdater->enable();
+  }
+}
+
+/**
  * Apply what's in the Settings object.
  */
 void applySettings() {
@@ -159,6 +181,9 @@ void applySettings() {
   if (mqttClient) {
     delete mqttClient;
     delete bulbStateUpdater;
+
+    mqttClient = NULL;
+    bulbStateUpdater = NULL;
   }
   if (stateStore) {
     delete stateStore;
@@ -181,6 +206,8 @@ void applySettings() {
   );
   milightClient->begin();
   milightClient->onPacketSent(onPacketSentHandler);
+  milightClient->onUpdateBegin(onUpdateBegin);
+  milightClient->onUpdateEnd(onUpdateEnd);
   milightClient->setResendCount(settings.packetRepeats);
 
   if (settings.mqttServer().length() > 0) {