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