|
@ -24,7 +24,7 @@ typedef struct { |
|
|
unsigned char type; // Type of measurement
|
|
|
unsigned char type; // Type of measurement
|
|
|
unsigned char decimals; // Number of decimals in textual representation
|
|
|
unsigned char decimals; // Number of decimals in textual representation
|
|
|
unsigned char global; // Global index in its type
|
|
|
unsigned char global; // Global index in its type
|
|
|
double current; // Current (last) value, unfiltered
|
|
|
|
|
|
|
|
|
double last; // Last raw value from sensor (unfiltered)
|
|
|
double reported; // Last reported value
|
|
|
double reported; // Last reported value
|
|
|
double min_change; // Minimum value change to report
|
|
|
double min_change; // Minimum value change to report
|
|
|
double max_change; // Maximum value change to report
|
|
|
double max_change; // Maximum value change to report
|
|
@ -62,6 +62,7 @@ unsigned char _magnitudeDecimals(unsigned char type) { |
|
|
if (type == MAGNITUDE_ANALOG) return ANALOG_DECIMALS; |
|
|
if (type == MAGNITUDE_ANALOG) return ANALOG_DECIMALS; |
|
|
if (type == MAGNITUDE_ENERGY || |
|
|
if (type == MAGNITUDE_ENERGY || |
|
|
type == MAGNITUDE_ENERGY_DELTA) { |
|
|
type == MAGNITUDE_ENERGY_DELTA) { |
|
|
|
|
|
_sensor_energy_units = getSetting("eneUnits", SENSOR_ENERGY_UNITS).toInt(); |
|
|
if (_sensor_energy_units == ENERGY_KWH) return 3; |
|
|
if (_sensor_energy_units == ENERGY_KWH) return 3; |
|
|
} |
|
|
} |
|
|
if (type == MAGNITUDE_POWER_ACTIVE || |
|
|
if (type == MAGNITUDE_POWER_ACTIVE || |
|
@ -162,8 +163,8 @@ void _sensorWebSocketSendData(JsonObject& root) { |
|
|
if (magnitude.type == MAGNITUDE_EVENT) continue; |
|
|
if (magnitude.type == MAGNITUDE_EVENT) continue; |
|
|
++size; |
|
|
++size; |
|
|
|
|
|
|
|
|
unsigned char decimals = magnitude.decimals; |
|
|
|
|
|
dtostrf(magnitude.current, 1-sizeof(buffer), decimals, buffer); |
|
|
|
|
|
|
|
|
double value_show = _magnitudeProcess(magnitude.type, magnitude.decimals, magnitude.last); |
|
|
|
|
|
dtostrf(value_show, 1-sizeof(buffer), magnitude.decimals, buffer); |
|
|
|
|
|
|
|
|
index.add<uint8_t>(magnitude.global); |
|
|
index.add<uint8_t>(magnitude.global); |
|
|
type.add<uint8_t>(magnitude.type); |
|
|
type.add<uint8_t>(magnitude.type); |
|
@ -296,9 +297,8 @@ void _sensorAPISetup() { |
|
|
|
|
|
|
|
|
apiRegister(topic.c_str(), [magnitude_id](char * buffer, size_t len) { |
|
|
apiRegister(topic.c_str(), [magnitude_id](char * buffer, size_t len) { |
|
|
sensor_magnitude_t magnitude = _magnitudes[magnitude_id]; |
|
|
sensor_magnitude_t magnitude = _magnitudes[magnitude_id]; |
|
|
unsigned char decimals = magnitude.decimals; |
|
|
|
|
|
double value = _sensor_realtime ? magnitude.current : magnitude.reported; |
|
|
|
|
|
dtostrf(value, 1-len, decimals, buffer); |
|
|
|
|
|
|
|
|
double value = _sensor_realtime ? magnitude.last : magnitude.reported; |
|
|
|
|
|
dtostrf(value, 1-len, magnitude.decimals, buffer); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
@ -859,16 +859,16 @@ void _sensorInit() { |
|
|
for (unsigned char k=0; k<_sensors[i]->count(); k++) { |
|
|
for (unsigned char k=0; k<_sensors[i]->count(); k++) { |
|
|
|
|
|
|
|
|
unsigned char type = _sensors[i]->type(k); |
|
|
unsigned char type = _sensors[i]->type(k); |
|
|
signed char decimals = _sensors[i]->decimals(type); |
|
|
|
|
|
if (decimals < 0) decimals = _magnitudeDecimals(type); |
|
|
|
|
|
|
|
|
signed char decimals = _sensors[i]->decimals(type); |
|
|
|
|
|
if (decimals < 0) decimals = _magnitudeDecimals(type); |
|
|
|
|
|
|
|
|
sensor_magnitude_t new_magnitude; |
|
|
sensor_magnitude_t new_magnitude; |
|
|
new_magnitude.sensor = _sensors[i]; |
|
|
new_magnitude.sensor = _sensors[i]; |
|
|
new_magnitude.local = k; |
|
|
new_magnitude.local = k; |
|
|
new_magnitude.type = type; |
|
|
new_magnitude.type = type; |
|
|
new_magnitude.decimals = (unsigned char) decimals; |
|
|
|
|
|
|
|
|
new_magnitude.decimals = (unsigned char) decimals; |
|
|
new_magnitude.global = _counts[type]; |
|
|
new_magnitude.global = _counts[type]; |
|
|
new_magnitude.current = 0; |
|
|
|
|
|
|
|
|
new_magnitude.last = 0; |
|
|
new_magnitude.reported = 0; |
|
|
new_magnitude.reported = 0; |
|
|
new_magnitude.min_change = 0; |
|
|
new_magnitude.min_change = 0; |
|
|
new_magnitude.max_change = 0; |
|
|
new_magnitude.max_change = 0; |
|
@ -1303,7 +1303,7 @@ unsigned char magnitudeType(unsigned char index) { |
|
|
|
|
|
|
|
|
double magnitudeValue(unsigned char index) { |
|
|
double magnitudeValue(unsigned char index) { |
|
|
if (index < _magnitudes.size()) { |
|
|
if (index < _magnitudes.size()) { |
|
|
return _sensor_realtime ? _magnitudes[index].current : _magnitudes[index].reported; |
|
|
|
|
|
|
|
|
return _sensor_realtime ? _magnitudes[index].last : _magnitudes[index].reported; |
|
|
} |
|
|
} |
|
|
return DBL_MIN; |
|
|
return DBL_MIN; |
|
|
} |
|
|
} |
|
@ -1418,8 +1418,9 @@ void sensorLoop() { |
|
|
last_update = millis(); |
|
|
last_update = millis(); |
|
|
report_count = (report_count + 1) % _sensor_report_every; |
|
|
report_count = (report_count + 1) % _sensor_report_every; |
|
|
|
|
|
|
|
|
double current; |
|
|
|
|
|
double filtered; |
|
|
|
|
|
|
|
|
double value_raw; // holds the raw value as the sensor returns it
|
|
|
|
|
|
double value_show; // holds the processed value applying units and decimals
|
|
|
|
|
|
double value_filtered; // holds the processed value applying filters, and the units and decimals
|
|
|
|
|
|
|
|
|
// Pre-read hook
|
|
|
// Pre-read hook
|
|
|
_sensorPre(); |
|
|
_sensorPre(); |
|
@ -1440,7 +1441,7 @@ void sensorLoop() { |
|
|
// Instant value
|
|
|
// Instant value
|
|
|
// -------------------------------------------------------------
|
|
|
// -------------------------------------------------------------
|
|
|
|
|
|
|
|
|
current = magnitude.sensor->value(magnitude.local); |
|
|
|
|
|
|
|
|
value_raw = magnitude.sensor->value(magnitude.local); |
|
|
|
|
|
|
|
|
// Completely remove spurious values if relay is OFF
|
|
|
// Completely remove spurious values if relay is OFF
|
|
|
#if SENSOR_POWER_CHECK_STATUS
|
|
|
#if SENSOR_POWER_CHECK_STATUS
|
|
@ -1451,26 +1452,31 @@ void sensorLoop() { |
|
|
magnitude.type == MAGNITUDE_CURRENT || |
|
|
magnitude.type == MAGNITUDE_CURRENT || |
|
|
magnitude.type == MAGNITUDE_ENERGY_DELTA |
|
|
magnitude.type == MAGNITUDE_ENERGY_DELTA |
|
|
) { |
|
|
) { |
|
|
current = 0; |
|
|
|
|
|
|
|
|
value_raw = 0; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
_magnitudes[i].last = value_raw; |
|
|
|
|
|
|
|
|
// -------------------------------------------------------------
|
|
|
// -------------------------------------------------------------
|
|
|
// Processing (filters)
|
|
|
// Processing (filters)
|
|
|
// -------------------------------------------------------------
|
|
|
// -------------------------------------------------------------
|
|
|
|
|
|
|
|
|
magnitude.filter->add(current); |
|
|
|
|
|
|
|
|
magnitude.filter->add(value_raw); |
|
|
|
|
|
|
|
|
// Special case for MovingAvergaeFilter
|
|
|
|
|
|
|
|
|
// Special case for MovingAverageFilter
|
|
|
if (MAGNITUDE_COUNT == magnitude.type || |
|
|
if (MAGNITUDE_COUNT == magnitude.type || |
|
|
MAGNITUDE_GEIGER_CPM ==magnitude. type || |
|
|
MAGNITUDE_GEIGER_CPM ==magnitude. type || |
|
|
MAGNITUDE_GEIGER_SIEVERT == magnitude.type) { |
|
|
MAGNITUDE_GEIGER_SIEVERT == magnitude.type) { |
|
|
current = magnitude.filter->result(); |
|
|
|
|
|
|
|
|
value_raw = magnitude.filter->result(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
current = _magnitudeProcess(magnitude.type, magnitude.decimals, current); |
|
|
|
|
|
_magnitudes[i].current = current; |
|
|
|
|
|
|
|
|
// -------------------------------------------------------------
|
|
|
|
|
|
// Procesing (units and decimals)
|
|
|
|
|
|
// -------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
value_show = _magnitudeProcess(magnitude.type, magnitude.decimals, value_raw); |
|
|
|
|
|
|
|
|
// -------------------------------------------------------------
|
|
|
// -------------------------------------------------------------
|
|
|
// Debug
|
|
|
// Debug
|
|
@ -1479,7 +1485,7 @@ void sensorLoop() { |
|
|
#if SENSOR_DEBUG
|
|
|
#if SENSOR_DEBUG
|
|
|
{ |
|
|
{ |
|
|
char buffer[64]; |
|
|
char buffer[64]; |
|
|
dtostrf(current, 1-sizeof(buffer), magnitude.decimals, buffer); |
|
|
|
|
|
|
|
|
dtostrf(value_show, 1-sizeof(buffer), magnitude.decimals, buffer); |
|
|
DEBUG_MSG_P(PSTR("[SENSOR] %s - %s: %s%s\n"), |
|
|
DEBUG_MSG_P(PSTR("[SENSOR] %s - %s: %s%s\n"), |
|
|
magnitude.sensor->slot(magnitude.local).c_str(), |
|
|
magnitude.sensor->slot(magnitude.local).c_str(), |
|
|
magnitudeTopic(magnitude.type).c_str(), |
|
|
magnitudeTopic(magnitude.type).c_str(), |
|
@ -1497,21 +1503,20 @@ void sensorLoop() { |
|
|
bool report = (0 == report_count); |
|
|
bool report = (0 == report_count); |
|
|
if ((MAGNITUDE_ENERGY == magnitude.type) && (magnitude.max_change > 0)) { |
|
|
if ((MAGNITUDE_ENERGY == magnitude.type) && (magnitude.max_change > 0)) { |
|
|
// for MAGNITUDE_ENERGY, filtered value is last value
|
|
|
// for MAGNITUDE_ENERGY, filtered value is last value
|
|
|
double value = _magnitudeProcess(magnitude.type, magnitude.decimals, current); |
|
|
|
|
|
report = (fabs(value - magnitude.reported) >= magnitude.max_change); |
|
|
|
|
|
|
|
|
report = (fabs(value_show - magnitude.reported) >= magnitude.max_change); |
|
|
} // if ((MAGNITUDE_ENERGY == magnitude.type) && (magnitude.max_change > 0))
|
|
|
} // if ((MAGNITUDE_ENERGY == magnitude.type) && (magnitude.max_change > 0))
|
|
|
|
|
|
|
|
|
if (report) { |
|
|
if (report) { |
|
|
|
|
|
|
|
|
filtered = magnitude.filter->result(); |
|
|
|
|
|
filtered = _magnitudeProcess(magnitude.type, magnitude.decimals, filtered); |
|
|
|
|
|
|
|
|
value_filtered = magnitude.filter->result(); |
|
|
|
|
|
value_filtered = _magnitudeProcess(magnitude.type, magnitude.decimals, value_filtered); |
|
|
magnitude.filter->reset(); |
|
|
magnitude.filter->reset(); |
|
|
|
|
|
|
|
|
// Check if there is a minimum change threshold to report
|
|
|
// Check if there is a minimum change threshold to report
|
|
|
if (fabs(filtered - magnitude.reported) >= magnitude.min_change) { |
|
|
|
|
|
_magnitudes[i].reported = filtered; |
|
|
|
|
|
_sensorReport(i, filtered); |
|
|
|
|
|
} // if (fabs(filtered - magnitude.reported) >= magnitude.min_change)
|
|
|
|
|
|
|
|
|
if (fabs(value_filtered - magnitude.reported) >= magnitude.min_change) { |
|
|
|
|
|
_magnitudes[i].reported = value_filtered; |
|
|
|
|
|
_sensorReport(i, value_filtered); |
|
|
|
|
|
} // if (fabs(value_filtered - magnitude.reported) >= magnitude.min_change)
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------
|
|
|
// -------------------------------------------------------------
|
|
|
// Saving to EEPROM
|
|
|
// Saving to EEPROM
|
|
@ -1524,7 +1529,7 @@ void sensorLoop() { |
|
|
|
|
|
|
|
|
if (0 == save_count) { |
|
|
if (0 == save_count) { |
|
|
if (MAGNITUDE_ENERGY == magnitude.type) { |
|
|
if (MAGNITUDE_ENERGY == magnitude.type) { |
|
|
setSetting("eneTotal", current); |
|
|
|
|
|
|
|
|
setSetting("eneTotal", value_raw); |
|
|
saveSettings(); |
|
|
saveSettings(); |
|
|
} |
|
|
} |
|
|
} // if (0 == save_count)
|
|
|
} // if (0 == save_count)
|
|
|