added first draft of a wifi quality analyzer
This commit is contained in:
106
sensors/radio/WiFiQualityAnalyzer.h
Normal file
106
sensors/radio/WiFiQualityAnalyzer.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef WIFIQUALITYANALYZER_H
|
||||
#define WIFIQUALITYANALYZER_H
|
||||
|
||||
#include "WiFiMeasurements.h"
|
||||
#include <unordered_set>
|
||||
|
||||
class WiFiQualityAnalyzer {
|
||||
|
||||
private:
|
||||
|
||||
int historySize = 3;
|
||||
std::vector<WiFiMeasurements> history;
|
||||
float quality = 0;
|
||||
|
||||
public:
|
||||
|
||||
/** attach the current measurement and infer the quality */
|
||||
void add(const WiFiMeasurements& mes) {
|
||||
|
||||
// update the history
|
||||
history.push_back(mes);
|
||||
while(history.size() > historySize) {
|
||||
history.erase(history.begin());
|
||||
}
|
||||
|
||||
// recalculate
|
||||
update();
|
||||
|
||||
}
|
||||
|
||||
/** get a quality score for the WiFi */
|
||||
float getQuality() const {
|
||||
return quality;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** re-calculate the current quality */
|
||||
void update() {
|
||||
|
||||
const float qCnt = getQualityByCount();
|
||||
const float qAvgdB = getQualityByAvgDB();
|
||||
|
||||
quality = qAvgdB;
|
||||
|
||||
}
|
||||
|
||||
/** score [0:1] based on the average sig-strength. the higher the better */
|
||||
float getQualityByAvgDB() const {
|
||||
|
||||
// stats
|
||||
float sum = 0;
|
||||
float sum2 = 0;
|
||||
float cnt = 0;
|
||||
|
||||
for (const WiFiMeasurements& mes : history) {
|
||||
for (const WiFiMeasurement& m : mes.entries) {
|
||||
const float rssi = m.getRSSI();
|
||||
sum += rssi;
|
||||
sum2 += rssi*rssi;
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
|
||||
// average sig strength
|
||||
const float avg = sum/cnt;
|
||||
const float avg2 = sum2/cnt;
|
||||
const float stdDev = std::sqrt(avg2 - avg*avg);
|
||||
|
||||
// avg rssi score
|
||||
const float minRSSI = -90;
|
||||
const float maxRSSI = -65;
|
||||
float score1 = (avg-minRSSI) / (maxRSSI-minRSSI); // min = 0; max = 1
|
||||
if (score1 > 1) {score1 = 1;}
|
||||
if (score1 < 0) {score1 = 0;}
|
||||
//const float score1 = 1.0 - std::exp(-0.07 * (avg-minRSSI));
|
||||
|
||||
// std dev score
|
||||
const float score2 = 1.0 - std::exp(-1.0 * stdDev);
|
||||
|
||||
return score1 * score2;
|
||||
|
||||
}
|
||||
|
||||
/** quality score [0:1] according to the number of seen APs */
|
||||
float getQualityByCount() const {
|
||||
|
||||
// distinct macs
|
||||
std::unordered_set<MACAddress> macs;
|
||||
for (const WiFiMeasurements& mes : history) {
|
||||
for (const WiFiMeasurement& m : mes.entries) {
|
||||
macs.insert(m.getAP().getMAC());
|
||||
}
|
||||
}
|
||||
|
||||
// number of distinct macs
|
||||
const int cnt = macs.size();
|
||||
|
||||
// see function plot. function between [0.0:1.0] has 0.5 around 7 seen APs
|
||||
return 1.0 - std::exp(-0.1 * cnt);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // WIFIQUALITYANALYZER_H
|
||||
Reference in New Issue
Block a user