Generic data container for physical data and utility functions. More...
Generic data container for physical data and utility functions.
The purpose of this module is to introduce a common view on physical data throughout RIOT. This data is typically the output from sensor readings, data aggregation, and also the input for actuators.
The idea is to enable different sensor/actuator drivers and other RIOT modules to exchange and have the same view on this kind of data. Labeling data with a unit type it's scaling makes it possible to pipe data between modules in an automated fashion without the need of specialized software wrappers and/or data normalization modules.
Files | |
file | phydat.h |
Generic data container for physical data interface. | |
Data Structures | |
struct | phydat_t |
Generic data structure for expressing physical values. More... | |
Macros | |
#define | PHYDAT_DIM (3U) |
The fixed number of dimensions we work with. | |
#define | PHYDAT_SCALE_STR_MAXLEN (sizeof("*E-128\0")) |
The maximum length of a scaling string. | |
#define | PHYDAT_MIN (INT16_MIN) |
Minimum value for phydat_t::val. | |
#define | PHYDAT_MAX (INT16_MAX) |
Maximum value for phydat_t::val. | |
Enumerations | |
enum | { UNIT_UNDEF , UNIT_NONE , UNIT_TEMP_C , UNIT_TEMP_F , UNIT_TEMP_K , UNIT_LUX , UNIT_M , UNIT_M2 , UNIT_M3 , UNIT_G_FORCE , UNIT_G = UNIT_G_FORCE , UNIT_DPS , UNIT_GRAM , UNIT_GR = UNIT_GRAM , UNIT_A , UNIT_V , UNIT_W , UNIT_GAUSS , UNIT_GS = UNIT_GAUSS , UNIT_T , UNIT_DBM , UNIT_COULOMB , UNIT_F , UNIT_OHM , UNIT_PH , UNIT_BAR , UNIT_PA , UNIT_CD , UNIT_BOOL , UNIT_CTS , UNIT_PERCENT , UNIT_PERMILL , UNIT_PPM , UNIT_PPB , UNIT_TIME , UNIT_DATE , UNIT_GPM3 , UNIT_CPM3 } |
Definition of physical units and comparable data types. More... | |
Functions | |
void | phydat_dump (phydat_t *data, uint8_t dim) |
Dump the given data container to STDIO. | |
void | phydat_unit_print (uint8_t unit) |
Print a unit. | |
ssize_t | phydat_unit_write (char *dest, size_t max_size, uint8_t unit) |
Write the string representation of the given unit into the given buffer. | |
char | phydat_prefix_from_scale (int8_t scale) |
Convert the given scale factor to an SI prefix. | |
void | phydat_fit (phydat_t *dat, const int32_t *values, unsigned int dim) |
Scale integer value(s) to fit into a phydat_t. | |
size_t | phydat_to_json (const phydat_t *data, size_t dim, char *buf) |
Convert the given phydat_t structure into a JSON string. | |
int64_t | phydat_date_time_to_unix (phydat_t *date, phydat_t *time, int32_t offset_seconds) |
Convert a date and time contained in phydat structs to a Unix timestamp. | |
int64_t | phydat_unix (int16_t year, int16_t month, int16_t day, int16_t hour, int16_t minute, int16_t second, int32_t offset) |
Convert a date and time (per ISO8601) to a Unix timestamp (seconds since 1970). | |
#define PHYDAT_DIM (3U) |
The fixed number of dimensions we work with.
We use a fixed number of 3 dimensions, as many physical values we encounter can be expressed this way. In practice we have e.g. readings from accelerometers, gyros, color sensors, or set data for RGB LEDs.
When expressing 1-dimensional data we just ignore the 2 higher dimension. This leads to a slight overhead of some byte of memory - but we benefit from a unified data structure for passing around physical data.
#define PHYDAT_MAX (INT16_MAX) |
Maximum value for phydat_t::val.
#define PHYDAT_MIN (INT16_MIN) |
Minimum value for phydat_t::val.
#define PHYDAT_SCALE_STR_MAXLEN (sizeof("*E-128\0")) |
anonymous enum |
Definition of physical units and comparable data types.
This list should contain all needed physical units (e.g. SI units), but also non-physical units that can be used to define the type of data passed around. This can be for example BOOL or aggregate values. As rule of thumb, the unit list can contain anything that helps two modules automatically negotiate, if they can understand each other.
Enumerator | |
---|---|
UNIT_UNDEF | unit undefined |
UNIT_NONE | data has no physical unit |
UNIT_TEMP_C | degree Celsius |
UNIT_TEMP_F | degree Fahrenheit |
UNIT_TEMP_K | Kelvin. |
UNIT_LUX | Lux (lx) |
UNIT_M | meters |
UNIT_M2 | square meters |
UNIT_M3 | cubic meters |
UNIT_G_FORCE | gravitational force equivalent |
UNIT_G |
|
UNIT_DPS | degree per second |
UNIT_GRAM | grams - not using the SI unit (kg) here to make scale handling simpler |
UNIT_GR |
|
UNIT_A | Ampere. |
UNIT_V | Volts. |
UNIT_W | Watt. |
UNIT_GAUSS | gauss |
UNIT_GS |
|
UNIT_T | Tesla. |
UNIT_DBM | decibel-milliwatts |
UNIT_COULOMB | coulomb |
UNIT_F | Farad. |
UNIT_OHM | Ohm. |
UNIT_PH | pH |
UNIT_BAR | Beer? |
UNIT_PA | Pascal. |
UNIT_CD | Candela. |
UNIT_BOOL | boolean value [0|1] |
UNIT_CTS | counts |
UNIT_PERCENT | out of 100 |
UNIT_PERMILL | out of 1000 |
UNIT_PPM | part per million |
UNIT_PPB | part per billion |
UNIT_TIME | the three dimensions contain sec, min, and hours |
UNIT_DATE | the 3 dimensions contain days, months and years |
UNIT_GPM3 | grams per cubic meter |
UNIT_CPM3 | count per cubic meter |
Convert a date and time contained in phydat structs to a Unix timestamp.
See phydat_unix() for the date notation and peculiarities.
date | Date to use in the timestamp. |
time | Time to use in the timestamp. |
offset_seconds | Timezone offset in seconds to use in the timestamp. |
void phydat_dump | ( | phydat_t * | data, |
uint8_t | dim | ||
) |
Dump the given data container to STDIO.
[in] | data | data container to dump |
[in] | dim | number of dimension of data to dump |
void phydat_fit | ( | phydat_t * | dat, |
const int32_t * | values, | ||
unsigned int | dim | ||
) |
Scale integer value(s) to fit into a phydat_t.
Inserts the values
in the given dat
so that all dim
values in values
fit inside the limits of the data type, [PHYDAT_MIN, PHYDAT_MAX], and updates the stored scale factor. The phydat_t::scale member in dat
is used as the the original scale of the values
. The value is rounded to the nearest integer if possible, otherwise away from zero. E.g. 0.5
and 0.6
are rounded to 1
, 0.4
and -0.4
are rounded to 0
, -0.5
and -0.6
are rounded to -1
.
-DPHYDAT_FIT_TRADE_PRECISION_FOR_ROM=0
, this function will scale the value -32768
, even though it would fit into a phydat_t. Statistically, this precision loss happens in 0.00153% of the calls. This optimization saves a bit more than 20 bytes.dat
is initialized to the scale of the values
by the caller prior to calling this function.[in,out] | dat | the value will be written into this data array |
[in] | values | value(s) to rescale |
[in] | dim | Number of elements in values |
char phydat_prefix_from_scale | ( | int8_t | scale | ) |
Convert the given scale factor to an SI prefix.
The given scaling factor is returned as a SI unit prefix (e.g. M for Mega, u for micro, etc), or \0
otherwise.
[in] | scale | scale factor to convert |
\0
if no SI prefix was found size_t phydat_to_json | ( | const phydat_t * | data, |
size_t | dim, | ||
char * | buf | ||
) |
Convert the given phydat_t structure into a JSON string.
The output string written to buf
will be \0
terminated. You must make sure, that the given buf
is large enough to hold the resulting string. You can call the function with @p buf := NULL
to simply calculate the size of the JSON string without writing anything.
The formatted JSON string will have the following format:
The data will be encoded as fixed point number based on the given scale factor.
For encoding the unit, this function uses the extended phydat_unit_write() function to also print units for non-SI types, e.g. it will produce ..."u":"date"}
for UNIT_DATE or ..."u":"none"}
for UNIT_NONE.
[in] | data | data to encode |
[in] | dim | dimensions used in data , MUST be > 0 and <= PHYDAT_DIM |
[out] | buf | target buffer for the JSON string, or NULL |
dim
> 0 dim
<= PHYDAT_DIMbuf
, including \0
terminator void phydat_unit_print | ( | uint8_t | unit | ) |
Print a unit.
[in] | unit | unit to print |
ssize_t phydat_unit_write | ( | char * | dest, |
size_t | max_size, | ||
uint8_t | unit | ||
) |
Write the string representation of the given unit into the given buffer.
[out] | dest | destination buffer to write to |
[in] | max_size | size of the buffer at dest |
[in] | unit | unit to convert |
-EOVERFLOW | buffer at dest is too small |
-EINVAL | invalid unit in unit |
NULL
for dest
, it will return the number of bytes it would write (regardless of max_size
) int64_t phydat_unix | ( | int16_t | year, |
int16_t | month, | ||
int16_t | day, | ||
int16_t | hour, | ||
int16_t | minute, | ||
int16_t | second, | ||
int32_t | offset | ||
) |
Convert a date and time (per ISO8601) to a Unix timestamp (seconds since 1970).
year | Year in the Common Era (CE). Note that 0 is 1 BCE, 1 is 2 BCE, etc. |
month | Month of the year. |
day | Day of the month. |
hour | Hour of the day. |
minute | Minute of the hour. |
second | Second of the minute. |
offset | Timezone offset in seconds. |