Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
dcdb
dcdb
Commits
72ebad22
Commit
72ebad22
authored
Apr 17, 2019
by
Michael Ott
Browse files
Fix integral and derivative computations, account for timestamp conversion
parent
42d95d47
Changes
3
Hide whitespace changes
Inline
Side-by-side
lib/include/dcdb/sensoroperations.h
View file @
72ebad22
...
@@ -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
rh
x
,
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 */
...
...
lib/src/sensoroperations.cpp
View file @
72ebad22
...
@@ -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 */
tools/dcdbquery/query.cpp
View file @
72ebad22
...
@@ -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
prev
Value
=
0
;
int64_t
prev
Reading
=
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
<<
","
;
}
}
}
}
prev
Value
=
value
;
prev
Reading
=
(
*
reading
).
value
;
prevT
=
ts
;
prevT
=
ts
;
std
::
cout
<<
std
::
endl
;
std
::
cout
<<
std
::
endl
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment