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 @@
#include <cstdint>
#include <cinttypes>
#include <cstdlib>
#include "unitconv.h"
#ifndef sensoroperations_h
#define sensoroperations_h
......@@ -30,8 +31,8 @@ namespace DCDB {
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(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 integral(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 x, uint64_t lht, uint64_t rht, int64_t* result, DCDB::Unit unit = DCDB::Unit_None);
} /* End of namespace DCDB */
......
......@@ -111,7 +111,7 @@ DCDB_OP_RESULT delta(uint64_t lh, uint64_t rh, int64_t* result) {
};
/* 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;
uint64_t dt = 0;
......@@ -127,28 +127,61 @@ DCDB_OP_RESULT derivative(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht,
if(dt == 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;
};
/* Safe implementation of an integral */
DCDB_OP_RESULT integral(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht, int64_t* result) {
int64_t dx = 0;
int64_t dt = 0;
DCDB_OP_RESULT deltaResult = delta(lhx, rhx, &dx);
if(deltaResult != DCDB_OP_SUCCESS) {
*result = dx;
return deltaResult;
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;
uint64_t tsDivisor = 1;
switch (unit) {
case DCDB::Unit_Watt:
case DCDB::Unit_KiloWatt:
case DCDB::Unit_MegaWatt:
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 */
......@@ -95,23 +95,39 @@ void DCDBQuery::genOutput(std::list<DCDB::SensorDataStoreReading> &results, quer
case DCDB_OP_INTEGRAL:
std::cout << ",Integral";
break;
default:
default:
break;
}
std::string unitStr;
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) {
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;
int64_t prevValue=0;
int64_t prevReading=0;
DCDB::TimeStamp prevT((uint64_t) 0);
for (std::list<DCDB::SensorDataStoreReading>::iterator reading = results.begin(); reading != results.end(); reading++) {
int64_t value = (*reading).value;
DCDB::TimeStamp ts = (*reading).timeStamp;
/* Print the sensor's public name */
std::cout << start->first.name << ",";
......@@ -123,54 +139,65 @@ void DCDBQuery::genOutput(std::list<DCDB::SensorDataStoreReading> &results, quer
std::cout << ts.getRaw();
else
std::cout << ts.getString();
/* Print the sensor value */
for (queryMap_t::iterator it=start; it!=stop; it++) {
if (scaleAndConvert(value, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit)) {
switch(it->second.operation) {
case DCDB_OP_NONE:
std::cout << "," << value;
break;
case DCDB_OP_DELTA: {
int64_t result;
if ((prevT > (uint64_t) 0) && (DCDB::delta(value, prevValue, &result) == DCDB::DCDB_OP_SUCCESS)) {
std::cout << "," << result;
} else {
std::cout << ",";
DCDB::Unit unit;
if (it->second.unit != DCDB::Unit_None) {
unit = it->second.unit;
} else {
unit = baseUnit;
}
int64_t value = (*reading).value;
int64_t result;
bool resultOk = false;
switch(it->second.operation) {
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: {
int64_t result;
}
break;
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)) {
std::cout << "," << result;
} else {
std::cout << ",";
resultOk = true;
}
break;}
case DCDB_OP_DERIVATIVE: {
int64_t result;
if( (prevT > (uint64_t) 0) && DCDB::derivative(value, prevValue, ts.getRaw(), prevT.getRaw(), &result) == DCDB::DCDB_OP_SUCCESS) {
std::cout << "," << result;
} else {
std::cout << ",";
}
break;
case DCDB_OP_DERIVATIVE: {
int64_t prevValue = prevReading;
if (scaleAndConvert(value, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit) && scaleAndConvert(prevValue, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit)) {
if( (prevT > (uint64_t) 0) && DCDB::derivative(value, prevValue, ts.getRaw(), prevT.getRaw(), &result, unit) == DCDB::DCDB_OP_SUCCESS) {
resultOk = true;
}
break;}
case DCDB_OP_INTEGRAL: {
int64_t result;
if( (prevT > (uint64_t) 0) && DCDB::integral(value, prevValue, ts.getRaw(), prevT.getRaw(), &result) == DCDB::DCDB_OP_SUCCESS) {
std::cout << "," << result;
} else {
std::cout << ",";
}
break;}
case DCDB_OP_INTEGRAL: {
int64_t prevValue = prevReading;
if (scaleAndConvert(prevValue, baseScalingFactor, it->second.scalingFactor, baseUnit, it->second.unit)) {
if( (prevT > (uint64_t) 0) && DCDB::integral(prevValue, ts.getRaw(), prevT.getRaw(), &result, unit) == DCDB::DCDB_OP_SUCCESS) {
resultOk = true;
}
break;}
default:
break;
}
}
break;}
default:
break;
}
if (resultOk) {
std::cout << "," << result;
} else {
std::cout << ",";
}
}
prevValue = value;
prevReading = (*reading).value;
prevT = ts;
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