Bladeren bron

configurable throttle parameters

Chris Mullins 8 jaren geleden
bovenliggende
commit
4b4293cca0
7 gewijzigde bestanden met toevoegingen van 66 en 12 verwijderingen
  1. 2 2
      dist/index.html.gz.h
  2. 15 5
      lib/MiLight/MiLightClient.cpp
  3. 17 1
      lib/MiLight/MiLightClient.h
  4. 6 0
      lib/Settings/Settings.cpp
  5. 7 1
      lib/Settings/Settings.h
  6. 7 1
      src/main.cpp
  7. 12 2
      web/src/js/script.js

File diff suppressed because it is too large
+ 2 - 2
dist/index.html.gz.h


+ 15 - 5
lib/MiLight/MiLightClient.cpp

@@ -4,14 +4,23 @@
 #include <RGBConverter.h>
 #include <Units.h>
 
-MiLightClient::MiLightClient(MiLightRadioFactory* radioFactory, GroupStateStore& stateStore)
+MiLightClient::MiLightClient(
+  MiLightRadioFactory* radioFactory,
+  GroupStateStore& stateStore,
+  size_t throttleThreshold,
+  size_t throttleSensitivity,
+  size_t packetRepeatMinimum
+)
   : baseResendCount(MILIGHT_DEFAULT_RESEND_COUNT),
     currentRadio(NULL),
     currentRemote(NULL),
     numRadios(MiLightRadioConfig::NUM_CONFIGS),
     packetSentHandler(NULL),
     stateStore(stateStore),
