Commit 72ebad22 authored by Michael Ott's avatar Michael Ott
Browse files

Fix integral and derivative computations, account for timestamp conversion

parent 42d95d47
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <cstdint> #include <cstdint>
#include <cinttypes> #include <cinttypes>
#include <cstdlib> #include <cstdlib>
#include "unitconv.h"
#ifndef sensoroperations_h #ifndef sensoroperations_h
#define sensoroperations_h #define sensoroperations_h
...@@ -30,8 +31,8 @@ namespace DCDB { ...@@ -30,8 +31,8 @@ namespace DCDB {
DCDB_OP_RESULT scale(int64_t* result, double scalingFactor, double baseScalingFactor); DCDB_OP_RESULT scale(int64_t* result, double scalingFactor, double baseScalingFactor);
DCDB_OP_RESULT delta(int64_t lh, int64_t rh, int64_t* result); DCDB_OP_RESULT delta(int64_t lh, int64_t rh, int64_t* result);
DCDB_OP_RESULT delta(uint64_t lh, uint64_t rh, int64_t* result); DCDB_OP_RESULT delta(uint64_t lh, uint64_t rh, int64_t* result);
DCDB_OP_RESULT derivative(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht, int64_t* result); DCDB_OP_RESULT derivative(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht, int64_t* result, DCDB::Unit unit = DCDB::Unit_None);
DCDB_OP_RESULT integral(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht, int64_t* result); DCDB_OP_RESULT integral(int64_t x, uint64_t lht, uint64_t rht, int64_t* result, DCDB::Unit unit = DCDB::Unit_None);
} /* End of namespace DCDB */ } /* End of namespace DCDB */
......
...@@ -111,7 +111,7 @@ DCDB_OP_RESULT delta(uint64_t lh, uint64_t rh, int64_t* result) { ...@@ -111,7 +111,7 @@ DCDB_OP_RESULT delta(uint64_t lh, uint64_t rh, int64_t* result) {
}; };
/* Safe implementation of a derivative */ /* Safe implementation of a derivative */
DCDB_OP_RESULT derivative(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht, int64_t* result) { DCDB_OP_RESULT derivative(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht, int64_t* result, DCDB::Unit unit) {
int64_t dx = 0; int64_t dx = 0;
uint64_t dt = 0; uint64_t dt = 0;
...@@ -127,28 +127,61 @@ DCDB_OP_RESULT derivative(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht, ...@@ -127,28 +127,61 @@ DCDB_OP_RESULT derivative(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht,
if(dt == 0) if(dt == 0)
return DCDB_OP_DIVISION_BY_ZERO; //Presumably it's always != 0... return DCDB_OP_DIVISION_BY_ZERO; //Presumably it's always != 0...
*result = dx / dt; uint64_t tsDivisor = 1;
switch (unit) {
case DCDB::Unit_Joules:
case DCDB::Unit_KiloJoules:
case DCDB::Unit_MegaJoules:
tsDivisor = 1000000000ll;
break;
case DCDB::Unit_WattHours:
case DCDB::Unit_KiloWattHours:
case DCDB::Unit_MegaWattHours:
tsDivisor = 1000000000ll * 3600;
break;
default:
break;
}
if (tsDivisor == 1) {
*result = dx / dt;
} else {
*result = dx / ((double) dt / tsDivisor);
}
return DCDB_OP_SUCCESS; return DCDB_OP_SUCCESS;
}; };
/* Safe implementation of an integral */ /* Safe implementation of an integral */
DCDB_OP_RESULT integral(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht, int64_t* result) { DCDB_OP_RESULT integral(int64_t x, uint64_t lht, uint64_t rht, int64_t* result, DCDB::Unit unit) {
int64_t dt = (int64_t) lht - rht;
int64_t dx = 0;
int64_t dt = 0; uint64_t tsDivisor = 1;
switch (unit) {
DCDB_OP_RESULT deltaResult = delta(lhx, rhx, &dx); case DCDB::Unit_Watt:
if(deltaResult != DCDB_OP_SUCCESS) { case DCDB::Unit_KiloWatt:
*result = dx; case DCDB::Unit_MegaWatt:
return deltaResult; tsDivisor = 1000000000ll;
break;
default:
break;
}
if (tsDivisor == 1) {
return safeMult(x, dt, result);
} else {
if (dt > 1000000000ll) {
dt/= 1000000;
tsDivisor/= 1000000;
} else if (dt > 1000000ll) {
dt/= 1000;
tsDivisor/= 1000;
}
DCDB_OP_RESULT rc = safeMult(x, dt, result);
*result = *result / tsDivisor;
return rc;
} }
dt = (int64_t) lht - rht;
return safeMult(dx, dt, result);
}; };
} /* end DCDB namespace */ } /* end DCDB namespace */
...@@ -95,23 +95,39 @@ void DCDBQuery::genOutput(std::list<DCDB::SensorDataStoreReading> &results, quer ...@@ -95,23 +95,39 @@ void DCDBQuery::genOutput(std::list<DCDB::SensorDataStoreReading> &results, quer
case DCDB_OP_INTEGRAL: case DCDB_OP_INTEGRAL:
std::cout << ",Integral"; std::cout << ",Integral";
break; break;
default: default:
break; break;
} }
std::string unitStr;
if(it->second.unit != DCDB::Unit_None) { if(it->second.unit != DCDB::Unit_None) {
std::cout << " (" << DCDB::UnitConv::toString(it->second.unit) << ")"; unitStr = DCDB::UnitConv::toString(it->second.unit);
} else if (baseUnit != DCDB::Unit_None) { } else if (baseUnit != DCDB::Unit_None) {
std::cout << " (" << DCDB::UnitConv::toString(baseUnit) << ")"; unitStr = DCDB::UnitConv::toString(baseUnit);
}
if (it->second.operation == DCDB_OP_DERIVATIVE) {
if ((unitStr.back() == 's') || (unitStr.back() == 'h')) {
unitStr.pop_back();
} else if (unitStr.back() == 'J') {
unitStr.pop_back();
unitStr.append("W");
}
} else if (it->second.operation == DCDB_OP_INTEGRAL) {
if (unitStr.back() == 'W') {
unitStr.append("s");
}
}
if (unitStr.size() > 0) {
std::cout << " (" << unitStr << ")";
} }
} }
std::cout << std::endl; std::cout << std::endl;
int64_t prevValue=0; int64_t prevReading=0;
DCDB::TimeStamp prevT((uint64_t) 0); DCDB::TimeStamp prevT((uint64_t) 0);
for (std::list<DCDB::SensorDataStoreReading>::iterator reading = results.begin(); reading != results.end(); reading++) { for (std::list<DCDB::SensorDataStoreReading>::iterator reading = results.begin(); reading != results.end(); reading++) {
int64_t value = (*reading).value;
DCDB::TimeStamp ts = (*reading).timeStamp; DCDB::TimeStamp ts = (*reading).timeStamp;
/* Print the sensor's public name */ /* Print the sensor's public name */
std::cout << start->first.name << ","; std::cout << start->first.name << ",";
...@@ -123,54 +139,65 @@ void DCDBQuery::genOutput(std::list<DCDB::SensorDataStoreReading> &results, quer ...@@ -123,54 +139,65 @@ void DCDBQuery::genOutput(std::list<DCDB::SensorDataStoreReading> &results, quer
std::cout << ts.getRaw(); std::cout << ts.getRaw();
else else
std::cout << ts.getString(); std::cout << ts.getString();
/* Print the sensor value */ /* Print the sensor value */
for (queryMap_t::iterator it=start; it!=stop; it++) { for (queryMap_t::iterator it=start; it!=stop; it++) {
if (scaleAndConvert(value, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit)) { DCDB::Unit unit;
switch(it->second.operation) { if (it->second.unit != DCDB::Unit_None) {
case DCDB_OP_NONE: unit = it->second.unit;
std::cout << "," << value; } else {
break; unit = baseUnit;
case DCDB_OP_DELTA: { }
int64_t result; int64_t value = (*reading).value;
if ((prevT > (uint64_t) 0) && (DCDB::delta(value, prevValue, &result) == DCDB::DCDB_OP_SUCCESS)) { int64_t result;
std::cout << "," << result; bool resultOk = false;
} else { switch(it->second.operation) {
std::cout << ","; case DCDB_OP_NONE:
if (scaleAndConvert(value, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit)) {
result = value;
resultOk = true;
}
break;
case DCDB_OP_DELTA:
if (scaleAndConvert(value, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit)) {
if ((prevT > (uint64_t) 0) && (DCDB::delta(value, prevReading, &result) == DCDB::DCDB_OP_SUCCESS)) {
resultOk = true;
} }
break;} }
case DCDB_OP_DELTAT: { break;
int64_t result; case DCDB_OP_DELTAT:
if (scaleAndConvert(value, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit)) {
if ((prevT > (uint64_t) 0) && (DCDB::delta(ts.getRaw(), prevT.getRaw(), &result) == DCDB::DCDB_OP_SUCCESS)) { if ((prevT > (uint64_t) 0) && (DCDB::delta(ts.getRaw(), prevT.getRaw(), &result) == DCDB::DCDB_OP_SUCCESS)) {
std::cout << "," << result; resultOk = true;
} else {
std::cout << ",";
} }
break;} }
case DCDB_OP_DERIVATIVE: { break;
int64_t result; case DCDB_OP_DERIVATIVE: {
if( (prevT > (uint64_t) 0) && DCDB::derivative(value, prevValue, ts.getRaw(), prevT.getRaw(), &result) == DCDB::DCDB_OP_SUCCESS) { int64_t prevValue = prevReading;
std::cout << "," << result; if (scaleAndConvert(value, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit) && scaleAndConvert(prevValue, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit)) {
} else { if( (prevT > (uint64_t) 0) && DCDB::derivative(value, prevValue, ts.getRaw(), prevT.getRaw(), &result, unit) == DCDB::DCDB_OP_SUCCESS) {
std::cout << ","; resultOk = true;
} }
break;} }
case DCDB_OP_INTEGRAL: { break;}
int64_t result; case DCDB_OP_INTEGRAL: {
if( (prevT > (uint64_t) 0) && DCDB::integral(value, prevValue, ts.getRaw(), prevT.getRaw(), &result) == DCDB::DCDB_OP_SUCCESS) { int64_t prevValue = prevReading;
std::cout << "," << result; if (scaleAndConvert(prevValue, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit)) {
} else { if( (prevT > (uint64_t) 0) && DCDB::integral(prevValue, ts.getRaw(), prevT.getRaw(), &result, unit) == DCDB::DCDB_OP_SUCCESS) {
std::cout << ","; resultOk = true;
} }
break;} }
default: break;}
break; default:
} break;
}
if (resultOk) {
std::cout << "," << result;
} else { } else {
std::cout << ","; std::cout << ",";
} }
} }
prevValue = value; prevReading = (*reading).value;
prevT = ts; prevT = ts;
std::cout << std::endl; std::cout << std::endl;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment