fix: send wifiStrength only for real signal changes

At -70 dBm the RSSI moves a dBm or two constantly, so the >1 dBm check
every 1.5s sent wifiStrength to every client about 270 times an hour.
That is extra traffic on an already lossy link and a state write in
Home Assistant for each one.

Broadcast on a channel change, or for a change of at least 3 dBm no
more than every 10s. A newly connected client still gets the current
value straight away.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-11 20:35:42 +02:00
parent 1d1f685fce
commit 05c3d309a6
5 changed files with 44 additions and 2 deletions

View file

@ -181,8 +181,9 @@ bool ESPNetwork::changeAP(const uint8_t *bssid, const int32_t channel) {
}
void ESPNetwork::emitSockets() {
this->emitHeap();
if(this->needsBroadcast ||
(this->connType == conn_types_t::wifi && (abs(abs(WiFi.RSSI()) - abs(this->lastRSSI)) > 1 || WiFi.channel() != this->lastChannel))) {
if(this->needsBroadcast ||
(this->connType == conn_types_t::wifi && rssiNeedsEmit(WiFi.RSSI(), this->lastRSSI, WiFi.channel(), this->lastChannel,
millis() - this->lastRSSIEmit, RSSI_EMIT_MIN_DBM, RSSI_EMIT_MIN_MS))) {
this->emitSockets(255);
sockEmit.loop();
this->needsBroadcast = false;
@ -212,6 +213,7 @@ void ESPNetwork::emitSockets(uint8_t num) {
sockEmit.endEmit(num);
this->lastRSSI = WiFi.RSSI();
this->lastChannel = WiFi.channel();
this->lastRSSIEmit = millis();
}
else {
JsonSockEvent *json = sockEmit.beginEmit("wifiStrength");
@ -231,6 +233,7 @@ void ESPNetwork::emitSockets(uint8_t num) {
sockEmit.endEmit(num);
this->lastRSSI = -100;
this->lastChannel = -1;
this->lastRSSIEmit = millis();
}
}
this->emitHeap(num);

View file

@ -8,10 +8,15 @@
#define CONNECT_TIMEOUT 20000
#define SSID_SCAN_INTERVAL 600000
// A weak signal moves a dBm or two all the time, so only broadcast real
// changes and not more often than this.
#define RSSI_EMIT_MIN_DBM 3
#define RSSI_EMIT_MIN_MS 10000
class ESPNetwork {
protected:
unsigned long lastEmit = 0;
unsigned long lastMDNS = 0;
unsigned long lastRSSIEmit = 0;
int lastRSSI = 0;
int lastChannel = 0;
int linkSpeed = 0;

View file

@ -130,3 +130,8 @@ int Timestamp::tzOffset() {
time(&now);
return Timestamp::calcTZOffset(&now);
}
bool rssiNeedsEmit(int rssi, int lastRssi, int channel, int lastChannel, uint32_t sinceLastMs, int minDelta, uint32_t minMs) {
if(channel != lastChannel) return true;
int delta = rssi > lastRssi ? rssi - lastRssi : lastRssi - rssi;
return delta >= minDelta && sinceLastMs >= minMs;
}

View file

@ -56,6 +56,10 @@ struct rebootDelay_t {
else if(str[0] == 'f' || str[0] == 'F' || str[0] == '0') return false;
return def;
}
// Whether a wifiStrength broadcast is worth sending: always on a channel change,
// otherwise only for an RSSI change of at least minDelta dBm and not more often
// than every minMs.
bool rssiNeedsEmit(int rssi, int lastRssi, int channel, int lastChannel, uint32_t sinceLastMs, int minDelta, uint32_t minMs);
class Timestamp {
char _timeBuffer[128];