fixed some issues with stats::variance
fixed umbrella header for stats added error-feedback to wifi optimizers improved logging for wifi optimizers adjusted calling-API for wifi-optimizers
This commit is contained in:
@@ -38,6 +38,9 @@ public:
|
||||
/** use the maximum signal-strength of all grouped APs */
|
||||
MAXIMUM,
|
||||
|
||||
/** use std-dev around the signal-strength average of all grouped APs. NOTE not directly useful but for debug! */
|
||||
STD_DEV,
|
||||
|
||||
};
|
||||
|
||||
/** how to determine the grouped timestamp */
|
||||
@@ -62,7 +65,7 @@ private:
|
||||
const Mode mode;
|
||||
|
||||
/** the signal-strength aggregation algorithm to use */
|
||||
const Aggregation agg;
|
||||
const Aggregation rssiAgg;
|
||||
|
||||
/** how to aggreage the grouped time */
|
||||
const TimeAggregation timeAgg;
|
||||
@@ -73,8 +76,8 @@ private:
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
VAPGrouper(const Mode mode, const Aggregation agg, const TimeAggregation timeAgg = TimeAggregation::AVERAGE, const int minOccurences = 2) :
|
||||
mode(mode), agg(agg), timeAgg(timeAgg), minOccurences(minOccurences) {
|
||||
VAPGrouper(const Mode mode, const Aggregation rssiAgg, const TimeAggregation timeAgg = TimeAggregation::AVERAGE, const int minOccurences = 2) :
|
||||
mode(mode), rssiAgg(rssiAgg), timeAgg(timeAgg), minOccurences(minOccurences) {
|
||||
;
|
||||
}
|
||||
|
||||
@@ -98,6 +101,12 @@ public:
|
||||
|
||||
}
|
||||
|
||||
#ifdef WITH_DEBUG_LOG
|
||||
std::stringstream vals;
|
||||
vals << std::fixed;
|
||||
vals.precision(1);
|
||||
#endif
|
||||
|
||||
// to-be-constructed output
|
||||
WiFiMeasurements result;
|
||||
int skipped = 0;
|
||||
@@ -112,19 +121,30 @@ public:
|
||||
if ((int)vaps.size() < minOccurences) {++skipped; continue;}
|
||||
|
||||
// group all VAPs into one measurement
|
||||
const WiFiMeasurement groupedMeasurement = groupVAPs(base, vaps);
|
||||
const WiFiMeasurement groupedMeasurement = groupVAPs(base, vaps, rssiAgg, timeAgg);
|
||||
|
||||
// get corresponding std-dev for debug
|
||||
#ifdef WITH_DEBUG_LOG
|
||||
const WiFiMeasurement groupedStdDev = groupVAPs(base, vaps, Aggregation::STD_DEV, timeAgg);
|
||||
vals << groupedMeasurement.getRSSI() << "±";
|
||||
vals << groupedStdDev.getRSSI() << " ";
|
||||
#endif
|
||||
|
||||
// add it to the result-vector
|
||||
result.entries.push_back(groupedMeasurement);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// debug
|
||||
Log::add(name,
|
||||
#ifdef WITH_DEBUG_LOG
|
||||
Log::add(name,
|
||||
"grouped " + std::to_string(original.entries.size()) + " measurements " +
|
||||
"into " + std::to_string(result.entries.size()) + " [omitted: " + std::to_string(skipped) + "]",
|
||||
"into " + std::to_string(result.entries.size()) + " [omitted: " + std::to_string(skipped) + "]" +
|
||||
" Stats:[" + vals.str() + "]",
|
||||
true
|
||||
);
|
||||
);
|
||||
#endif
|
||||
|
||||
// done
|
||||
return result;
|
||||
@@ -135,9 +155,9 @@ public:
|
||||
MACAddress getBaseMAC(const MACAddress& mac) const {
|
||||
|
||||
switch(mode) {
|
||||
case Mode::DISABLED: return mac;
|
||||
case Mode::LAST_MAC_DIGIT_TO_ZERO: return lastMacDigitToZero(mac);
|
||||
default: throw Exception("unsupported vap-grouping mode given");
|
||||
case Mode::DISABLED: return mac;
|
||||
case Mode::LAST_MAC_DIGIT_TO_ZERO: return lastMacDigitToZero(mac);
|
||||
default: throw Exception("unsupported vap-grouping mode given");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -154,26 +174,24 @@ private:
|
||||
|
||||
|
||||
/** combine all of the given VAPs into one entry using the configured aggregation method */
|
||||
WiFiMeasurement groupVAPs(const MACAddress& baseMAC, const std::vector<WiFiMeasurement>& vaps) const {
|
||||
static WiFiMeasurement groupVAPs(const MACAddress& baseMAC, const std::vector<WiFiMeasurement>& vaps, Aggregation aggRssi, TimeAggregation aggTime) {
|
||||
|
||||
// the resulting entry is an AP with the base-MAC all of the given VAPs have in common
|
||||
const AccessPoint baseAP(baseMAC);
|
||||
|
||||
// the resultign timestamp
|
||||
//Timestamp baseTS = vaps.front().getTimestamp();
|
||||
|
||||
// calculate the rssi using the configured aggregate function
|
||||
float rssi = NAN;
|
||||
switch(agg) {
|
||||
switch(aggRssi) {
|
||||
case Aggregation::AVERAGE: rssi = getAVG<float, FieldRSSI>(vaps); break;
|
||||
case Aggregation::MEDIAN: rssi = getMedian(vaps); break;
|
||||
case Aggregation::MAXIMUM: rssi = getMax<float, FieldRSSI>(vaps); break;
|
||||
case Aggregation::STD_DEV: rssi = getStdDev<float, FieldRSSI>(vaps); break;
|
||||
default: throw Exception("unsupported rssi-aggregation method");
|
||||
}
|
||||
|
||||
// calculate the time using the configured aggregate function
|
||||
Timestamp baseTS;
|
||||
switch(timeAgg) {
|
||||
switch(aggTime) {
|
||||
case TimeAggregation::MINIMUM: baseTS = getMin<Timestamp, FieldTS>(vaps); break;
|
||||
case TimeAggregation::AVERAGE: baseTS = getAVG<Timestamp, FieldTS>(vaps); break;
|
||||
case TimeAggregation::MAXIMUM: baseTS = getMax<Timestamp, FieldTS>(vaps); break;
|
||||
@@ -189,13 +207,8 @@ private:
|
||||
private:
|
||||
|
||||
/** get the average signal strength */
|
||||
template <typename T, typename Field> inline T getAVG(const std::vector<WiFiMeasurement>& vaps) const {
|
||||
template <typename T, typename Field> static inline T getAVG(const std::vector<WiFiMeasurement>& vaps) {
|
||||
|
||||
// T field = T();
|
||||
// for (const WiFiMeasurement& vap : vaps) {
|
||||
// field = field + Field::get(vap);
|
||||
// }
|
||||
// return field / vaps.size();
|
||||
Stats::Average<T> avg;
|
||||
for (const WiFiMeasurement& vap : vaps) {
|
||||
avg.add(Field::get(vap));
|
||||
@@ -204,8 +217,19 @@ private:
|
||||
|
||||
}
|
||||
|
||||
/** get the std-dev around the average */
|
||||
template <typename T, typename Field> static inline T getStdDev(const std::vector<WiFiMeasurement>& vaps) {
|
||||
|
||||
Stats::Variance<T> var;
|
||||
for (const WiFiMeasurement& vap : vaps) {
|
||||
var.add(Field::get(vap));
|
||||
}
|
||||
return var.getStdDev();
|
||||
|
||||
}
|
||||
|
||||
/** get the median signal strength */
|
||||
inline float getMedian(const std::vector<WiFiMeasurement>& vaps) const {
|
||||
static inline float getMedian(const std::vector<WiFiMeasurement>& vaps) {
|
||||
|
||||
Stats::Median<float> median;
|
||||
for (const WiFiMeasurement& vap : vaps) {
|
||||
@@ -216,7 +240,7 @@ private:
|
||||
}
|
||||
|
||||
/** get the maximum value */
|
||||
template <typename T, typename Field> inline T getMax(const std::vector<WiFiMeasurement>& vaps) const {
|
||||
template <typename T, typename Field> static inline T getMax(const std::vector<WiFiMeasurement>& vaps) {
|
||||
|
||||
Stats::Maximum<T> max;
|
||||
for (const WiFiMeasurement& vap : vaps) {
|
||||
@@ -227,7 +251,7 @@ private:
|
||||
}
|
||||
|
||||
/** get the minimum value */
|
||||
template <typename T, typename Field> inline T getMin(const std::vector<WiFiMeasurement>& vaps) const {
|
||||
template <typename T, typename Field> static inline T getMin(const std::vector<WiFiMeasurement>& vaps) {
|
||||
|
||||
Stats::Minimum<T> min;
|
||||
for (const WiFiMeasurement& vap : vaps) {
|
||||
|
||||
Reference in New Issue
Block a user