Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
9.2.2023: Due to updates GitLab will be unavailable for some minutes between 9:00 and 11:00.
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 @@
#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
rh
x
,
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 */
...
...
lib/src/sensoroperations.cpp
View file @
72ebad22
...
...
@@ -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 */
tools/dcdbquery/query.cpp
View file @
72ebad22
...
...
@@ -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
prev
Value
=
0
;
int64_t
prev
Reading
=
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
<<
","
;
}
}
prev
Value
=
value
;
prev
Reading
=
(
*
reading
).
value
;
prevT
=
ts
;
std
::
cout
<<
std
::
endl
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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