-    lastSend(0)
+    lastSend(0),
+    throttleThreshold(throttleThreshold),
+    throttleSensitivity(throttleSensitivity),
+    packetRepeatMinimum(packetRepeatMinimum)
 {
   radios = new MiLightRadio*[numRadios];
 
@@ -85,6 +94,7 @@ void MiLightClient::prepare(const MiLightRemoteType type,
 void MiLightClient::setResendCount(const unsigned int resendCount) {
   this->baseResendCount = resendCount;
   this->currentResendCount = resendCount;
+  this->throttleMultiplier = ceil((throttleSensitivity / 1000.0) * this->baseResendCount);
 }
 
 bool MiLightClient::available() {
@@ -383,10 +393,10 @@ uint8_t MiLightClient::parseStatus(const JsonObject& object) {
 void MiLightClient::updateResendCount() {
   unsigned long now = millis();
   long millisSinceLastSend = now - lastSend;
-  long x = (millisSinceLastSend - MILIGHT_CLIENT_RESEND_THROTTLE_THRESHOLD);
-  long delta = x/MILIGHT_CLIENT_RESEND_THROTTLE_WEIGHT;
+  long x = (millisSinceLastSend - throttleThreshold);
+  long delta = x * throttleMultiplier;
 
-  this->currentResendCount = constrain(this->currentResendCount + delta, 1, this->baseResendCount);
+  this->currentResendCount = constrain(this->currentResendCount + delta, packetRepeatMinimum, this->baseResendCount);
   this->lastSend = now;
 }
 

+ 17 - 1
lib/MiLight/MiLightClient.h

@@ -25,7 +25,13 @@
 
 class MiLightClient {
 public:
-  MiLightClient(MiLightRadioFactory* radioFactory, GroupStateStore& stateStore);
+  MiLightClient(
+    MiLightRadioFactory* radioFactory,
+    GroupStateStore& stateStore,
+    size_t throttleThreshold,
+    size_t throttleSensitivity,
+    size_t packetRepeatMinimum
+  );
 
   ~MiLightClient() {
     delete[] radios;
@@ -95,6 +101,16 @@ protected:
   unsigned long lastSend;
   int currentResendCount;
   unsigned int baseResendCount;
+  int packetRepeatMinimum;
+  size_t throttleThreshold;
+  size_t throttleSensitivity;
+
+  // This will be pre-computed, but is simply:
+  //
+  //    (sensitivity / 1000.0) * R
+  //
+  // Where R is the base number of repeats.
+  size_t throttleMultiplier;
 
   /*
    * Calculates the number of resend packets based on when the last packet

+ 6 - 0
lib/Settings/Settings.cpp

@@ -82,6 +82,9 @@ void Settings::patch(JsonObject& parsedSettings) {
     this->setIfPresent(parsedSettings, "listen_repeats", listenRepeats);
     this->setIfPresent(parsedSettings, "state_flush_interval", stateFlushInterval);
     this->setIfPresent(parsedSettings, "mqtt_state_rate_limit", mqttStateRateLimit);
+    this->setIfPresent(parsedSettings, "packet_repeat_throttle_threshold", packetRepeatThrottleThreshold);
+    this->setIfPresent(parsedSettings, "packet_repeat_throttle_sensitivity", packetRepeatThrottleSensitivity);
+    this->setIfPresent(parsedSettings, "packet_repeat_minimum", packetRepeatMinimum);
 
     if (parsedSettings.containsKey("radio_interface_type")) {
       this->radioInterfaceType = Settings::typeFromString(parsedSettings["radio_interface_type"]);
@@ -151,6 +154,9 @@ void Settings::serialize(Stream& stream, const bool prettyPrint) {
   root["listen_repeats"] = this->listenRepeats;
   root["state_flush_interval"] = this->stateFlushInterval;
   root["mqtt_state_rate_limit"] = this->mqttStateRateLimit;
+  root["packet_repeat_throttle_sensitivity"] = this->packetRepeatThrottleSensitivity;
+  root["packet_repeat_throttle_threshold"] = this->packetRepeatThrottleThreshold;
+  root["packet_repeat_minimum"] = this->packetRepeatMinimum;
 
   if (this->deviceIds) {
     JsonArray& arr = jsonBuffer.createArray();

+ 7 - 1
lib/Settings/Settings.h

@@ -74,7 +74,10 @@ public:
     _autoRestartPeriod(0),
     discoveryPort(48899),
     stateFlushInterval(1000),
-    mqttStateRateLimit(500)
+    mqttStateRateLimit(500),
+    packetRepeatThrottleThreshold(200),
+    packetRepeatThrottleSensitivity(1),
+    packetRepeatMinimum(3)
   { }
 
   ~Settings() {
@@ -124,6 +127,9 @@ public:
   uint8_t listenRepeats;
   size_t stateFlushInterval;
   size_t mqttStateRateLimit;
+  size_t packetRepeatThrottleSensitivity;
+  size_t packetRepeatThrottleThreshold;
+  size_t packetRepeatMinimum;
 
 protected:
   size_t _autoRestartPeriod;

+ 7 - 1
src/main.cpp

@@ -169,7 +169,13 @@ void applySettings() {
 
   stateStore = new GroupStateStore(MILIGHT_MAX_STATE_ITEMS, settings.stateFlushInterval);
 
-  milightClient = new MiLightClient(radioFactory, *stateStore);
+  milightClient = new MiLightClient(
+    radioFactory,
+    *stateStore,
+    settings.packetRepeatThrottleThreshold,
+    settings.packetRepeatThrottleSensitivity,
+    settings.packetRepeatMinimum
+  );
   milightClient->begin();
   milightClient->onPacketSent(onPacketSentHandler);
   milightClient->setResendCount(settings.packetRepeats);

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

@@ -9,7 +9,8 @@ var FORM_SETTINGS = [
   "http_repeat_factor", "auto_restart_period", "discovery_port", "mqtt_server",
   "mqtt_topic_pattern", "mqtt_update_topic_pattern", "mqtt_state_topic_pattern",
   "mqtt_username", "mqtt_password", "radio_interface_type", "listen_repeats",
-  "state_flush_interval", "mqtt_state_rate_limit"
+  "state_flush_interval", "mqtt_state_rate_limit", "packet_repeat_throttle_threshold",
+  "packet_repeat_throttle_sensitivity", "packet_repeat_minimum"
 ];
 
 var FORM_SETTINGS_HELP = {
@@ -39,7 +40,16 @@ var FORM_SETTINGS_HELP = {
   state_flush_interval : "Minimum number of milliseconds between flushing state to flash. " +
     "Set to 0 to disable delay and immediately persist state to flash.",
   mqtt_state_rate_limit : "Minimum number of milliseconds between MQTT updates of bulb state. " +
-    "Defaults to 500."
+    "Defaults to 500.",
+  packet_repeat_throttle_threshold : "Controls how packet repeats are throttled.  Packets sent " +
+    "with less time between them than this value (in milliseconds) will cause " +
+    "packet repeats to be throttled down.  More than this value will unthrottle " +
+    "up.  Defaults to 200ms",
+  packet_repeat_throttle_sensitivity : "Controls how packet repeats are throttled. " +
+    "Higher values cause packets to be throttled up and down faster.  Set to 0 " +
+    "to disable throttling.  Defaults to 1.  Maximum value 1000.",
+  packet_repeat_minimum : "Controls how far throttling can decrease the number " +
+    "of repeated packets.  Defaults to 3."
 }
 
 var UDP_PROTOCOL_VERSIONS = [ 5, 6 ];