Jak na: CBOR
Zařízení CHESTER s Cloud v2 používá CBOR pro kódování a dekódování přenášených dat. Díky CBOR můžete pomocí souboru YAML popsat, jak budou přenášená data vypadat, a poté ve svém kódu v C používat klíče z tohoto souboru YAML.
V úvodních zprávách session posílá Cloud hash kodeku ve zprávě session down. CHESTER porovná tento hash se svým vlastním hashem kodeku a pokud je potřeba, nahraje dekodér zprávou decoder up a případně nahraje enkodér ve zprávě encoder up.
Abyste mohli s zařízením CHESTER používat CBOR, je potřeba:
- Vytvořit ve složce aplikace soubor
codec\cbor-decoder.yaml, který popisuje atributy JSON. - Případně vytvořit soubor
codec\cbor-encoder.yamlpro downlink příkazy (viz kód CHESTER Control) - Hlavičkový soubor
src/app_codec.hse vygeneruje automaticky při zavoláníwest build. - Použít tyto definice v
app_cbor.ca přidat potřebná data.
Soubor YAML má hlavičku a poté v schema definujete striktně hierarchickou strukturu.
V src/app_codec.h jsou vygenerované #define s názvy jako CODEC_KEY_E_, kde E znamená Encoder (z pohledu zařízení CHESTER).
Pokud vnořujete položky do hlubší struktury, uvidíte v hlavičkovém souboru dvojité podtržítko __.
Například CODEC_KEY_E_NETWORK__MESSAGE__VERSION pro příklad YAML níže.
version: 2
type: decoder
name: com.hardwario.chester.app.clime
schema:
- message:
- version:
- sequence:
- timestamp:
...
Více praktických příkladů najdete v CHESTER SDK ve složce katalogových aplikací chester/applications/*.
Pojmenování cbor-decoder.yaml a cbor-encoder.yaml vychází z pohledu Cloudu. Zařízení CHESTER tedy kóduje data pomocí souboru decoder, protože cloud tento soubor YAML používá k dekódování.
YAML
V YAML definujete názvy klíčů, které se později použijí v dekódovaném JSON. Soubor YAML však může definovat i další věci:
- Modifikátory
- Enumerátory
- Data časových řad, periodická (TSP) nebo s časovým offsetem (TSO)
Modifikátory
Modifikátory jsou:
$add$sub$mul$div$fpp- počet desetinných míst čísla s plovoucí řádovou tečkou v JSON$key- přejmenování klíče v JSON
Příklad níže vytváří klíč s názvem temperature. V zařízení CHESTER je potřeba hodnotu vynásobit 100, poté je v HARDWARIO Cloud automaticky vydělena 100 a ve výsledném JSON má číslo dvě desetinná místa.
- temperature:
- $div: 100
- $fpp: 2
Kód v C pro zařízení CHESTER bude vypadat takto:
zcbor_uint32_put(zs, CODEC_KEY_E_TEMPERATURE);
zcbor_int32_put(zs, g_app_data.therm_temperature * 100.f);
Výstupní JSON bude:
"temperature": 21.75
Enumerátory
Definujte textové hodnoty a posílejte je efektivně jako celé číslo.
- backup_state:
- $enum:
- inactive
- active
Kód v C pro zařízení CHESTER bude vypadat takto:
zcbor_uint32_put(zs, CODEC_KEY_E_BACKUP_STATE);
zcbor_uint32_put(zs, g_app_data.backup.line_present ? 1 : 0);
Výstupní JSON bude:
"backup_state": "active"
Time Series Period
Time Series Period (TSP) efektivně kóduje hodnotu nebo více hodnot s časovými značkami. V zařízení CHESTER posíláte pouze referenční timestamp, period a values. Dekodér automaticky přidá ke každé hodnotě absolutní časovou značku.
- measurements_val:
- $tsp:
- avg:
- mdn:
Kód v C pro zařízení CHESTER bude vypadat takto:
zcbor_uint32_put(zs, CODEC_KEY_E_MEASUREMENTS_VAL);
{
zcbor_list_start_encode(zs, ZCBOR_VALUE_IS_INDEFINITE_LENGTH);
zcbor_uint64_put(zs, g_app_data.counter.timestamp); // unix timestamp 1679321760
zcbor_uint32_put(zs, g_app_config.counter_interval_aggreg); // 30 seconds
for (int i = 0; i < g_app_data.counter.measurement_count; i++) {
zcbor_uint64_put(zs, g_app_data.counter.measurements[i].avg);
zcbor_uint64_put(zs, g_app_data.counter.measurements[i].mdn);
}
zcbor_list_end_encode(zs, ZCBOR_VALUE_IS_INDEFINITE_LENGTH);
}
Výstupní JSON bude:
measurements_val:
[
{
"timestamp": 1679321760,
"avg": 123,
"mdn": 456
},
{
"timestamp": 1679321790,
"avg": 123,
"mdn": 456
},
...
]
Všimněte si, že v JSON je časová značka každého vzorku absolutní. Vypočítá se z referenční časové značky 1679321760 prvního vzorku; další vzorek pak má časovou značku větší o 30 sekund, tedy 1679321790.
Time Series Offset
Time Series Offset (TSO) je podobný předchozímu Time Series Period (TSP). Čas mezi vzorky však není periodický a každý vzorek má svůj vlastní offset vůči předchozímu.
Tento kód také ukazuje, jak lze kombinovat modifikátory uvnitř TSO.
- trigger_events:
- $key: "events"
- $tso:
- type:
- $enum:
- deactivated
- activated
Kód v C pro zařízení CHESTER bude vypadat takto:
int64_t timestamp_abs = g_app_data.trigger.events[0].timestamp;
zcbor_uint32_put(zs, CODEC_KEY_E_TRIGGER_EVENTS);
{
zcbor_list_start_encode(zs, ZCBOR_VALUE_IS_INDEFINITE_LENGTH);
/* TSO absolute timestamp */
zcbor_int64_put(zs, timestamp_abs);
for (int i = 0; i < g_app_data.trigger.event_count; i++) {
/* TSO offset timestamp */
zcbor_int64_put(zs, g_app_data.trigger.events[i].timestamp - timestamp_abs);
zcbor_uint32_put(zs, g_app_data.trigger.events[i].is_active ? 1 : 0);
}
zcbor_list_end_encode(zs, ZCBOR_VALUE_IS_INDEFINITE_LENGTH);
}
Výstupní JSON bude:
events:
[
{
"timestamp": 1679321760,
"event": "activated"
},
{
"timestamp": 1679321765,
"event": "deactivated"
},
{
"timestamp": 1679321780,
"event": "activated"
},
...
]