knx
ETS configurable knx-stack
group_object.cpp
Go to the documentation of this file.
1 #include "group_object.h"
2 #include "bits.h"
3 #include "string.h"
4 #include "datapoint_types.h"
6 
7 #ifdef SMALL_GROUPOBJECT
8  GroupObjectUpdatedHandler GroupObject::_updateHandlerStatic = 0;
9 #endif
10 GroupObjectTableObject* GroupObject::_table = 0;
11 
13 {
14  _data = 0;
15  _uninitialized = true;
16  _commFlag = Uninitialized;
17  _dataLength = 0;
18 #ifndef SMALL_GROUPOBJECT
19  _updateHandler = 0;
20 #endif
21 }
22 
24 {
25  if (_data)
26  delete[] _data;
27 }
28 
30 {
31  if (!_table)
32  return false;
33 
34  return bitRead(ntohs(_table->_tableData[_asap]), 15) > 0;
35 }
36 
38 {
39  if (!_table)
40  return false;
41 
42  return bitRead(ntohs(_table->_tableData[_asap]), 14) > 0 ;
43 }
44 
46 {
47  if (!_table)
48  return false;
49 
50  return bitRead(ntohs(_table->_tableData[_asap]), 13) > 0;
51 }
52 
54 {
55  if (!_table)
56  return false;
57 
58  return bitRead(ntohs(_table->_tableData[_asap]), 12) > 0 ;
59 }
60 
62 {
63  if (!_table)
64  return false;
65 
66  // we forbid reading of new (uninitialized) go
67  if (_uninitialized)
68  return false;
69 
70  return bitRead(ntohs(_table->_tableData[_asap]), 11) > 0;
71 }
72 
74 {
75  if (!_table)
76  return false;
77 
78  return bitRead(ntohs(_table->_tableData[_asap]), 10) > 0;
79 }
80 
81 
83 {
84  if (!_table)
85  return LowPriority;
86 
87  return (Priority)((ntohs(_table->_tableData[_asap]) >> 6) & (3 << 2)) ;
88 }
89 
91 {
92  return _data;
93 }
94 
96 {
97  return _asap;
98 }
99 
100 size_t GroupObject::goSize()
101 {
102  size_t size = sizeInTelegram();
103 
104  if (size == 0)
105  return 1;
106 
107  return size;
108 }
109 
110 // see knxspec 3.5.1 p. 178
111 size_t GroupObject::asapValueSize(uint8_t code) const
112 {
113  if (code < 7)
114  return 0;
115 
116  if (code < 8)
117  return 1;
118 
119  if (code < 11 || (code > 20 && code < 255))
120  return code - 6;
121 
122  switch (code)
123  {
124  case 11:
125  return 6;
126 
127  case 12:
128  return 8;
129 
130  case 13:
131  return 10;
132 
133  case 14:
134  return 14;
135 
136  case 15:
137  return 5;
138 
139  case 16:
140  return 7;
141 
142  case 17:
143  return 9;
144 
145  case 18:
146  return 11;
147 
148  case 19:
149  return 12;
150 
151  case 20:
152  return 13;
153 
154  case 255:
155  return 252;
156  }
157 
158  return -1;
159 }
160 
161 
163 {
164  return _commFlag;
165 }
166 
168 {
169  _commFlag = value;
170 
171  if (value == WriteRequest || value == Updated || value == Ok)
172  _uninitialized = false;
173 }
174 
176 {
177  return !_uninitialized;
178 }
179 
181 {
183 }
184 
186 {
188 }
189 
191 {
192  return _dataLength;
193 }
194 
196 {
197  uint8_t code = lowByte(ntohs(_table->_tableData[_asap]));
198  return asapValueSize(code);
199 }
200 
202 {
203  uint8_t code = lowByte(ntohs(_table->_tableData[_asap]));
204  size_t result = asapValueSize(code);
205 
206  if (result == 0)
207  return 1;
208 
209  if (code == 14)
210  return 14 + 1;
211 
212  return result;
213 }
214 
215 #ifdef SMALL_GROUPOBJECT
217 {
218  return _updateHandlerStatic;
219 }
220 
222 {
223  _updateHandlerStatic = handler;
224 }
225 
227 {
228  if (_updateHandlerStatic != 0)
229  _updateHandlerStatic(ko);
230 }
231 
232 #else
234 {
235  _updateHandler = handler;
236 }
237 
238 
240 {
241  return _updateHandler;
242 }
243 #endif
244 
245 bool GroupObject::value(const KNXValue& value, const Dpt& type)
246 {
247  if (valueNoSend(value, type))
248  {
249  // write on successful conversion/setting value only
250  objectWritten();
251  return true;
252  }
253  return false;
254 }
255 
256 
258 {
259  KNXValue value = "";
260  KNX_Decode_Value(_data, _dataLength, type, value);
261  return value;
262 }
263 
264 bool GroupObject::tryValue(KNXValue& value, const Dpt& type)
265 {
266  return KNX_Decode_Value(_data, _dataLength, type, value);
267 }
268 
269 #ifndef SMALL_GROUPOBJECT
271 {
272  _datapointType = value;
273 }
274 
275 
277 {
278  return _datapointType;
279 }
280 
281 
283 {
284  return tryValue(value, _datapointType);
285 }
286 
287 
288 bool GroupObject::value(const KNXValue& value)
289 {
290  return this->value(value, _datapointType);
291 }
292 
293 
295 {
296  return value(_datapointType);
297 }
298 
299 
301 {
302  return valueNoSend(value, _datapointType);
303 }
304 #endif
305 
306 bool GroupObject::valueNoSend(const KNXValue& value, const Dpt& type)
307 {
308  const bool encodingDone = KNX_Encode_Value(value, _data, _dataLength, type);
309 
310  // initialize on succesful conversion only
311  if (encodingDone && _uninitialized)
312  commFlag(Ok);
313 
314  return encodingDone;
315 }
316 
317 bool GroupObject::valueNoSendCompare(const KNXValue& value, const Dpt& type)
318 {
319  if (_uninitialized)
320  {
321  // always set first value
322  return valueNoSend(value, type);
323  }
324  else
325  {
326  // convert new value to given DPT
327  uint8_t newData[_dataLength];
328  memset(newData, 0, _dataLength);
329  const bool encodingDone = KNX_Encode_Value(value, newData, _dataLength, type);
330  if (!encodingDone)
331  {
332  // value conversion to DPT failed
333  // do NOT update the value of the KO!
334  return false;
335  }
336 
337  // check for change in converted value / update value on change only
338  const bool dataChanged = memcmp(_data, newData, _dataLength);
339 
340  if (dataChanged)
341  memcpy(_data, newData, _dataLength);
342 
343  return dataChanged;
344  }
345 }
346 
347 bool GroupObject::valueCompare(const KNXValue& value, const Dpt& type)
348 {
349  if (valueNoSendCompare(value, type))
350  {
351  objectWritten();
352  return true;
353  }
354 
355  return false;
356 }
Definition: dpt.h:364
This class represents a single group object.
Definition: group_object.h:42
bool writeEnable()
Check if the write flag (W) was set.
bool valueCompare(const KNXValue &value, const Dpt &type)
Check if the value (after conversion to dpt) will differ from current value of the group object and c...
GroupObjectUpdatedHandler callback()
returns the registered callback
uint16_t asap()
returns the Application Service Access Point of the group object.
bool responseUpdateEnable()
Check if the update flag (U) was set.
bool initialized()
Check if the group object contains a valid value assigned from bus or from application program.
virtual ~GroupObject()
The destructor.
size_t sizeInTelegram()
returns the size of the group object in Byte as it is in a telegram.
static void processClassCallback(GroupObject &ko)
static GroupObjectUpdatedHandler classCallback()
Alternative callback processing: register one global callback for all group object.
ComFlag commFlag()
Return the current state of the group object.
KNXValue value()
return the current value of the group object.
size_t sizeInMemory() const
returns the size of the group object in the heap memory of the group object.
bool transmitEnable()
Check if the transmit flag (T) was set.
GroupObject()
The constructor.
void objectWritten()
Mark a communication object as written.
uint8_t * valueRef()
returns the pointer to the value of the group object.
bool valueNoSendCompare(const KNXValue &value, const Dpt &type)
Check if the value (after conversion to dpt) will differ from current value of the group object and u...
void requestObjectRead()
Request the read of a communication object.
Priority priority()
Get the priority of the group object.
bool valueReadOnInit()
Check if the initialisation flag (I) was set.
bool communicationEnable()
Check if the communication flag (C) was set.
bool tryValue(KNXValue &value, const Dpt &type)
set the current value of the group object.
bool valueNoSend(const KNXValue &value, const Dpt &type)
set the current value of the group objectand show success.
size_t valueSize()
returns the size of the group object in Byte.
Dpt dataPointType()
returns the currently configured datapoint type.
bool readEnable()
Check if the read flag (R) was set.
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
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
ComFlag
Definition: group_object.h:11
@ Ok
read or write request were send successfully
Definition: group_object.h:16
@ ReadRequest
Read was requested but was not processed.
Definition: group_object.h:13
@ Updated
Group object was updated.
Definition: group_object.h:12
@ Uninitialized
uninitialized Group Object, its value is not valid
Definition: group_object.h:18
@ WriteRequest
Write was requested but was not processed.
Definition: group_object.h:14
std::function< void(GroupObject &)> GroupObjectUpdatedHandler
Definition: group_object.h:33
Priority
Definition: knx_types.h:10
@ LowPriority
Normal priority of group communication.
Definition: knx_types.h:11