Loading...
Searching...
No Matches
Phydat

Generic data container for physical data and utility functions. More...

Detailed Description

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.

Todo:
It might make sense to introduce additional data types for increased precision, i.e. something like phydat_float_t...

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).
 

Macro Definition Documentation

◆ PHYDAT_DIM

#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.

Definition at line 59 of file phydat.h.

◆ PHYDAT_MAX

#define PHYDAT_MAX   (INT16_MAX)

Maximum value for phydat_t::val.

Definition at line 169 of file phydat.h.

◆ PHYDAT_MIN

#define PHYDAT_MIN   (INT16_MIN)

Minimum value for phydat_t::val.

Definition at line 164 of file phydat.h.

◆ PHYDAT_SCALE_STR_MAXLEN

#define PHYDAT_SCALE_STR_MAXLEN   (sizeof("*E-128\0"))

The maximum length of a scaling string.

Definition at line 64 of file phydat.h.

Enumeration Type Documentation

◆ anonymous enum

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.

Note
Extent this list as needed.
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 
Deprecated:
, use UNIT_G_FORCE instead
UNIT_DPS 

degree per second

UNIT_GRAM 

grams - not using the SI unit (kg) here to make scale handling simpler

UNIT_GR 
Deprecated:
, use UNIT_GRAM instead
UNIT_A 

Ampere.

UNIT_V 

Volts.

UNIT_W 

Watt.

UNIT_GAUSS 

gauss

UNIT_GS 
Deprecated:
, use UNIT_GAUSS instead
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

Definition at line 77 of file phydat.h.

Function Documentation

◆ phydat_date_time_to_unix()

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.

See phydat_unix() for the date notation and peculiarities.

Parameters
dateDate to use in the timestamp.
timeTime to use in the timestamp.
offset_secondsTimezone offset in seconds to use in the timestamp.
Returns
A unix timestamp

◆ phydat_dump()

void phydat_dump ( phydat_t data,
uint8_t  dim 
)

Dump the given data container to STDIO.

Parameters
[in]datadata container to dump
[in]dimnumber of dimension of data to dump

◆ phydat_fit()

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.

int32_t values[] = { 100000, 2000000, 30000000 };
phydat_t dat = { .scale = 0 };
phydat_fit(&dat, values, 3);
void phydat_fit(phydat_t *dat, const int32_t *values, unsigned int dim)
Scale integer value(s) to fit into a phydat_t.
Generic data structure for expressing physical values.
Definition phydat.h:155
int8_t scale
the scale factor, 10^*scale*
Definition phydat.h:158
Note
Unless compiled with -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.
Precondition
The phydat_t::scale member in dat is initialized to the scale of the values by the caller prior to calling this function.
Parameters
[in,out]datthe value will be written into this data array
[in]valuesvalue(s) to rescale
[in]dimNumber of elements in values

◆ phydat_prefix_from_scale()

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.

Parameters
[in]scalescale factor to convert
Returns
SI prefix if applicable
\0 if no SI prefix was found

◆ phydat_to_json()

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:

// case (dim == 1):
{
"d": 21.45,
"u": "°C"
}
// case (dim > 1), dim := 3 in this case:
{
"d": [1.02, 0.23, -0.81],
"u": "g"
}

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.

Parameters
[in]datadata to encode
[in]dimdimensions used in data, MUST be > 0 and <= PHYDAT_DIM
[out]buftarget buffer for the JSON string, or NULL
Precondition
dim > 0
dim <= PHYDAT_DIM
Returns
number of bytes (potentially) written to buf, including \0 terminator

◆ phydat_unit_print()

void phydat_unit_print ( uint8_t  unit)

Print a unit.

Parameters
[in]unitunit to print

◆ phydat_unit_write()

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.

Parameters
[out]destdestination buffer to write to
[in]max_sizesize of the buffer at dest
[in]unitunit to convert
Returns
Number of bytes written
Return values
-EOVERFLOWbuffer at dest is too small
-EINVALinvalid unit in unit
Warning
The function will never write a terminating zero byte
Note
If you pass NULL for dest, it will return the number of bytes it would write (regardless of max_size)

◆ phydat_unix()

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).

Parameters
yearYear in the Common Era (CE). Note that 0 is 1 BCE, 1 is 2 BCE, etc.
monthMonth of the year.
dayDay of the month.
hourHour of the day.
minuteMinute of the hour.
secondSecond of the minute.
offsetTimezone offset in seconds.
Returns
A Unix timestamp (seconds since 1970).