Commit 822938d4 authored by Axel Auweter's avatar Axel Auweter
Browse files

Fixes ticket #44:

Adds -f option to dcdbquery and dcdbunitconv.
parent 01fe6d70
......@@ -66,6 +66,7 @@ public:
static DCDBUnit fromString(std::string unit);
static std::string toString(DCDBUnit unit);
static bool convert(int64_t& value, DCDBUnit from, DCDBUnit to);
static bool convert(double& value, DCDBUnit from, DCDBUnit to);
};
#endif
......@@ -227,3 +227,66 @@ bool UnitConv::convert(int64_t& value, DCDBUnit in, DCDBUnit out) {
return false;
}
bool UnitConv::convert(double& value, DCDBUnit in, DCDBUnit out) {
/* Do a depth-first search to find a suitable conversion path */
std::list<int> convChain;
if (dfs(convChain, in, out)) {
/* Convert */
double factor = 1;
double offset = 0;
for (std::list<int>::iterator it = convChain.begin(); it != convChain.end(); it++) {
double newFact = (*it) < 0 ? -conversionTable[-(*it)].baseConvFactor : conversionTable[*it].baseConvFactor;
double newOff = (*it) < 0 ? -conversionTable[-(*it)].baseConvOffset : conversionTable[*it].baseConvOffset;
double absFactor = factor > 0 ? factor : -factor;
double absNewFact = newFact > 0 ? newFact : -newFact;
/* Do offset calculation */
if (newFact > 0) {
offset = (offset * newFact) + newOff;
}
else {
offset = (offset + newOff) / (-newFact);
}
/* Do factor calculation */
if (factor > 0 && newFact > 0) {
factor = factor * newFact;
}
else if (factor < 0 && newFact < 0) {
factor = -(factor * newFact);
}
else if (absFactor == absNewFact) {
factor = 1;
}
else if (absFactor > absNewFact && factor > 0) {
factor = (absFactor / absNewFact);
}
else if (absFactor < absNewFact && newFact > 0) {
factor = (absNewFact / absFactor);
}
else if (absFactor > absNewFact && factor < 0) {
factor = -(absFactor / absNewFact);
}
else if (absFactor < absNewFact && newFact < 0) {
factor = -(absNewFact / absFactor);
}
else {
return false;
}
}
/* Calculate final result */
if (factor > 0) {
value = (value * factor) + (int64_t)offset;
}
else {
value = (value / (-factor)) + (int64_t)offset;
}
return true;
}
return false;
}
......@@ -51,7 +51,7 @@ int main(int argc, char* argv[])
/* Get the options */
int ret;
const char *host = "localhost";
while ((ret=getopt(argc, argv, "+h:rl"))!=-1) {
while ((ret=getopt(argc, argv, "+h:rlf"))!=-1) {
switch(ret) {
case 'h':
host = optarg;
......@@ -62,6 +62,9 @@ int main(int argc, char* argv[])
case 'l':
myQuery->setLocalTimeEnabled(true);
break;
case 'f':
myQuery->setFloatOutputEnabled(true);
break;
default:
usage();
exit(EXIT_FAILURE);
......
......@@ -35,6 +35,14 @@ bool DCDBQuery::getRawOutputEnabled() {
return useRawOutput;
}
void DCDBQuery::setFloatOutputEnabled(bool enable) {
useFloatOutput = enable;
}
bool DCDBQuery::getFloatOutputEnabled() {
return useFloatOutput;
}
void DCDBQuery::doQuery(const char* hostname, std::list<std::string> sensors, DCDBTimeStamp start, DCDBTimeStamp end)
{
/* Create a new connection to the database */
......@@ -119,21 +127,47 @@ void DCDBQuery::doQuery(const char* hostname, std::list<std::string> sensors, DC
/* Iterate over the readings */
for (std::list<SensorDataStoreReading>::iterator rit = readings.begin(); rit != readings.end(); rit++) {
double fvalue;
int64_t ivalue;
SensorDataStoreReading reading = *rit;
/* Assign the reading to local variable */
if (useFloatOutput) {
fvalue = reading.value;
}
else {
ivalue = reading.value;
}
/* Convert the unit if requested */
if (unitConvert) {
if (!UnitConv::convert(reading.value, baseUnit, targetUnit)) {
std::cerr << "Warning, cannot convert units ("
<< UnitConv::toString(baseUnit) << " -> "
<< UnitConv::toString(targetUnit) << ")" << std::endl;
unitConvert = false;
if (useFloatOutput) {
if (!UnitConv::convert(fvalue, baseUnit, targetUnit)) {
std::cerr << "Warning, cannot convert units ("
<< UnitConv::toString(baseUnit) << " -> "
<< UnitConv::toString(targetUnit) << ")" << std::endl;
unitConvert = false;
}
}
else {
if (!UnitConv::convert(ivalue, baseUnit, targetUnit)) {
std::cerr << "Warning, cannot convert units ("
<< UnitConv::toString(baseUnit) << " -> "
<< UnitConv::toString(targetUnit) << ")" << std::endl;
unitConvert = false;
}
}
}
/* Scale the value if requested */
if (scale) {
reading.value *= scalingFactor;
if (useFloatOutput) {
fvalue *= scalingFactor;
}
else {
ivalue *= scalingFactor;
}
}
/* Print the sensor's public name */
......@@ -151,7 +185,12 @@ void DCDBQuery::doQuery(const char* hostname, std::list<std::string> sensors, DC
}
/* Print the sensor value */
std::cout << reading.value << std::endl;
if (useFloatOutput) {
std::cout << fvalue << std::endl;
}
else {
std::cout << ivalue << std::endl;
}
}
}
}
......@@ -169,4 +208,5 @@ DCDBQuery::DCDBQuery()
connection = nullptr;
useLocalTime = false;
useRawOutput = false;
useFloatOutput = false;
}
......@@ -24,12 +24,15 @@ protected:
DCDBConnection* connection;
bool useLocalTime;
bool useRawOutput;
bool useFloatOutput;
public:
void setLocalTimeEnabled(bool enable);
bool getLocalTimeEnabled();
void setRawOutputEnabled(bool enable);
bool getRawOutputEnabled();
void setFloatOutputEnabled(bool enable);
bool getFloatOutputEnabled();
void doQuery(const char* hostname, std::list<std::string> sensors, DCDBTimeStamp start, DCDBTimeStamp end);
DCDBQuery();
......
......@@ -11,50 +11,88 @@
/* C standard headers */
#include <cstdint>
#include <cinttypes>
#include <cstring>
/* Custom headers */
#include "dcdb/unitconv.h"
void usage()
{
std::cout
<< "Usage: dcdbunitconv [-f] <value> <from> <to>" << std::endl
<< " where <value> is a integer value" << std::endl
<< " <from> is the source unit" << std::endl
<< " <to> is the target unit" << std::endl
<< " -f enables floating-point output" << std::endl;
}
int main(int argc, const char* argv[])
{
/* Check command line */
if (argc < 4) {
std::cout
<< "Usage: " << argv[0] << " <value> <from> <to>" << std::endl
<< " where <value> is a integer value" << std::endl
<< " <from> is the source unit" << std::endl
<< " <to> is the target unit" << std::endl;
usage();
return 1;
}
/* Parse command line */
int64_t value;
int64_t ivalue;
double fvalue;
DCDBUnit from, to;
bool fp = false;
int argshift = 0;
if (sscanf(argv[1], "%" SCNd64, &value) != 1) {
std::cout << "Cannot interpret " << argv[1] << std::endl;
return 2;
if ((strlen(argv[1]) == 2) && (strcmp("-f", argv[1]) == 0)) {
fp = true;
if (argc < 5) {
usage();
return 1;
}
argshift = 1;
}
if (fp) {
if (sscanf(argv[1+argshift], "%lf", &fvalue) != 1) {
std::cout << "Cannot interpret " << argv[1+argshift] << std::endl;
return 2;
}
}
else {
if (sscanf(argv[1+argshift], "%" SCNd64, &ivalue) != 1) {
std::cout << "Cannot interpret " << argv[1+argshift] << std::endl;
return 2;
}
}
from = UnitConv::fromString(argv[2]);
from = UnitConv::fromString(argv[2+argshift]);
if (from == DCDBUnit_None) {
std::cout << "No known unit: " << argv[2] << std::endl;
std::cout << "No known unit: " << argv[2+argshift] << std::endl;
return 3;
}
to = UnitConv::fromString(argv[3]);
to = UnitConv::fromString(argv[3+argshift]);
if (to == DCDBUnit_None) {
std::cout << "No known unit: " << argv[3] << std::endl;
std::cout << "No known unit: " << argv[3+argshift] << std::endl;
return 4;
}
/* Run conversion */
if (UnitConv::convert(value, from, to)) {
std::cout << value << std::endl;
if (fp) {
if (UnitConv::convert(fvalue, from, to)) {
std::cout << fvalue << std::endl;
}
else {
std::cout << "Cannot convert from " << UnitConv::toString(from) << " to " << UnitConv::toString(to) << std::endl;
return 5;
}
}
else {
std::cout << "Cannot convert from " << UnitConv::toString(from) << " to " << UnitConv::toString(to) << std::endl;
return 5;
if (UnitConv::convert(ivalue, from, to)) {
std::cout << ivalue << std::endl;
}
else {
std::cout << "Cannot convert from " << UnitConv::toString(from) << " to " << UnitConv::toString(to) << std::endl;
return 5;
}
}
return 0;
......
......@@ -85,6 +85,7 @@ _dcdbquery_options()
sensorlist_at=1
rawreq=0
localreq=0
floatreq=0
i=0
# Go through all possible options until first non-option (i.e. sensor) is found
......@@ -92,9 +93,12 @@ _dcdbquery_options()
if [ "${COMP_WORDS[$i]}" = "-r" ]; then
rawreq=1
sensorlist_at=$((sensorlist_at+1))
elif [ "${COMP_WORDS[$i]}" = "-l" ]; then
localreq=1
sensorlist_at=$((sensorlist_at+1))
elif [ "${COMP_WORDS[$i]}" = "-l" ]; then
localreq=1
sensorlist_at=$((sensorlist_at+1))
elif [ "${COMP_WORDS[$i]}" = "-f" ]; then
floatreq=1
sensorlist_at=$((sensorlist_at+1))
elif [ "${COMP_WORDS[$i]:0:2}" = "-h" ]; then
if [ "${COMP_WORDS[$i]}" = "-h" ]; then
i=$((i+1))
......@@ -116,6 +120,9 @@ _dcdbquery_options()
if [ ! "${localreq}" -eq "1" ]; then
comrep+=" -l"
fi
if [ ! "${floatreq}" -eq "1" ]; then
comrep+=" -f"
fi
if [ "${hostname_str}" = "" ]; then
comrep+=" -h"
fi
......
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