mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
9d61bdbb06
Add a basic SenML module and submodules with support for: - Encoding SenML values as CBOR using NanoCBOR. - Converting from Phydat to SenML. - Reading and encoding SAUL sensors.
100 lines
2.8 KiB
C
100 lines
2.8 KiB
C
/*
|
|
* Copyright (C) 2021 Silke Hofstra
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
#include "nanocbor/nanocbor.h"
|
|
#include "saul_reg.h"
|
|
#include "senml.h"
|
|
#include "senml/cbor.h"
|
|
#include "senml/phydat.h"
|
|
#include "senml/saul.h"
|
|
|
|
static inline void senml_encode_phydat_bool(nanocbor_encoder_t *enc,
|
|
const saul_reg_t *dev,
|
|
const phydat_t *data,
|
|
const uint8_t dim)
|
|
{
|
|
senml_bool_value_t val = { .attr = { .name = dev->name } };
|
|
|
|
phydat_to_senml_bool(&val, data, dim);
|
|
senml_encode_bool_cbor(enc, &val);
|
|
}
|
|
|
|
static inline uint8_t senml_fix_unit(const saul_reg_t *dev, const uint8_t unit)
|
|
{
|
|
/* Fix the unit for relative humidity. */
|
|
if (dev->driver->type == SAUL_SENSE_HUM &&
|
|
unit == SENML_UNIT_PERCENT) {
|
|
return SENML_UNIT_RELATIVE_HUMIDITY_PERCENT;
|
|
}
|
|
return unit;
|
|
}
|
|
|
|
static void senml_encode_phydat_float(nanocbor_encoder_t *enc,
|
|
const saul_reg_t *dev,
|
|
const phydat_t *data, const uint8_t dim)
|
|
{
|
|
senml_value_t val = { .attr = { .name = dev->name } };
|
|
|
|
phydat_to_senml_float(&val, data, dim);
|
|
val.attr.unit = senml_fix_unit(dev, val.attr.unit);
|
|
senml_encode_value_cbor(enc, &val);
|
|
}
|
|
|
|
static void senml_encode_phydat_decimal(nanocbor_encoder_t *enc,
|
|
const saul_reg_t *dev,
|
|
const phydat_t *data, const uint8_t dim)
|
|
{
|
|
senml_value_t val = { .attr = { .name = dev->name } };
|
|
|
|
phydat_to_senml_decimal(&val, data, dim);
|
|
val.attr.unit = senml_fix_unit(dev, val.attr.unit);
|
|
senml_encode_value_cbor(enc, &val);
|
|
}
|
|
|
|
int senml_saul_reg_encode_cbor(nanocbor_encoder_t *enc, saul_reg_t *dev)
|
|
{
|
|
phydat_t data;
|
|
int dim = saul_reg_read(dev, &data);
|
|
|
|
if (dim <= 0) {
|
|
return dim;
|
|
}
|
|
|
|
for (uint8_t i = 0; i < dim; i++) {
|
|
if (data.unit == UNIT_BOOL) {
|
|
senml_encode_phydat_bool(enc, dev, &data, i);
|
|
}
|
|
else if (CONFIG_SENML_SAUL_USE_FLOATS) {
|
|
senml_encode_phydat_float(enc, dev, &data, i);
|
|
}
|
|
else {
|
|
senml_encode_phydat_decimal(enc, dev, &data, i);
|
|
}
|
|
}
|
|
|
|
return dim;
|
|
}
|
|
|
|
size_t senml_saul_encode_cbor(uint8_t *buf, size_t len, saul_reg_t *dev)
|
|
{
|
|
nanocbor_encoder_t enc;
|
|
|
|
nanocbor_encoder_init(&enc, buf, len);
|
|
nanocbor_fmt_array_indefinite(&enc);
|
|
|
|
while (dev) {
|
|
if (senml_saul_reg_encode_cbor(&enc, dev) <= 0) {
|
|
return 0;
|
|
}
|
|
dev = dev->next;
|
|
}
|
|
|
|
nanocbor_fmt_end_indefinite(&enc);
|
|
return nanocbor_encoded_len(&enc);
|
|
}
|