knx
ETS configurable knx-stack
dptconvert.cpp
Go to the documentation of this file.
1 #include "dptconvert.h"
2 #include "bits.h"
3 #include <cmath>
4 #include <cstdlib>
5 #include <cstring>
6 
7 #define ASSERT_PAYLOAD(x) \
8  if (payload_length != (x)) \
9  return false
10 #define ENSURE_PAYLOAD(x)
11 
12 
13 bool KNX_Decode_Value(uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
14 {
15  if (payload_length > 0)
16  {
17  // DPT 1.* - Binary
18  if (datatype.mainGroup == 1 && datatype.subGroup >= 1 && datatype.subGroup <= 23 && datatype.subGroup != 20 && !datatype.index)
19  return busValueToBinary(payload, payload_length, datatype, value);
20 
21  // DPT 2.* - Binary Control
22  if (datatype.mainGroup == 2 && datatype.subGroup >= 1 && datatype.subGroup <= 12 && datatype.index <= 1)
23  return busValueToBinaryControl(payload, payload_length, datatype, value);
24 
25  // DPT 3.* - Step Control
26  if (datatype.mainGroup == 3 && datatype.subGroup >= 7 && datatype.subGroup <= 8 && datatype.index <= 1)
27  return busValueToStepControl(payload, payload_length, datatype, value);
28 
29  // DPT 4.* - Character
30  if (datatype.mainGroup == 4 && datatype.subGroup >= 1 && datatype.subGroup <= 2 && !datatype.index)
31  return busValueToCharacter(payload, payload_length, datatype, value);
32 
33  // DPT 5.* - Unsigned 8 Bit Integer
34  if (datatype.mainGroup == 5 && ((datatype.subGroup >= 1 && datatype.subGroup <= 6 && datatype.subGroup != 2) || datatype.subGroup == 10) && !datatype.index)
35  return busValueToUnsigned8(payload, payload_length, datatype, value);
36 
37  // DPT 6.001/6.010 - Signed 8 Bit Integer
38  if (datatype.mainGroup == 6 && (datatype.subGroup == 1 || datatype.subGroup == 10) && !datatype.index)
39  return busValueToSigned8(payload, payload_length, datatype, value);
40 
41  // DPT 6.020 - Status with Mode
42  if (datatype.mainGroup == 6 && datatype.subGroup == 20 && datatype.index <= 5)
43  return busValueToStatusAndMode(payload, payload_length, datatype, value);
44 
45  // DPT 7.001/7.010/7.011/7.012/7.013/7.600 - Unsigned 16 Bit Integer
46  if (datatype.mainGroup == 7 && (datatype.subGroup == 1 || (datatype.subGroup >= 10 && datatype.subGroup <= 13) || (datatype.subGroup == 600)) && !datatype.index)
47  return busValueToUnsigned16(payload, payload_length, datatype, value);
48 
49  // DPT 7.002-DPT 7.007 - Time Period
50  if (datatype.mainGroup == 7 && datatype.subGroup >= 2 && datatype.subGroup <= 7 && !datatype.index)
51  return busValueToTimePeriod(payload, payload_length, datatype, value);
52 
53  // DPT 8.001/8.010/8.011 - Signed 16 Bit Integer
54  if (datatype.mainGroup == 8 && (datatype.subGroup == 1 || datatype.subGroup == 10 || datatype.subGroup == 11) && !datatype.index)
55  return busValueToSigned16(payload, payload_length, datatype, value);
56 
57  // DPT 8.002-DPT 8.007 - Time Delta
58  if (datatype.mainGroup == 8 && datatype.subGroup >= 2 && datatype.subGroup <= 7 && !datatype.index)
59  return busValueToTimeDelta(payload, payload_length, datatype, value);
60 
61  // DPT 9.* - 16 Bit Float
62  if (datatype.mainGroup == 9 && ((datatype.subGroup >= 1 && datatype.subGroup <= 11) || (datatype.subGroup >= 20 && datatype.subGroup <= 29)) && !datatype.index)
63  return busValueToFloat16(payload, payload_length, datatype, value);
64 
65  // DPT 10.* - Time and Weekday
66  if (datatype.mainGroup == 10 && datatype.subGroup == 1 && datatype.index <= 1)
67  return busValueToTime(payload, payload_length, datatype, value);
68 
69  // DPT 11.* - Date
70  if (datatype.mainGroup == 11 && datatype.subGroup == 1 && !datatype.index)
71  return busValueToDate(payload, payload_length, datatype, value);
72 
73  // DPT 12.* - Unsigned 32 Bit Integer
74  if (datatype.mainGroup == 12 && datatype.subGroup == 1 && !datatype.index)
75  return busValueToUnsigned32(payload, payload_length, datatype, value);
76 
77  // DPT 13.001/13.002/13.010-13.015 - Signed 32 Bit Integer
78  if (datatype.mainGroup == 13 && (datatype.subGroup == 1 || datatype.subGroup == 2 || (datatype.subGroup >= 10 && datatype.subGroup <= 15)) && !datatype.index)
79  return busValueToSigned32(payload, payload_length, datatype, value);
80 
81  // DPT 13.100 - Long Time Period
82  if (datatype.mainGroup == 13 && datatype.subGroup == 100 && !datatype.index)
83  return busValueToLongTimePeriod(payload, payload_length, datatype, value);
84 
85  // DPT 14.* - 32 Bit Float
86  if (datatype.mainGroup == 14 && datatype.subGroup <= 79 && !datatype.index)
87  return busValueToFloat32(payload, payload_length, datatype, value);
88 
89  // DPT 15.* - Access Data
90  if (datatype.mainGroup == 15 && !datatype.subGroup && datatype.index <= 5)
91  return busValueToAccess(payload, payload_length, datatype, value);
92 
93  // DPT 16.* - String
94  if (datatype.mainGroup == 16 && datatype.subGroup <= 1 && !datatype.index)
95  return busValueToString(payload, payload_length, datatype, value);
96 
97  // DPT 17.* - Scene Number
98  if (datatype.mainGroup == 17 && datatype.subGroup == 1 && !datatype.index)
99  return busValueToScene(payload, payload_length, datatype, value);
100 
101  // DPT 18.* - Scene Control
102  if (datatype.mainGroup == 18 && datatype.subGroup == 1 && datatype.index <= 1)
103  return busValueToSceneControl(payload, payload_length, datatype, value);
104 
105  // DPT 19.* - Date and Time
106  if (datatype.mainGroup == 19 && datatype.subGroup == 1 && (datatype.index <= 3 || datatype.index == 9 || datatype.index == 10))
107  return busValueToDateTime(payload, payload_length, datatype, value);
108 
109  // DPT 20.* - HVAC Control mode Unsigned 8 Bit Integer
110  if (datatype.mainGroup == 20 && !datatype.index)
111  return busValueToUnsigned8(payload, payload_length, datatype, value);
112 
113  // DPT 26.* - Scene Info
114  if (datatype.mainGroup == 26 && datatype.subGroup == 1 && datatype.index <= 1)
115  return busValueToSceneInfo(payload, payload_length, datatype, value);
116 
117  // DPT 27.001 - 32 Bit field
118  if (datatype.mainGroup == 27 && datatype.subGroup == 1 && !datatype.index)
119  return busValueToSigned32(payload, payload_length, datatype, value);
120 
121  // DPT 28.* - Unicode String
122  if (datatype.mainGroup == 28 && datatype.subGroup == 1 && !datatype.index)
123  return busValueToUnicode(payload, payload_length, datatype, value);
124 
125  // DPT 29.* - Signed 64 Bit Integer
126  if (datatype.mainGroup == 29 && datatype.subGroup >= 10 && datatype.subGroup <= 12 && !datatype.index)
127  return busValueToSigned64(payload, payload_length, datatype, value);
128 
129  // DPT 219.* - Alarm Info
130  if (datatype.mainGroup == 219 && datatype.subGroup == 1 && datatype.index <= 10)
131  return busValueToAlarmInfo(payload, payload_length, datatype, value);
132 
133  // DPT 221.* - Serial Number
134  if (datatype.mainGroup == 221 && datatype.subGroup == 1 && datatype.index <= 1)
135  return busValueToSerialNumber(payload, payload_length, datatype, value);
136 
137  // DPT 217.* - Version
138  if (datatype.mainGroup == 217 && datatype.subGroup == 1 && datatype.index <= 2)
139  return busValueToVersion(payload, payload_length, datatype, value);
140 
141  // DPT 225.001/225.002 - Scaling Speed and Scaling Step Time
142  if (datatype.mainGroup == 225 && datatype.subGroup >= 1 && datatype.subGroup <= 2 && datatype.index <= 1)
143  return busValueToScaling(payload, payload_length, datatype, value);
144 
145  // DPT 225.003 - Next Tariff
146  if (datatype.mainGroup == 225 && datatype.subGroup == 3 && datatype.index <= 1)
147  return busValueToTariff(payload, payload_length, datatype, value);
148 
149  // DPT 231.* - Locale
150  if (datatype.mainGroup == 231 && datatype.subGroup == 1 && datatype.index <= 1)
151  return busValueToLocale(payload, payload_length, datatype, value);
152 
153  // DPT 232.600 - RGB
154  if (datatype.mainGroup == 232 && datatype.subGroup == 600 && !datatype.index)
155  return busValueToRGB(payload, payload_length, datatype, value);
156 
157  // DPT 234.* - Language and Region
158  if (datatype.mainGroup == 234 && datatype.subGroup >= 1 && datatype.subGroup <= 2 && !datatype.index)
159  return busValueToLocale(payload, payload_length, datatype, value);
160 
161  // DPT 235.* - Active Energy
162  if (datatype.mainGroup == 235 && datatype.subGroup == 1 && datatype.index <= 3)
163  return busValueToActiveEnergy(payload, payload_length, datatype, value);
164 
165  // DPT 238.* - Scene Config
166  if (datatype.mainGroup == 238 && datatype.subGroup == 1 && datatype.index <= 2)
167  return busValueToSceneConfig(payload, payload_length, datatype, value);
168 
169  // DPT 239.* - Flagged Scaling
170  if (datatype.mainGroup == 239 && datatype.subGroup == 1 && datatype.index <= 1)
171  return busValueToFlaggedScaling(payload, payload_length, datatype, value);
172 
173  // DPT 251.600 - RGBW
174  if (datatype.mainGroup == 251 && datatype.subGroup == 600 && datatype.index <= 1)
175  return busValueToRGBW(payload, payload_length, datatype, value);
176  }
177 
178  return false;
179 }
180 
181 bool KNX_Encode_Value(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
182 {
183  if (datatype.mainGroup == 1 && datatype.subGroup >= 1 && datatype.subGroup <= 23 && datatype.subGroup != 20 && !datatype.index)
184  return valueToBusValueBinary(value, payload, payload_length, datatype);
185 
186  // DPT 2.* - Binary Control
187  if (datatype.mainGroup == 2 && datatype.subGroup >= 1 && datatype.subGroup <= 12 && datatype.index <= 1)
188  return valueToBusValueBinaryControl(value, payload, payload_length, datatype);
189 
190  // DPT 3.* - Step Control
191  if (datatype.mainGroup == 3 && datatype.subGroup >= 7 && datatype.subGroup <= 8 && datatype.index <= 1)
192  return valueToBusValueStepControl(value, payload, payload_length, datatype);
193 
194  // DPT 4.* - Character
195  if (datatype.mainGroup == 4 && datatype.subGroup >= 1 && datatype.subGroup <= 2 && !datatype.index)
196  return valueToBusValueCharacter(value, payload, payload_length, datatype);
197 
198  // DPT 5.* - Unsigned 8 Bit Integer
199  if (datatype.mainGroup == 5 && ((datatype.subGroup >= 1 && datatype.subGroup <= 6 && datatype.subGroup != 2) || datatype.subGroup == 10) && !datatype.index)
200  return valueToBusValueUnsigned8(value, payload, payload_length, datatype);
201 
202  // DPT 6.001/6.010 - Signed 8 Bit Integer
203  if (datatype.mainGroup == 6 && (datatype.subGroup == 1 || datatype.subGroup == 10) && !datatype.index)
204  return valueToBusValueSigned8(value, payload, payload_length, datatype);
205 
206  // DPT 6.020 - Status with Mode
207  if (datatype.mainGroup == 6 && datatype.subGroup == 20 && datatype.index <= 5)
208  return valueToBusValueStatusAndMode(value, payload, payload_length, datatype);
209 
210  // DPT 7.001/7.010/7.011/7.012/7.013/7.600 - Unsigned 16 Bit Integer
211  if (datatype.mainGroup == 7 && (datatype.subGroup == 1 || (datatype.subGroup >= 10 && datatype.subGroup <= 13) || datatype.subGroup == 600) && !datatype.index)
212  return valueToBusValueUnsigned16(value, payload, payload_length, datatype);
213 
214  // DPT 7.002-DPT 7.007 - Time Period
215  if (datatype.mainGroup == 7 && datatype.subGroup >= 2 && datatype.subGroup <= 7 && !datatype.index)
216  return valueToBusValueTimePeriod(value, payload, payload_length, datatype);
217 
218  // DPT 8.001/8.010/8.011 - Signed 16 Bit Integer
219  if (datatype.mainGroup == 8 && (datatype.subGroup == 1 || datatype.subGroup == 10 || datatype.subGroup == 11) && !datatype.index)
220  return valueToBusValueSigned16(value, payload, payload_length, datatype);
221 
222  // DPT 8.002-DPT 8.007 - Time Delta
223  if (datatype.mainGroup == 8 && datatype.subGroup >= 2 && datatype.subGroup <= 7 && !datatype.index)
224  return valueToBusValueTimeDelta(value, payload, payload_length, datatype);
225 
226  // DPT 9.* - 16 Bit Float
227  if (datatype.mainGroup == 9 && ((datatype.subGroup >= 1 && datatype.subGroup <= 11 ) || (datatype.subGroup >= 20 && datatype.subGroup <= 29)) && !datatype.index)
228  return valueToBusValueFloat16(value, payload, payload_length, datatype);
229 
230  // DPT 10.* - Time and Weekday
231  if (datatype.mainGroup == 10 && datatype.subGroup == 1 && datatype.index <= 1)
232  return valueToBusValueTime(value, payload, payload_length, datatype);
233 
234  // DPT 11.* - Date
235  if (datatype.mainGroup == 11 && datatype.subGroup == 1 && !datatype.index)
236  return valueToBusValueDate(value, payload, payload_length, datatype);
237 
238  // DPT 12.* - Unsigned 32 Bit Integer
239  if (datatype.mainGroup == 12 && datatype.subGroup == 1 && !datatype.index)
240  return valueToBusValueUnsigned32(value, payload, payload_length, datatype);
241 
242  // DPT 13.001/13.002/13.010-13.015 - Signed 32 Bit Integer
243  if (datatype.mainGroup == 13 && (datatype.subGroup == 1 || datatype.subGroup == 2 || (datatype.subGroup >= 10 && datatype.subGroup <= 15)) && !datatype.index)
244  return valueToBusValueSigned32(value, payload, payload_length, datatype);
245 
246  // DPT 13.100 - Long Time Period
247  if (datatype.mainGroup == 13 && datatype.subGroup == 100 && !datatype.index)
248  return valueToBusValueLongTimePeriod(value, payload, payload_length, datatype);
249 
250  // DPT 14.* - 32 Bit Float
251  if (datatype.mainGroup == 14 && datatype.subGroup <= 79 && !datatype.index)
252  return valueToBusValueFloat32(value, payload, payload_length, datatype);
253 
254  // DPT 15.* - Access Data
255  if (datatype.mainGroup == 15 && !datatype.subGroup && datatype.index <= 5)
256  return valueToBusValueAccess(value, payload, payload_length, datatype);
257 
258  // DPT 16.* - String
259  if (datatype.mainGroup == 16 && datatype.subGroup <= 1 && !datatype.index)
260  return valueToBusValueString(value, payload, payload_length, datatype);
261 
262  // DPT 17.* - Scene Number
263  if (datatype.mainGroup == 17 && datatype.subGroup == 1 && !datatype.index)
264  return valueToBusValueScene(value, payload, payload_length, datatype);
265 
266  // DPT 18.* - Scene Control
267  if (datatype.mainGroup == 18 && datatype.subGroup == 1 && datatype.index <= 1)
268  return valueToBusValueSceneControl(value, payload, payload_length, datatype);
269 
270  // DPT 19.* - Date and Time
271  if (datatype.mainGroup == 19 && datatype.subGroup == 1 && (datatype.index <= 3 || datatype.index == 9 || datatype.index == 10))
272  return valueToBusValueDateTime(value, payload, payload_length, datatype);
273 
274  // DPT 20.* - HVAC Control mode Unsigned 8 Bit Integer
275  if (datatype.mainGroup == 20 && !datatype.index)
276  return valueToBusValueUnsigned8(value, payload, payload_length, datatype);
277 
278  // DPT 26.* - Scene Info
279  if (datatype.mainGroup == 26 && datatype.subGroup == 1 && datatype.index <= 1)
280  return valueToBusValueSceneInfo(value, payload, payload_length, datatype);
281 
282  // DPT 27.001 - 32 Bit Field
283  if (datatype.mainGroup == 27 && datatype.subGroup == 1 && !datatype.index)
284  return valueToBusValueUnsigned32(value, payload, payload_length, datatype);
285 
286  // DPT 28.* - Unicode String
287  if (datatype.mainGroup == 28 && datatype.subGroup == 1 && !datatype.index)
288  return valueToBusValueUnicode(value, payload, payload_length, datatype);
289 
290  // DPT 29.* - Signed 64 Bit Integer
291  if (datatype.mainGroup == 29 && datatype.subGroup >= 10 && datatype.subGroup <= 12 && !datatype.index)
292  return valueToBusValueSigned64(value, payload, payload_length, datatype);
293 
294  // DPT 219.* - Alarm Info
295  if (datatype.mainGroup == 219 && datatype.subGroup == 1 && datatype.index <= 10)
296  return valueToBusValueAlarmInfo(value, payload, payload_length, datatype);
297 
298  // DPT 221.* - Serial Number
299  if (datatype.mainGroup == 221 && datatype.subGroup == 1 && datatype.index <= 1)
300  return valueToBusValueSerialNumber(value, payload, payload_length, datatype);
301 
302  // DPT 217.* - Version
303  if (datatype.mainGroup == 217 && datatype.subGroup == 1 && datatype.index <= 2)
304  return valueToBusValueVersion(value, payload, payload_length, datatype);
305 
306  // DPT 225.001/225.002 - Scaling Speed and Scaling Step Time
307  if (datatype.mainGroup == 225 && datatype.subGroup >= 1 && datatype.subGroup <= 2 && datatype.index <= 1)
308  return valueToBusValueScaling(value, payload, payload_length, datatype);
309 
310  // DPT 225.003 - Next Tariff
311  if (datatype.mainGroup == 225 && datatype.subGroup == 3 && datatype.index <= 1)
312  return valueToBusValueTariff(value, payload, payload_length, datatype);
313 
314  // DPT 231.* - Locale
315  if (datatype.mainGroup == 231 && datatype.subGroup == 1 && datatype.index <= 1)
316  return valueToBusValueLocale(value, payload, payload_length, datatype);
317 
318  // DPT 232.600 - RGB
319  if (datatype.mainGroup == 232 && datatype.subGroup == 600 && !datatype.index)
320  return valueToBusValueRGB(value, payload, payload_length, datatype);
321 
322  // DPT 234.* - Language and Region
323  if (datatype.mainGroup == 234 && datatype.subGroup >= 1 && datatype.subGroup <= 2 && !datatype.index)
324  return valueToBusValueLocale(value, payload, payload_length, datatype);
325 
326  // DPT 235.* - Active Energy
327  if (datatype.mainGroup == 235 && datatype.subGroup == 1 && datatype.index <= 3)
328  return valueToBusValueActiveEnergy(value, payload, payload_length, datatype);
329 
330  // DPT 238.* - Scene Config
331  if (datatype.mainGroup == 238 && datatype.subGroup == 1 && datatype.index <= 2)
332  return valueToBusValueSceneConfig(value, payload, payload_length, datatype);
333 
334  // DPT 239.* - Flagged Scaling
335  if (datatype.mainGroup == 239 && datatype.subGroup == 1 && datatype.index <= 1)
336  return valueToBusValueFlaggedScaling(value, payload, payload_length, datatype);
337 
338  // DPT 251.600 - RGBW
339  if (datatype.mainGroup == 251 && datatype.subGroup == 600 && datatype.index <= 1)
340  return valueToBusValueRGBW(value, payload, payload_length, datatype);
341 
342  return false;
343 }
344 
345 bool busValueToBinary(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
346 {
347  ASSERT_PAYLOAD(1);
348  value = bitFromPayload(payload, 7);
349  return true;
350 }
351 
352 bool busValueToBinaryControl(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
353 {
354  ASSERT_PAYLOAD(1);
355  value = (uint8_t)(unsigned8FromPayload(payload, 0) & 0x03);
356  return true;
357 }
358 
359 bool busValueToStepControl(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
360 {
361  ASSERT_PAYLOAD(1);
362  value = (uint8_t)(unsigned8FromPayload(payload, 0) & 0x0F);
363  return true;
364 }
365 bool busValueToCharacter(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
366 {
367  ASSERT_PAYLOAD(1);
368  int8_t charValue = signed8FromPayload(payload, 0);
369 
370  if (datatype.subGroup == 1 && (charValue & 0x80))
371  return false;
372 
373  if (datatype.subGroup == 2)
374  {
375  value = (uint8_t)charValue;
376  return true;
377  }
378 
379  value = charValue;
380  return true;
381 }
382 
383 bool busValueToUnsigned8(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
384 {
385  ASSERT_PAYLOAD(1);
386 
387  switch (datatype.subGroup)
388  {
389  case 1:
390  value = (uint8_t)round(unsigned8FromPayload(payload, 0) * 100.0 / 255.0);
391  return true;
392 
393  case 3:
394  value = (uint8_t)round(unsigned8FromPayload(payload, 0) * 360.0 / 255.0);
395  return true;
396 
397  case 6:
398  {
399  uint8_t numValue = unsigned8FromPayload(payload, 0);
400 
401  if (numValue == 0xFF)
402  return false;
403 
404  value = numValue;
405  return true;
406  }
407  }
408 
409  value = unsigned8FromPayload(payload, 0);
410  return true;
411 }
412 
413 bool busValueToSigned8(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
414 {
415  ASSERT_PAYLOAD(1);
416  value = (uint8_t)(unsigned8FromPayload(payload, 0));
417  return true;
418 }
419 
420 bool busValueToStatusAndMode(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
421 {
422  ASSERT_PAYLOAD(1);
423 
424  if (datatype.index < 5)
425  {
426  value = bitFromPayload(payload, datatype.index);
427  return true;
428  }
429  else if (datatype.index == 5)
430  {
431  value = (uint8_t)(unsigned8FromPayload(payload, 0) & 0x07);
432  return true;
433  }
434 
435  return false;
436 }
437 
438 bool busValueToUnsigned16(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
439 {
440  ASSERT_PAYLOAD(2);
441  value = unsigned16FromPayload(payload, 0);
442  return true;
443 }
444 
445 bool busValueToTimePeriod(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
446 {
447  ASSERT_PAYLOAD(2);
448 
449  int64_t duration = unsigned16FromPayload(payload, 0);
450  value = duration;
451  return true;
452 }
453 
454 bool busValueToSigned16(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
455 {
456  ASSERT_PAYLOAD(2);
457 
458  if (datatype.subGroup == 10)
459  {
460  value = signed16FromPayload(payload, 0) / 100.0;
461  return true;
462  }
463 
464  value = signed16FromPayload(payload, 0);
465  return true;
466 }
467 
468 bool busValueToTimeDelta(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
469 {
470  ASSERT_PAYLOAD(2);
471 
472  int64_t duration = signed16FromPayload(payload, 0);
473  value = duration;
474  return true;
475 }
476 
477 bool busValueToFloat16(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
478 {
479  ASSERT_PAYLOAD(2);
480 
481  if (unsigned16FromPayload(payload, 0) == 0x7FFF)
482  return false;
483 
484  value = float16FromPayload(payload, 0);
485  return true;
486 }
487 
488 bool busValueToTime(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
489 {
490  ASSERT_PAYLOAD(3);
491 
492  switch (datatype.index)
493  {
494  case 0:
495  value = (uint8_t)((unsigned8FromPayload(payload, 0) >> 5) & 0x07);
496  return true;
497 
498  case 1:
499  {
500  unsigned char hours = unsigned8FromPayload(payload, 0) & 0x1F;
501  unsigned char weekDay = (unsigned8FromPayload(payload, 0) & 0xE0) >> 5;
502  unsigned char minutes = unsigned8FromPayload(payload, 1) & 0x3F;
503  unsigned char seconds = unsigned8FromPayload(payload, 2) & 0x3F;
504 
505  if (hours > 23 || minutes > 59 || seconds > 59)
506  return false;
507 
508  struct tm tmp;
509  memset(&tmp, 0, sizeof(tmp));
510  tmp.tm_hour = hours;
511  tmp.tm_wday = weekDay;
512  tmp.tm_min = minutes;
513  tmp.tm_sec = seconds;
514  value = tmp;
515  return true;
516  }
517  }
518 
519  return false;
520 }
521 
522 bool busValueToDate(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
523 {
524  ASSERT_PAYLOAD(3);
525  unsigned short year = unsigned8FromPayload(payload, 2) & 0x7F;
526  unsigned char month = unsigned8FromPayload(payload, 1) & 0x0F;
527  unsigned char day = unsigned8FromPayload(payload, 0) & 0x1F;
528 
529  if (year > 99 || month < 1 || month > 12 || day < 1)
530  return false;
531 
532  struct tm tmp;
533  memset(&tmp, 0, sizeof(tmp));
534  year += year >= 90 ? 1900 : 2000;
535  tmp.tm_mday = day;
536  tmp.tm_year = year;
537  tmp.tm_mon = month;
538  value = tmp;
539  return true;
540 }
541 
542 bool busValueToUnsigned32(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
543 {
544  ASSERT_PAYLOAD(4);
545  value = unsigned32FromPayload(payload, 0);
546  return true;
547 }
548 
549 bool busValueToSigned32(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
550 {
551  ASSERT_PAYLOAD(4);
552  value = signed32FromPayload(payload, 0);
553  return true;
554 }
555 
556 bool busValueToLongTimePeriod(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
557 {
558  ASSERT_PAYLOAD(4);
559  value = signed32FromPayload(payload, 0);
560  return true;
561 }
562 
563 bool busValueToFloat32(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
564 {
565  ASSERT_PAYLOAD(4);
566  value = float32FromPayload(payload, 0);
567  return true;
568 }
569 
570 bool busValueToAccess(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
571 {
572  ASSERT_PAYLOAD(4);
573 
574  switch (datatype.index)
575  {
576  case 0:
577  {
578  int32_t digits = 0;
579 
580  for (int n = 0, factor = 100000; n < 6; ++n, factor /= 10)
581  {
582  unsigned char digit = bcdFromPayload(payload, n);
583 
584  if (digit > 9)
585  return false;
586 
587  digits += digit * factor;
588  }
589 
590  value = digits;
591  return true;
592  }
593 
594  case 1:
595  case 2:
596  case 3:
597  case 4:
598  value = bitFromPayload(payload, 23 + datatype.index);
599  return true;
600 
601  case 5:
602  value = bcdFromPayload(payload, 7);
603  return true;
604  }
605 
606  return false;
607 }
608 
609 bool busValueToString(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
610 {
611  ASSERT_PAYLOAD(14);
612 
613  for (int n = 0; n < 14; ++n)
614  {
615  auto value = signed8FromPayload(payload, n);
616 
617  if (!datatype.subGroup && (value & 0x80))
618  return false;
619  }
620 
621  value = (const char*) payload;
622  return true;
623 }
624 
625 bool busValueToScene(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
626 {
627  ASSERT_PAYLOAD(1);
628  value = (uint8_t)(unsigned8FromPayload(payload, 0) & 0x3F);
629  return true;
630 }
631 
632 bool busValueToSceneControl(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
633 {
634  ASSERT_PAYLOAD(1);
635 
636  switch (datatype.index)
637  {
638  case 0:
639  {
640  value = bitFromPayload(payload, 0);
641  return true;
642  }
643 
644  case 1:
645  {
646  value = (uint8_t)(unsigned8FromPayload(payload, 0) & 0x3F);
647  return true;
648  }
649  }
650 
651  return false;
652 }
653 
654 bool busValueToSceneInfo(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
655 {
656  ASSERT_PAYLOAD(1);
657 
658  switch (datatype.index)
659  {
660  case 0:
661  {
662  value = bitFromPayload(payload, 1);
663  return true;
664  }
665 
666  case 1:
667  {
668  value = (uint8_t)(unsigned8FromPayload(payload, 0) & 0x3F);
669  return true;
670  }
671  }
672 
673  return false;
674 }
675 
676 bool busValueToSceneConfig(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
677 {
678  ASSERT_PAYLOAD(1);
679 
680  switch (datatype.index)
681  {
682  case 0:
683  {
684  value = (uint8_t)(unsigned8FromPayload(payload, 0) & 0x3F);
685  return true;
686  }
687 
688  case 1:
689  case 2:
690  {
691  value = bitFromPayload(payload, 2 - datatype.index);
692  return true;
693  }
694  }
695 
696  return false;
697 }
698 
699 bool busValueToDateTime(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
700 {
701  ASSERT_PAYLOAD(8);
702 
703  if (datatype.index == 3)
704  {
705  value = bitFromPayload(payload, 48);
706  return true;
707  }
708 
709  if (!bitFromPayload(payload, 48))
710  {
711  switch (datatype.index)
712  {
713  case 0:
714  {
715  if (bitFromPayload(payload, 51) || bitFromPayload(payload, 52))
716  return false;
717 
718  unsigned short year = unsigned8FromPayload(payload, 0) + 1900;
719  unsigned short month = unsigned8FromPayload(payload, 1) & 0x0F;
720  unsigned short day = unsigned8FromPayload(payload, 2) & 0x1F;
721  unsigned short hours = unsigned8FromPayload(payload, 3) & 0x1F;
722  unsigned short minutes = unsigned8FromPayload(payload, 4) & 0x3F;
723  unsigned short seconds = unsigned8FromPayload(payload, 5) & 0x3F;
724 
725  if ((month < 1 || month > 12 || day < 1))
726  return false;
727 
728  if ((hours > 24 || minutes > 59 || seconds > 59))
729  return false;
730 
731  struct tm tmp;
732  memset(&tmp, 0, sizeof(tmp));
733  tmp.tm_sec = seconds;
734  tmp.tm_min = minutes;
735  tmp.tm_hour = hours;
736  tmp.tm_mday = day;
737  tmp.tm_mon = month;
738  tmp.tm_year = year;
739  value = tmp;
740  return true;
741  }
742 
743  case 1:
744  {
745  if (bitFromPayload(payload, 53))
746  return false;
747 
748  value = (uint8_t)((unsigned8FromPayload(payload, 3) >> 5) & 0x07);
749  return true;
750  }
751 
752  case 2:
753  {
754  if (bitFromPayload(payload, 50))
755  return false;
756 
757  value = bitFromPayload(payload, 49);
758  return true;
759  }
760 
761  case 9:
762  {
763  value = bitFromPayload(payload, 55);
764  return true;
765  }
766 
767  case 10:
768  {
769  value = bitFromPayload(payload, 56);
770  return true;
771  }
772  }
773  }
774 
775  return false;
776 }
777 
778 bool busValueToUnicode(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
779 {
780  //TODO
781  return false;
782 }
783 
784 bool busValueToSigned64(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
785 {
786  ASSERT_PAYLOAD(8);
787  value = signed64FromPayload(payload, 0);
788  return true;
789 }
790 
791 bool busValueToAlarmInfo(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
792 {
793  ASSERT_PAYLOAD(6);
794 
795  switch (datatype.index)
796  {
797  case 1:
798  {
799  unsigned char prio = unsigned8FromPayload(payload, 1);
800 
801  if (prio > 3)
802  return false;
803 
804  value = prio;
805  return true;
806  }
807 
808  case 0:
809  case 2:
810  case 3:
811  value = unsigned8FromPayload(payload, datatype.index);
812  return true;
813 
814  case 4:
815  case 5:
816  case 6:
817  case 7:
818  value = bitFromPayload(payload, 43 - datatype.index);
819  return true;
820 
821  case 8:
822  case 9:
823  case 10:
824  value = bitFromPayload(payload, 55 - datatype.index);
825  return true;
826  }
827 
828  return false;
829 }
830 
831 bool busValueToSerialNumber(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
832 {
833  ASSERT_PAYLOAD(6);
834 
835  switch (datatype.index)
836  {
837  case 0:
838  value = unsigned16FromPayload(payload, 0);
839  return true;
840 
841  case 1:
842  value = unsigned32FromPayload(payload, 2);
843  return true;
844  }
845 
846  return false;
847 }
848 
849 bool busValueToVersion(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
850 {
851  ASSERT_PAYLOAD(2);
852 
853  switch (datatype.index)
854  {
855  case 0:
856  value = (uint8_t)((unsigned8FromPayload(payload, 0) >> 3) & 0x1F);
857  return true;
858 
859  case 1:
860  value = (uint16_t)((unsigned16FromPayload(payload, 0) >> 6) & 0x1F);
861  return true;
862 
863  case 2:
864  value = (uint8_t)(unsigned8FromPayload(payload, 1) & 0x3F);
865  return true;
866  }
867 
868  return false;
869 }
870 
871 bool busValueToScaling(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
872 {
873  ASSERT_PAYLOAD(3);
874 
875  switch (datatype.index)
876  {
877  case 0:
878  value = unsigned16FromPayload(payload, 0);
879  return true;
880 
881  case 1:
882  value = (uint8_t)(unsigned8FromPayload(payload, 2) * 100.0 / 255.0);
883  return true;
884  }
885 
886  return false;
887 }
888 
889 bool busValueToTariff(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
890 {
891  ASSERT_PAYLOAD(3);
892 
893  switch (datatype.index)
894  {
895  case 0:
896  value = unsigned16FromPayload(payload, 0);
897  return true;
898 
899  case 1:
900  {
901  uint8_t tariff = unsigned8FromPayload(payload, 2);
902 
903  if (tariff > 254)
904  return false;
905 
906  value = tariff;
907  return true;
908  }
909  }
910 
911  return false;
912 }
913 
914 bool busValueToLocale(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
915 {
916  ASSERT_PAYLOAD(datatype.mainGroup == 231 ? 4 : 2);
917 
918  if (!datatype.index || (datatype.mainGroup == 231 && datatype.index == 1))
919  {
920  char code[2];
921  code[0] = unsigned8FromPayload(payload, datatype.index * 2);
922  code[1] = unsigned8FromPayload(payload, datatype.index * 2 + 1);
923  value = code;
924  return true;
925  }
926 
927  return false;
928 }
929 
930 bool busValueToRGB(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
931 {
932  ASSERT_PAYLOAD(3);
933  uint32_t rgb = (unsigned16FromPayload(payload, 0) << 8) | unsigned8FromPayload(payload, 2);
934  value = rgb;
935  return true;
936 }
937 
938 bool busValueToRGBW(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
939 {
940  ASSERT_PAYLOAD(6);
941 
942  switch (datatype.index)
943  {
944  case 0: // The RGBW value
945  {
946  uint32_t rgbw = unsigned32FromPayload(payload, 0);
947  value = rgbw;
948  return true;
949  }
950  case 1: // The mask bits only
951  {
952  value = unsigned8FromPayload(payload, 5);
953  return true;
954  }
955  }
956 
957  return false;
958 }
959 
960 bool busValueToFlaggedScaling(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
961 {
962  ASSERT_PAYLOAD(2);
963 
964  switch (datatype.index)
965  {
966  case 0:
967  value = (uint8_t)(unsigned8FromPayload(payload, 0) * 100.0 / 255.0);
968  return true;
969 
970  case 1:
971  value = bitFromPayload(payload, 15);
972  return true;
973  }
974 
975  return false;
976 }
977 
978 bool busValueToActiveEnergy(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
979 {
980  ASSERT_PAYLOAD(6);
981 
982  switch (datatype.index)
983  {
984  case 0:
985  value = signed32FromPayload(payload, 0);
986  return true;
987 
988  case 1:
989  value = unsigned8FromPayload(payload, 4);
990  return true;
991 
992  case 2:
993  case 3:
994  value = bitFromPayload(payload, datatype.index + 44);
995  return true;
996  }
997 
998  return false;
999 }
1000 
1001 //-------------------------------------------------------------------------------------------------------------------------------------
1002 
1003 bool valueToBusValueBinary(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1004 {
1005  bitToPayload(payload, payload_length, 7, value);
1006  return true;
1007 }
1008 
1009 bool valueToBusValueBinaryControl(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1010 {
1011  unsigned8ToPayload(payload, payload_length, 0, (uint64_t)value, 0x03);
1012  return true;
1013 }
1014 
1015 bool valueToBusValueStepControl(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1016 {
1017  unsigned8ToPayload(payload, payload_length, 0, (uint64_t)value, 0x0F);
1018  return true;
1019 }
1020 
1021 bool valueToBusValueCharacter(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1022 {
1023  if ((uint64_t)value > INT64_C(255) || (datatype.subGroup == 1 && (uint64_t)value > INT64_C(127)))
1024  return false;
1025 
1026  unsigned8ToPayload(payload, payload_length, 0, (uint64_t)value, 0xFF);
1027  return true;
1028 }
1029 
1030 bool valueToBusValueUnsigned8(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1031 {
1032  if ((int64_t)value < INT64_C(0))
1033  return false;
1034 
1035  switch (datatype.subGroup)
1036  {
1037  case 1:
1038  {
1039  if ((double)value > 100.0)
1040  return false;
1041 
1042  unsigned8ToPayload(payload, payload_length, 0, round((double)value * 255.0 / 100.0), 0xFF);
1043  break;
1044  }
1045 
1046  case 3:
1047  {
1048  if ((double)value > 360.0)
1049  return false;
1050 
1051  unsigned8ToPayload(payload, payload_length, 0, round((double)value * 255.0 / 360.0), 0xFF);
1052  break;
1053  }
1054 
1055  case 6:
1056  {
1057  if ((int64_t)value > INT64_C(254))
1058  return false;
1059 
1060  unsigned8ToPayload(payload, payload_length, 0, (uint64_t)value, 0xFF);
1061  break;
1062  }
1063 
1064  default:
1065  {
1066  if ((int64_t)value > INT64_C(255))
1067  return false;
1068 
1069  unsigned8ToPayload(payload, payload_length, 0, (uint64_t)value, 0xFF);
1070  }
1071  }
1072 
1073  return true;
1074 }
1075 
1076 bool valueToBusValueSigned8(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1077 {
1078  if ((int64_t)value < INT64_C(-128) || (int64_t)value > INT64_C(127))
1079  return false;
1080 
1081  signed8ToPayload(payload, payload_length, 0, (uint64_t)value, 0xFF);
1082  return true;
1083 }
1084 
1085 bool valueToBusValueStatusAndMode(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1086 {
1087  if (datatype.index < 5)
1088  bitToPayload(payload, payload_length, datatype.index, value);
1089  else if (datatype.index == 5)
1090  {
1091  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(7))
1092  return false;
1093 
1094  unsigned8ToPayload(payload, payload_length, 0, (uint64_t)value, 0x07);
1095  }
1096  else
1097  return false;
1098 
1099  return true;
1100 }
1101 
1102 bool valueToBusValueUnsigned16(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1103 {
1104  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(65535))
1105  return false;
1106 
1107  unsigned16ToPayload(payload, payload_length, 0, (uint64_t)value, 0xFFFF);
1108  return true;
1109 }
1110 
1111 bool valueToBusValueTimePeriod(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1112 {
1113  struct tm tmp = value;
1114  time_t timeSinceEpoch = mktime(&tmp);
1115 
1116  if (timeSinceEpoch < INT64_C(0) || timeSinceEpoch > INT64_C(65535))
1117  return false;
1118 
1119  unsigned16ToPayload(payload, payload_length, 0, timeSinceEpoch, 0xFFFF);
1120  return true;
1121 }
1122 
1123 bool valueToBusValueSigned16(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1124 {
1125  if ((int64_t)value < INT64_C(-32768) || (int64_t)value > INT64_C(32767))
1126  return false;
1127 
1128  if (datatype.subGroup == 10)
1129  {
1130  if ((double)value < -327.68 || (double)value > 327.67)
1131  return false;
1132 
1133  signed16ToPayload(payload, payload_length, 0, (int16_t)((double)value * 100.0), 0xFFFF);
1134  }
1135  else
1136  signed16ToPayload(payload, payload_length, 0, (uint64_t)value, 0xffff);
1137 
1138  return true;
1139 }
1140 
1141 bool valueToBusValueTimeDelta(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1142 {
1143  struct tm tmp = value;
1144  time_t timeSinceEpoch = mktime(&tmp);
1145 
1146  if (timeSinceEpoch < INT64_C(-32768) || timeSinceEpoch > INT64_C(32767))
1147  return false;
1148 
1149  signed16ToPayload(payload, payload_length, 0, timeSinceEpoch, 0xFFFF);
1150  return true;
1151 }
1152 
1153 bool valueToBusValueFloat16(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1154 {
1155  double numValue = value;
1156 
1157  // bigger values like 670760.0 result in 0x7FFF which denotes invalid data.
1158  // I'm not sure if the GO shouldn't be updated to this value instead
1159  if (numValue > 670433.28)
1160  return false;
1161 
1162  if (numValue < -671088.64)
1163  return false;
1164 
1165  switch (datatype.subGroup)
1166  {
1167  case 1:
1168  if (numValue < -273.0)
1169  return false;
1170 
1171  break;
1172 
1173  case 2:
1174  case 3:
1175  case 10:
1176  case 11:
1177  case 20:
1178  case 21:
1179  case 22:
1180  case 23:
1181  case 24:
1182  case 25:
1183  if (numValue < -670760.0)
1184  return false;
1185 
1186  break;
1187 
1188  case 4:
1189  case 5:
1190  case 6:
1191  case 7:
1192  case 8:
1193  case 28:
1194  if (numValue < 0.0)
1195  return false;
1196 
1197  break;
1198 
1199  case 27:
1200  if (numValue < -459.6)
1201  return false;
1202 
1203  break;
1204  }
1205 
1206  float16ToPayload(payload, payload_length, 0, numValue, 0xFFFF);
1207  return true;
1208 }
1209 
1210 bool valueToBusValueTime(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1211 {
1212  switch (datatype.index)
1213  {
1214  case 0:
1215  {
1216  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(7))
1217  return false;
1218 
1219  ENSURE_PAYLOAD(3);
1220  unsigned8ToPayload(payload, payload_length, 0, (uint64_t)value << 5, 0xE0);
1221  break;
1222  }
1223 
1224  case 1:
1225  {
1226  struct tm tmp = value;
1227  unsigned8ToPayload(payload, payload_length, 0, tmp.tm_hour, 0x1F);
1228  unsigned8ToPayload(payload, payload_length, 1, tmp.tm_min, 0x3F);
1229  unsigned8ToPayload(payload, payload_length, 2, tmp.tm_sec, 0x3F);
1230  break;
1231  }
1232 
1233  default:
1234  return false;
1235  }
1236 
1237  return true;
1238 }
1239 
1240 bool valueToBusValueDate(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1241 {
1242  struct tm tmp = value;
1243 
1244  if (tmp.tm_year < 1990 || tmp.tm_year > 2089)
1245  return false;
1246 
1247  unsigned8ToPayload(payload, payload_length, 0, tmp.tm_mday, 0x1F);
1248  unsigned8ToPayload(payload, payload_length, 1, tmp.tm_mon, 0x0F);
1249  unsigned8ToPayload(payload, payload_length, 2, tmp.tm_year % 100, 0x7F);
1250  return true;
1251 }
1252 
1253 bool valueToBusValueUnsigned32(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1254 {
1255  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(4294967295))
1256  return false;
1257 
1258  unsigned32ToPayload(payload, payload_length, 0, (uint64_t)value, 0xFFFFFFFF);
1259  return true;
1260 }
1261 
1262 bool valueToBusValueSigned32(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1263 {
1264  if ((int64_t)value < INT64_C(-2147483648) || (int64_t)value > INT64_C(2147483647))
1265  return false;
1266 
1267  signed32ToPayload(payload, payload_length, 0, (uint64_t)value, 0xFFFFFFFF);
1268  return true;
1269 }
1270 
1271 bool valueToBusValueLongTimePeriod(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1272 {
1273  if ((int64_t)value < INT64_C(-2147483648) || (int64_t)value > INT64_C(2147483647))
1274  return false;
1275 
1276  signed32ToPayload(payload, payload_length, 0, (uint64_t)value, 0xFFFFFFFF);
1277  return true;
1278 }
1279 
1280 bool valueToBusValueFloat32(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1281 {
1282  double numValue = value;
1283 
1284  if (numValue < (-8388608.0 * pow(2, 255)) || numValue > (8388607.0 * pow(2, 255)))
1285  return false;
1286 
1287  float32ToPayload(payload, payload_length, 0, numValue, 0xFFFFFFFF);
1288  return true;
1289 }
1290 
1291 bool valueToBusValueAccess(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1292 {
1293  switch (datatype.index)
1294  {
1295  case 0:
1296  {
1297  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(999999))
1298  return false;
1299 
1300  ENSURE_PAYLOAD(4);
1301 
1302  for (int n = 0, factor = 100000; n < 6; ++n, factor /= 10)
1303  bcdToPayload(payload, payload_length, n, ((uint64_t)value / factor) % 10);
1304 
1305  break;
1306  }
1307 
1308  case 1:
1309  case 2:
1310  case 3:
1311  case 4:
1312  bitToPayload(payload, payload_length, 23 + datatype.index, value);
1313  break;
1314 
1315  case 5:
1316  {
1317  if ((uint64_t)value > INT64_C(15))
1318  return false;
1319 
1320  bcdToPayload(payload, payload_length, 7, (uint64_t)value);
1321  break;
1322  }
1323 
1324  default:
1325  return false;
1326  }
1327 
1328  return true;
1329 }
1330 
1331 bool valueToBusValueString(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1332 {
1333  const char* strValue = value;
1334  uint8_t val = strValue[0];
1335 
1336  for (int n = 0; n < 14; n++)
1337  {
1338  if (val)
1339  val = strValue[n]; //string terminator 0x00 will stop further assignments and init the remainig payload with zero
1340 
1341  unsigned8ToPayload(payload, payload_length, n, val, 0xff);
1342  }
1343 
1344  return true;
1345 }
1346 
1347 bool valueToBusValueScene(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1348 {
1349  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(63))
1350  return false;
1351 
1352  unsigned8ToPayload(payload, payload_length, 0, (uint64_t)value, 0xFF);
1353  return true;
1354 }
1355 
1356 bool valueToBusValueSceneControl(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1357 {
1358  switch (datatype.index)
1359  {
1360  case 0:
1361  bitToPayload(payload, payload_length, 0, value);
1362  break;
1363 
1364  case 1:
1365  {
1366  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(63))
1367  return false;
1368 
1369  unsigned8ToPayload(payload, payload_length, 0, (int64_t)value, 0x3F);
1370  break;
1371  }
1372 
1373  default:
1374  return false;
1375  }
1376 
1377  return true;
1378 }
1379 
1380 bool valueToBusValueSceneInfo(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1381 {
1382  switch (datatype.index)
1383  {
1384  case 0:
1385  bitToPayload(payload, payload_length, 1, value);
1386  break;
1387 
1388  case 1:
1389  {
1390  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(63))
1391  return false;
1392 
1393  unsigned8ToPayload(payload, payload_length, 0, (int64_t)value, 0x3F);
1394  break;
1395  }
1396 
1397  default:
1398  return false;
1399  }
1400 
1401  return true;
1402 }
1403 
1404 bool valueToBusValueSceneConfig(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1405 {
1406  switch (datatype.index)
1407  {
1408  case 0:
1409  {
1410  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(63))
1411  return false;
1412 
1413  unsigned8ToPayload(payload, payload_length, 0, (int64_t)value, 0x3F);
1414  break;
1415  }
1416 
1417  case 1:
1418  case 2:
1419  bitToPayload(payload, payload_length, 2 - datatype.index, value);
1420  break;
1421 
1422  default:
1423  return false;
1424  }
1425 
1426  return true;
1427 }
1428 
1429 bool valueToBusValueDateTime(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1430 {
1431  switch (datatype.index)
1432  {
1433  case 0:
1434  {
1435  struct tm local = value;
1436  time_t time = mktime(&local);
1437 
1438  if (!time) //TODO add check if date or time is invalid
1439  return false;
1440 
1441  ENSURE_PAYLOAD(8);
1442  struct tm tmp = value;
1443  bitToPayload(payload, payload_length, 51, false);
1444  bitToPayload(payload, payload_length, 52, false);
1445  unsigned8ToPayload(payload, payload_length, 0, tmp.tm_year - 1900, 0xFF);
1446  unsigned8ToPayload(payload, payload_length, 1, tmp.tm_mon, 0x0F);
1447  unsigned8ToPayload(payload, payload_length, 2, tmp.tm_mday, 0x1F);
1448 
1449  bitToPayload(payload, payload_length, 54, false);
1450  unsigned8ToPayload(payload, payload_length, 3, tmp.tm_hour, 0x1F);
1451  unsigned8ToPayload(payload, payload_length, 4, tmp.tm_min, 0x3F);
1452  unsigned8ToPayload(payload, payload_length, 5, tmp.tm_sec, 0x3F);
1453  break;
1454  }
1455 
1456  case 1:
1457  {
1458  ENSURE_PAYLOAD(8);
1459 
1460  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(7))
1461  bitToPayload(payload, payload_length, 53, true);
1462  else
1463  {
1464  bitToPayload(payload, payload_length, 53, false);
1465  unsigned8ToPayload(payload, payload_length, 3, (int64_t)value << 5, 0xE0);
1466  }
1467 
1468  break;
1469  }
1470 
1471  case 2:
1472  {
1473  ENSURE_PAYLOAD(8);
1474  bitToPayload(payload, payload_length, 49, value);
1475  bitToPayload(payload, payload_length, 50, false);
1476  break;
1477  }
1478 
1479  case 3:
1480  {
1481  ENSURE_PAYLOAD(8);
1482  bitToPayload(payload, payload_length, 48, value);
1483  break;
1484  }
1485 
1486  case 9:
1487  {
1488  ENSURE_PAYLOAD(8);
1489  bitToPayload(payload, payload_length, 55, value);
1490  break;
1491  }
1492 
1493  case 10:
1494  {
1495  bitToPayload(payload, payload_length, 56, value);
1496  break;
1497  }
1498 
1499  default:
1500  return false;
1501  }
1502 
1503  return true;
1504 }
1505 
1506 bool valueToBusValueUnicode(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1507 {
1508  //TODO
1509  return false;
1510 }
1511 
1512 bool valueToBusValueSigned64(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1513 {
1514  signed64ToPayload(payload, payload_length, 0, (int64_t)value, UINT64_C(0xFFFFFFFFFFFFFFFF));
1515  return true;
1516 }
1517 
1518 bool valueToBusValueAlarmInfo(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1519 {
1520  switch (datatype.index)
1521  {
1522  case 1:
1523  {
1524  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(3))
1525  return false;
1526 
1527  ENSURE_PAYLOAD(6);
1528  unsigned8ToPayload(payload, payload_length, 1, (int64_t)value, 0xFF);
1529  break;
1530  }
1531 
1532  case 0:
1533  case 2:
1534  case 3:
1535  {
1536  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(255))
1537  return false;
1538 
1539  ENSURE_PAYLOAD(6);
1540  unsigned8ToPayload(payload, payload_length, datatype.index, (int64_t)value, 0xFF);
1541  break;
1542  }
1543 
1544  case 4:
1545  case 5:
1546  case 6:
1547  case 7:
1548  {
1549  ENSURE_PAYLOAD(6);
1550  bitToPayload(payload, payload_length, 43 - datatype.index, value);
1551  break;
1552  }
1553 
1554  case 8:
1555  case 9:
1556  case 10:
1557  {
1558  ENSURE_PAYLOAD(6);
1559  bitToPayload(payload, payload_length, 55 - datatype.index, value);
1560  break;
1561  }
1562 
1563  default:
1564  return false;
1565  }
1566 
1567  return true;
1568 }
1569 
1570 bool valueToBusValueSerialNumber(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1571 {
1572  switch (datatype.index)
1573  {
1574  case 0:
1575  {
1576  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(65535))
1577  return false;
1578 
1579  ENSURE_PAYLOAD(6);
1580  unsigned16ToPayload(payload, payload_length, 0, (int64_t)value, 0xFFFF);
1581  break;
1582  }
1583 
1584  case 1:
1585  {
1586  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(4294967295))
1587  return false;
1588 
1589  ENSURE_PAYLOAD(6);
1590  unsigned32ToPayload(payload, payload_length, 2, (int64_t)value, 0xFFFF);
1591  break;
1592  }
1593 
1594  default:
1595  return false;
1596  }
1597 
1598  return true;
1599 }
1600 
1601 bool valueToBusValueVersion(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1602 {
1603  switch (datatype.index)
1604  {
1605  case 0:
1606  {
1607  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(31))
1608  return false;
1609 
1610  ENSURE_PAYLOAD(2);
1611  unsigned8ToPayload(payload, payload_length, 0, (int64_t)value << 3, 0xF8);
1612  break;
1613  }
1614 
1615  case 1:
1616  {
1617  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(31))
1618  return false;
1619 
1620  unsigned16ToPayload(payload, payload_length, 0, (int64_t)value << 6, 0x07C0);
1621  break;
1622  }
1623 
1624  case 2:
1625  {
1626  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(63))
1627  return false;
1628 
1629  unsigned8ToPayload(payload, payload_length, 1, (int64_t)value, 0x3F);
1630  break;
1631  }
1632 
1633  default:
1634  return false;
1635  }
1636 
1637  return true;
1638 }
1639 
1640 bool valueToBusValueScaling(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1641 {
1642  switch (datatype.index)
1643  {
1644  case 0:
1645  {
1646  uint32_t duration = value;
1647 
1648  if (duration > INT64_C(65535))
1649  return false;
1650 
1651  ENSURE_PAYLOAD(3);
1652  unsigned16ToPayload(payload, payload_length, 0, duration, 0xFFFF);
1653  return true;
1654  }
1655 
1656  case 1:
1657  {
1658  if ((double)value < 0.0 || (double)value > 100.0)
1659  return false;
1660 
1661  unsigned8ToPayload(payload, payload_length, 2, round((double)value * 255.0 / 100.0), 0xff);
1662  break;
1663  }
1664  }
1665 
1666  return true;
1667 }
1668 
1669 bool valueToBusValueTariff(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1670 {
1671  switch (datatype.index)
1672  {
1673  case 0:
1674  {
1675  uint32_t duration = value;
1676 
1677  if (duration > INT64_C(65535))
1678  return false;
1679 
1680  ENSURE_PAYLOAD(3);
1681  unsigned16ToPayload(payload, payload_length, 0, duration, 0xFFFF);
1682  return true;
1683  }
1684 
1685  case 1:
1686  {
1687  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(254))
1688  return false;
1689 
1690  unsigned8ToPayload(payload, payload_length, 2, (int64_t)value, 0xff);
1691  break;
1692  }
1693  }
1694 
1695  return true;
1696 }
1697 
1698 bool valueToBusValueLocale(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1699 {
1700  int strl = strlen(value);
1701 
1702  if (strl != 2)
1703  return false;
1704 
1705  if (!datatype.index || (datatype.mainGroup == 231 && datatype.index == 1))
1706  {
1707  ENSURE_PAYLOAD(datatype.mainGroup == 231 ? 4 : 2);
1708  unsigned8ToPayload(payload, payload_length, datatype.index * 2, ((const char*)value)[0], 0xff);
1709  unsigned8ToPayload(payload, payload_length, datatype.index * 2 + 1, ((const char*)value)[1], 0xff);
1710  return true;
1711  }
1712 
1713  return false;
1714 }
1715 
1716 bool valueToBusValueRGB(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1717 {
1718  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(0xffffff))
1719  return false;
1720 
1721  unsigned int rgb = (int64_t)value;
1722 
1723  unsigned16ToPayload(payload, payload_length, 0, rgb >> 8, 0xffff);
1724  unsigned8ToPayload(payload, payload_length, 2, rgb & 0xff, 0xff);
1725  return true;
1726 }
1727 
1728 bool valueToBusValueRGBW(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1729 {
1730  switch (datatype.index)
1731  {
1732  case 0: // RGBW
1733  {
1734  uint32_t rgbw = (uint32_t)value;
1735  unsigned32ToPayload(payload, payload_length, 0, rgbw, 0xffffffff); // RGBW
1736  break;
1737  }
1738  case 1: // Mask bits
1739  {
1740  unsigned8ToPayload(payload, payload_length, 5, (uint8_t)value, 0x0f);
1741  break;
1742  }
1743  }
1744 
1745  return true;
1746 }
1747 
1748 bool valueToBusValueFlaggedScaling(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1749 {
1750  switch (datatype.index)
1751  {
1752  case 0:
1753  {
1754  if ((double)value < 0.0 || (double)value > 100.0)
1755  return false;
1756 
1757  ENSURE_PAYLOAD(2);
1758  unsigned8ToPayload(payload, payload_length, 0, round((double)value * 255.0 / 100.0), 0xff);
1759  break;
1760  }
1761 
1762  case 1:
1763  bitToPayload(payload, payload_length, 15, value);
1764  break;
1765 
1766  default:
1767  return false;
1768  }
1769 
1770  return true;
1771 }
1772 
1773 bool valueToBusValueActiveEnergy(const KNXValue& value, uint8_t* payload, size_t payload_length, const Dpt& datatype)
1774 {
1775  switch (datatype.index)
1776  {
1777  case 0:
1778  {
1779  if ((int64_t)value < INT64_C(-2147483648) || (int64_t)value > INT64_C(2147483647))
1780  return false;
1781 
1782  ENSURE_PAYLOAD(6);
1783  signed32ToPayload(payload, payload_length, 0, (int64_t)value, 0xffffffff);
1784  break;
1785  }
1786 
1787  case 1:
1788  {
1789  if ((int64_t)value < INT64_C(0) || (int64_t)value > INT64_C(254))
1790  return false;
1791 
1792  ENSURE_PAYLOAD(6);
1793  unsigned8ToPayload(payload, payload_length, 4, (int64_t)value, 0xff);
1794  break;
1795  }
1796 
1797  case 2:
1798  case 3:
1799  bitToPayload(payload, payload_length, datatype.index + 44, value);
1800  break;
1801 
1802  default:
1803  return false;
1804  }
1805 
1806  return true;
1807 }
1808 
1809 // Helper functions
1810 bool bitFromPayload(const uint8_t* payload, int index)
1811 {
1812  int bit = payload[index / 8] & (1 << (7 - (index % 8)));
1813  return bit ? true : false;
1814 }
1815 uint8_t unsigned8FromPayload(const uint8_t* payload, int index)
1816 {
1817  return (uint8_t)payload[index];
1818 }
1819 int8_t signed8FromPayload(const uint8_t* payload, int index)
1820 {
1821  return (int8_t)payload[index];
1822 }
1823 uint16_t unsigned16FromPayload(const uint8_t* payload, int index)
1824 {
1825  return ((((uint16_t)payload[index]) << 8) & 0xFF00) | (((uint16_t)payload[index + 1]) & 0x00FF);
1826 }
1827 int16_t signed16FromPayload(const uint8_t* payload, int index)
1828 {
1829  return ((((uint16_t)payload[index]) << 8) & 0xFF00) | (((uint16_t)payload[index + 1]) & 0x00FF);
1830 }
1831 uint32_t unsigned32FromPayload(const uint8_t* payload, int index)
1832 {
1833  return ((((uint32_t)payload[index]) << 24) & 0xFF000000) |
1834  ((((uint32_t)payload[index + 1]) << 16) & 0x00FF0000) |
1835  ((((uint32_t)payload[index + 2]) << 8) & 0x0000FF00) |
1836  (((uint32_t)payload[index + 3]) & 0x000000FF);
1837 }
1838 int32_t signed32FromPayload(const uint8_t* payload, int index)
1839 {
1840  return (int32_t)unsigned32FromPayload(payload, index);
1841 }
1842 uint64_t unsigned64FromPayload(const uint8_t* payload, int index)
1843 {
1844  return ((((uint64_t)payload[index]) << 56) & 0xFF00000000000000) |
1845  ((((uint64_t)payload[index + 1]) << 48) & 0x00FF000000000000) |
1846  ((((uint64_t)payload[index + 2]) << 40) & 0x0000FF0000000000) |
1847  ((((uint64_t)payload[index + 3]) << 32) & 0x000000FF00000000) |
1848  ((((uint64_t)payload[index + 4]) << 24) & 0x00000000FF000000) |
1849  ((((uint64_t)payload[index + 5]) << 16) & 0x0000000000FF0000) |
1850  ((((uint64_t)payload[index + 6]) << 8) & 0x000000000000FF00) |
1851  (((uint64_t)payload[index + 7]) & 0x00000000000000FF);
1852 }
1853 double float16FromPayload(const uint8_t* payload, int index)
1854 {
1855  uint16_t mantissa = unsigned16FromPayload(payload, index) & 0x87FF;
1856 
1857  if (mantissa & 0x8000)
1858  return ((~mantissa & 0x07FF) + 1.0) * -0.01 * (1 << ((payload[index] >> 3) & 0x0F));
1859 
1860  return mantissa * 0.01 * (1 << ((payload[index] >> 3) & 0x0F));
1861 }
1862 float float32FromPayload(const uint8_t* payload, int index)
1863 {
1864  union
1865  {
1866  float f;
1867  uint32_t i;
1868  } area;
1869  area.i = unsigned32FromPayload(payload, index);
1870  return area.f;
1871 }
1872 double float64FromPayload(const uint8_t* payload, int index)
1873 {
1874  union
1875  {
1876  double f;
1877  uint64_t i;
1878  } area;
1879  area.i = unsigned64FromPayload(payload, index);
1880  return area.f;
1881 }
1882 int64_t signed64FromPayload(const uint8_t* payload, int index)
1883 {
1884  return ((((uint64_t)payload[index]) << 56) & UINT64_C(0xFF00000000000000)) |
1885  ((((uint64_t)payload[index + 1]) << 48) & UINT64_C(0x00FF000000000000)) |
1886  ((((uint64_t)payload[index + 2]) << 40) & UINT64_C(0x0000FF0000000000)) |
1887  ((((uint64_t)payload[index + 3]) << 32) & UINT64_C(0x000000FF00000000)) |
1888  ((((uint64_t)payload[index + 4]) << 24) & UINT64_C(0x00000000FF000000)) |
1889  ((((uint64_t)payload[index + 5]) << 16) & UINT64_C(0x0000000000FF0000)) |
1890  ((((uint64_t)payload[index + 6]) << 8) & UINT64_C(0x000000000000FF00)) |
1891  (((uint64_t)payload[index + 7]) & UINT64_C(0x00000000000000FF));
1892 }
1893 uint8_t bcdFromPayload(const uint8_t* payload, int index)
1894 {
1895  if (index % 2)
1896  return (uint8_t)(payload[index / 2] & 0x0F);
1897 
1898  return (uint8_t)((payload[index / 2] >> 4) & 0x0F);
1899 }
1900 
1901 void bitToPayload(uint8_t* payload, size_t payload_length, int index, bool value)
1902 {
1903  ENSURE_PAYLOAD(index / 8 + 1);
1904  payload[index / 8] = (payload[index / 8] & ~(1 << (7 - (index % 8)))) | (value ? (1 << (7 - (index % 8))) : 0);
1905 }
1906 void unsigned8ToPayload(uint8_t* payload, size_t payload_length, int index, uint8_t value, uint8_t mask)
1907 {
1908  ENSURE_PAYLOAD(index + 1);
1909  payload[index] = (payload[index] & ~mask) | (value & mask);
1910 }
1911 void signed8ToPayload(uint8_t* payload, size_t payload_length, int index, int8_t value, uint8_t mask)
1912 {
1913  ENSURE_PAYLOAD(index + 1);
1914  payload[index] = (payload[index] & ~mask) | (value & mask);
1915 }
1916 void unsigned16ToPayload(uint8_t* payload, size_t payload_length, int index, uint16_t value, uint16_t mask)
1917 {
1918  ENSURE_PAYLOAD(index + 2);
1919  payload[index] = (payload[index] & (~mask >> 8)) | ((value >> 8) & (mask >> 8));
1920  payload[index + 1] = (payload[index + 1] & ~mask) | (value & mask);
1921 }
1922 void signed16ToPayload(uint8_t* payload, size_t payload_length, int index, int16_t value, uint16_t mask)
1923 {
1924  ENSURE_PAYLOAD(index + 2);
1925  payload[index] = (payload[index] & (~mask >> 8)) | ((value >> 8) & (mask >> 8));
1926  payload[index + 1] = (payload[index + 1] & ~mask) | (value & mask);
1927 }
1928 void unsigned32ToPayload(uint8_t* payload, size_t payload_length, int index, uint32_t value, uint32_t mask)
1929 {
1930  ENSURE_PAYLOAD(index + 4);
1931  payload[index] = (payload[index] & (~mask >> 24)) | ((value >> 24) & (mask >> 24));
1932  payload[index + 1] = (payload[index + 1] & (~mask >> 16)) | ((value >> 16) & (mask >> 16));
1933  payload[index + 2] = (payload[index + 2] & (~mask >> 8)) | ((value >> 8) & (mask >> 8));
1934  payload[index + 3] = (payload[index + 3] & ~mask) | (value & mask);
1935 }
1936 void signed32ToPayload(uint8_t* payload, size_t payload_length, int index, int32_t value, uint32_t mask)
1937 {
1938  ENSURE_PAYLOAD(index + 4);
1939  payload[index] = (payload[index] & (~mask >> 24)) | ((value >> 24) & (mask >> 24));
1940  payload[index + 1] = (payload[index + 1] & (~mask >> 16)) | ((value >> 16) & (mask >> 16));
1941  payload[index + 2] = (payload[index + 2] & (~mask >> 8)) | ((value >> 8) & (mask >> 8));
1942  payload[index + 3] = (payload[index + 3] & ~mask) | (value & mask);
1943 }
1944 
1945 void float16ToPayload(uint8_t* payload, size_t payload_length, int index, double value, uint16_t mask)
1946 {
1947  bool wasNegative = false;
1948 
1949  if (value < 0)
1950  {
1951  wasNegative = true;
1952  value *= -1;
1953  }
1954 
1955  value *= 100.0;
1956  unsigned short exponent = 0;
1957 
1958  if (value > 2048)
1959  exponent = ceil(log2(value) - 11.0);
1960 
1961  short mantissa = roundf(value / (1 << exponent));
1962 
1963  // above calculation causes mantissa overflow for values of the form 2^n, where n>11
1964  if (mantissa >= 0x800)
1965  {
1966  exponent++;
1967  mantissa = roundf(value / (1 << exponent));
1968  }
1969 
1970  if (wasNegative)
1971  mantissa *= -1;
1972 
1973  // println(mantissa);
1974 
1975  signed16ToPayload(payload, payload_length, index, mantissa, mask);
1976  unsigned8ToPayload(payload, payload_length, index, exponent << 3, 0x78 & (mask >> 8));
1977 }
1978 void float32ToPayload(uint8_t* payload, size_t payload_length, int index, double value, uint32_t mask)
1979 {
1980  union
1981  {
1982  float f;
1983  uint32_t i;
1984  } num;
1985  num.f = value;
1986  unsigned32ToPayload(payload, payload_length, index, num.i, mask);
1987 }
1988 void signed64ToPayload(uint8_t* payload, size_t payload_length, int index, int64_t value, uint64_t mask)
1989 {
1990  ENSURE_PAYLOAD(index + 8);
1991  payload[index] = (payload[index] & (~mask >> 56)) | ((value >> 56) & (mask >> 56));
1992  payload[index + 1] = (payload[index + 1] & (~mask >> 48)) | ((value >> 48) & (mask >> 48));
1993  payload[index + 2] = (payload[index + 2] & (~mask >> 40)) | ((value >> 40) & (mask >> 40));
1994  payload[index + 3] = (payload[index + 3] & (~mask >> 32)) | ((value >> 32) & (mask >> 32));
1995  payload[index + 4] = (payload[index + 4] & (~mask >> 24)) | ((value >> 24) & (mask >> 24));
1996  payload[index + 5] = (payload[index + 5] & (~mask >> 16)) | ((value >> 16) & (mask >> 16));
1997  payload[index + 6] = (payload[index + 6] & (~mask >> 8)) | ((value >> 8) & (mask >> 8));
1998  payload[index + 7] = (payload[index + 7] & ~mask) | (value & mask);
1999 }
2000 void bcdToPayload(uint8_t* payload, size_t payload_length, int index, uint8_t value)
2001 {
2002  ENSURE_PAYLOAD(index / 2 + 1);
2003 
2004  if (index % 2)
2005  payload[index / 2] = (payload[index / 2] & 0xF0) | (value & 0x0F);
2006  else
2007  payload[index / 2] = (payload[index / 2] & 0x0F) | ((value << 4) & 0xF0);
2008 }
Definition: dpt.h:364
unsigned short mainGroup
Definition: dpt.h:368
unsigned short index
Definition: dpt.h:370
unsigned short subGroup
Definition: dpt.h:369
bool valueToBusValueRGB(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueStepControl(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool busValueToUnicode(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:778
bool valueToBusValueBinary(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
uint32_t unsigned32FromPayload(const uint8_t *payload, int index)
bool busValueToDate(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:522
bool valueToBusValueScene(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueLongTimePeriod(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
int32_t signed32FromPayload(const uint8_t *payload, int index)
bool valueToBusValueUnsigned16(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueActiveEnergy(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueScaling(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
double float64FromPayload(const uint8_t *payload, int index)
bool busValueToAlarmInfo(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:791
bool busValueToAccess(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:570
bool busValueToVersion(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:849
bool busValueToUnsigned32(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:542
bool busValueToUnsigned16(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:438
bool busValueToLongTimePeriod(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:556
bool valueToBusValueTime(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool busValueToSigned16(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:454
bool valueToBusValueRGBW(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool busValueToTimePeriod(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:445
bool busValueToBinaryControl(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:352
uint16_t unsigned16FromPayload(const uint8_t *payload, int index)
bool busValueToSigned32(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:549
bool busValueToRGB(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:930
bool busValueToBinary(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:345
bool busValueToDateTime(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:699
bool busValueToSceneInfo(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:654
bool valueToBusValueUnicode(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueTimeDelta(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool busValueToSigned64(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:784
bool busValueToSceneConfig(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:676
bool valueToBusValueDateTime(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool busValueToFlaggedScaling(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:960
bool busValueToSigned8(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:413
bool valueToBusValueTariff(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
void float32ToPayload(uint8_t *payload, size_t payload_length, int index, double value, uint32_t mask)
bool busValueToStepControl(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:359
bool valueToBusValueLocale(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueFloat16(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool busValueToScaling(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:871
bool busValueToSerialNumber(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:831
int64_t signed64FromPayload(const uint8_t *payload, int index)
bool busValueToActiveEnergy(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:978
uint8_t unsigned8FromPayload(const uint8_t *payload, int index)
void signed64ToPayload(uint8_t *payload, size_t payload_length, int index, int64_t value, uint64_t mask)
bool valueToBusValueFlaggedScaling(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueSceneControl(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueAlarmInfo(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
uint8_t bcdFromPayload(const uint8_t *payload, int index)
bool valueToBusValueSerialNumber(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
void unsigned8ToPayload(uint8_t *payload, size_t payload_length, int index, uint8_t value, uint8_t mask)
double float16FromPayload(const uint8_t *payload, int index)
bool valueToBusValueSigned8(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
int16_t signed16FromPayload(const uint8_t *payload, int index)
bool busValueToFloat16(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:477
bool busValueToUnsigned8(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:383
float float32FromPayload(const uint8_t *payload, int index)
void bitToPayload(uint8_t *payload, size_t payload_length, int index, bool value)
bool valueToBusValueSceneConfig(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool bitFromPayload(const uint8_t *payload, int index)
bool busValueToTimeDelta(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:468
void unsigned32ToPayload(uint8_t *payload, size_t payload_length, int index, uint32_t value, uint32_t mask)
bool valueToBusValueSigned64(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
void float16ToPayload(uint8_t *payload, size_t payload_length, int index, double value, uint16_t mask)
void bcdToPayload(uint8_t *payload, size_t payload_length, int index, uint8_t value)
bool busValueToRGBW(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:938
bool valueToBusValueAccess(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueStatusAndMode(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueSigned16(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
int8_t signed8FromPayload(const uint8_t *payload, int index)
bool busValueToSceneControl(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:632
bool valueToBusValueSceneInfo(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueString(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueFloat32(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool busValueToCharacter(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:365
bool valueToBusValueSigned32(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool busValueToScene(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:625
uint64_t unsigned64FromPayload(const uint8_t *payload, int index)
bool busValueToString(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:609
bool busValueToLocale(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:914
void signed16ToPayload(uint8_t *payload, size_t payload_length, int index, int16_t value, uint16_t mask)
bool valueToBusValueBinaryControl(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueUnsigned8(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueTimePeriod(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool KNX_Encode_Value(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
Converts the KNXValue struct to the KNX Payload as the specific DPT.
Definition: dptconvert.cpp:181
void signed32ToPayload(uint8_t *payload, size_t payload_length, int index, int32_t value, uint32_t mask)
bool KNX_Decode_Value(uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Converts the KNX Payload given by the specific DPT and puts the value in the KNXValue struc.
Definition: dptconvert.cpp:13
bool busValueToStatusAndMode(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:420
bool valueToBusValueUnsigned32(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool busValueToFloat32(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:563
void unsigned16ToPayload(uint8_t *payload, size_t payload_length, int index, uint16_t value, uint16_t mask)
bool valueToBusValueCharacter(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueDate(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
bool valueToBusValueVersion(const KNXValue &value, uint8_t *payload, size_t payload_length, const Dpt &datatype)
void signed8ToPayload(uint8_t *payload, size_t payload_length, int index, int8_t value, uint8_t mask)
bool busValueToTariff(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:889
bool busValueToTime(const uint8_t *payload, size_t payload_length, const Dpt &datatype, KNXValue &value)
Definition: dptconvert.cpp:488