1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/sys/senml/phydat.c
Marian Buschsieweke 3c287c058d
sys/phydat: Fix unit confusion
Previously, `UNIT_G` was used for g-force with the correct symbol `g`,
`UNIT_GR` for gram (as in kilogram) with the incorrect symbol `G` (which
would be correct for Gauss), and `UNIT_GS` for Gauss with symbol `Gs`
(which is an uncommon but correct symbol).

To avoid confusion between G-Force, Gauss, and Gram the units have been
renamed to `UNIT_G_FORCE`, `UNIT_GRAM`, and `UNIT_GAUSS`. In addition,
gram now uses the correct symbol `g` and Gauss uses `G`.
2023-02-23 16:44:24 +01:00

154 lines
4.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 <stdint.h>
#include "math.h"
#include "senml.h"
#include "senml/phydat.h"
static uint8_t phydat_unit_to_senml_unit(uint8_t unit)
{
switch (unit) {
/* Compatible units */
case UNIT_TEMP_C: return SENML_UNIT_CELSIUS;
case UNIT_TEMP_K: return SENML_UNIT_KELVIN;
case UNIT_LUX: return SENML_UNIT_LUX;
case UNIT_M: return SENML_UNIT_METER;
case UNIT_M2: return SENML_UNIT_SQUARE_METER;
case UNIT_M3: return SENML_UNIT_CUBIC_METER;
case UNIT_GRAM: return SENML_UNIT_GRAM;
case UNIT_A: return SENML_UNIT_AMPERE;
case UNIT_V: return SENML_UNIT_VOLT;
case UNIT_W: return SENML_UNIT_WATT;
case UNIT_T: return SENML_UNIT_TESLA;
case UNIT_COULOMB: return SENML_UNIT_COULOMB;
case UNIT_F: return SENML_UNIT_FARAD;
case UNIT_OHM: return SENML_UNIT_OHM;
case UNIT_PH: return SENML_UNIT_PH;
case UNIT_PA: return SENML_UNIT_PASCAL;
case UNIT_CD: return SENML_UNIT_CANDELA;
/* Compatible Secondary units */
case UNIT_DBM: return SENML_UNIT_DECIBEL_MILLIWATT;
case UNIT_PERCENT: return SENML_UNIT_PERCENT;
case UNIT_PERMILL: return SENML_UNIT_PERMILLE;
case UNIT_PPM: return SENML_UNIT_PARTS_PER_MILLION;
case UNIT_PPB: return SENML_UNIT_PARTS_PER_BILLION;
/* Incompatible units */
case UNIT_TEMP_F: return SENML_UNIT_NONE; /* use K or Cel instead */
case UNIT_GAUSS: return SENML_UNIT_NONE; /* use T instead */
case UNIT_G_FORCE: return SENML_UNIT_NONE; /* use m/s2 instead */
case UNIT_BAR: return SENML_UNIT_NONE; /* use Pa or hPa instead */
case UNIT_TIME: return SENML_UNIT_NONE; /* split into second/minute/hour */
case UNIT_DATE: return SENML_UNIT_NONE; /* split into day/month/year */
case UNIT_GPM3: return SENML_UNIT_NONE; /* use kg/m3 instead */
case UNIT_DPS: return SENML_UNIT_NONE; /* no alternative */
case UNIT_CPM3: return SENML_UNIT_NONE; /* no alternative */
default: return SENML_UNIT_NONE;
}
}
void phydat_to_senml_bool(senml_bool_value_t *senml, const phydat_t *phydat, const uint8_t dim)
{
senml->value = phydat->val[dim] == 1;
senml->attr.unit = SENML_UNIT_NONE;
}
void phydat_to_senml_float(senml_value_t *senml, const phydat_t *phydat, const uint8_t dim)
{
float value = (float)(phydat->val[dim]);
if (phydat->scale) {
value *= pow(10, phydat->scale);
}
switch (phydat->unit) {
/* time conversion */
case UNIT_TIME:
senml->attr.unit = (dim == 0)
? SENML_UNIT_SECOND
: (dim == 1)
? SENML_UNIT_MINUTE
: SENML_UNIT_HOUR;
break;
/* simple conversions */
case UNIT_TEMP_F:
/* convert fahrenheit to kelvin */
value = (value + 459.67) * (5. / 9.);
senml->attr.unit = SENML_UNIT_KELVIN;
break;
case UNIT_G_FORCE:
/* convert gravitational acceleration to acceleration */
value *= 9.80665;
senml->attr.unit = SENML_UNIT_METER_PER_SQUARE_SECOND;
break;
case UNIT_BAR:
value *= 100000;
senml->attr.unit = SENML_UNIT_PASCAL;
break;
case UNIT_GPM3:
value *= 0.001;
senml->attr.unit = SENML_UNIT_KILOGRAM_PER_CUBIC_METER;
break;
case UNIT_GAUSS:
value *= 0.0001;
senml->attr.unit = SENML_UNIT_TESLA;
break;
/* compatible (or not converted) */
default:
senml->attr.unit = phydat_unit_to_senml_unit(phydat->unit);
break;
}
senml->value = senml_float(value);
}
void phydat_to_senml_decimal(senml_value_t *senml, const phydat_t *phydat, const uint8_t dim)
{
int32_t m = phydat->val[dim];
int32_t e = phydat->scale;
switch (phydat->unit) {
/* time conversion */
case UNIT_TIME:
senml->attr.unit = (dim == 0)
? SENML_UNIT_SECOND
: (dim == 1)
? SENML_UNIT_MINUTE
: SENML_UNIT_HOUR;
break;
/* simple conversions */
case UNIT_BAR:
e += 5;
senml->attr.unit = SENML_UNIT_PASCAL;
break;
case UNIT_GPM3:
e -= 3;
senml->attr.unit = SENML_UNIT_KILOGRAM_PER_CUBIC_METER;
break;
case UNIT_GAUSS:
e -= 4;
senml->attr.unit = SENML_UNIT_TESLA;
break;
/* compatible, or not converted */
default:
senml->attr.unit = phydat_unit_to_senml_unit(phydat->unit);
break;
}
senml->value = senml_decfrac(m, e);
}