DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
lonworks.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file lonworks.cpp
6 * @brief LonWorks / LON-IP network-variable codec (see lonworks.h).
7 */
8
10
11#if DETWS_ENABLE_LONWORKS
12
13#include <string.h>
14
15size_t detws_lon_build_nv(uint8_t msg_code, uint16_t selector, const uint8_t *value, size_t value_len, uint8_t *out,
16 size_t cap)
17{
18 if (!out || (value_len && !value) || selector > Lon::LON_NV_SELECTOR_MAX)
19 return 0;
20 size_t n = 3 + value_len;
21 if (n > cap)
22 return 0;
23 out[0] = msg_code;
24 out[1] = (uint8_t)(selector >> 8); // 14-bit selector, big-endian
25 out[2] = (uint8_t)selector;
26 if (value_len)
27 memcpy(out + 3, value, value_len);
28 return n;
29}
30
31bool detws_lon_parse_nv(const uint8_t *pdu, size_t len, LonNv *out)
32{
33 if (!pdu || !out || len < 3)
34 return false;
35 out->msg_code = pdu[0];
36 out->selector = (uint16_t)(((pdu[1] & 0x3F) << 8) | pdu[2]); // 14-bit
37 out->value = (len > 3) ? (pdu + 3) : nullptr;
38 out->value_len = len - 3;
39 return true;
40}
41
42void detws_lon_snvt_temp_encode(double celsius, uint8_t out[2])
43{
44 // SNVT_temp: kelvin in 0.01 K steps -> (celsius + 273.15) * 100, as a signed 16-bit big-endian.
45 double kelvin_hundredths = (celsius + 273.15) * 100.0;
46 int32_t v = (int32_t)(kelvin_hundredths >= 0 ? kelvin_hundredths + 0.5 : kelvin_hundredths - 0.5);
47 if (v > 32767)
48 v = 32767;
49 if (v < -32768)
50 v = -32768;
51 uint16_t u = (uint16_t)v;
52 out[0] = (uint8_t)(u >> 8);
53 out[1] = (uint8_t)u;
54}
55
56double detws_lon_snvt_temp_decode(const uint8_t in[2])
57{
58 int16_t v = (int16_t)((in[0] << 8) | in[1]);
59 return (double)v / 100.0 - 273.15;
60}
61
62void detws_lon_snvt_switch_encode(double percent, uint8_t state, uint8_t out[2])
63{
64 // SNVT_switch: value is 0..200 in 0.5% steps (0..100.5%), state is 0/1/0xFF.
65 if (percent < 0)
66 percent = 0;
67 if (percent > 100.5)
68 percent = 100.5;
69 uint8_t v = (uint8_t)(percent * 2.0 + 0.5);
70 out[0] = v;
71 out[1] = state;
72}
73
74void detws_lon_snvt_switch_decode(const uint8_t in[2], double *percent, uint8_t *state)
75{
76 if (percent)
77 *percent = (double)in[0] / 2.0;
78 if (state)
79 *state = in[1];
80}
81
82#endif // DETWS_ENABLE_LONWORKS
LonWorks / LON-IP (ISO/IEC 14908) network-variable codec (DETWS_ENABLE_LONWORKS).