Skip to content

Commit 940f2df

Browse files
authored
Merge pull request #300 from cornelius-koepp/fix/group-object-setting-invalid-value--thelsing/master
Fix Sending Wrong Values on Failed Conversion to DPT
2 parents a30bbd0 + 73d4a6c commit 940f2df

2 files changed

Lines changed: 43 additions & 22 deletions

File tree

src/knx/group_object.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,15 @@ GroupObjectUpdatedHandler GroupObject::callback()
242242
}
243243
#endif
244244

245-
void GroupObject::value(const KNXValue& value, const Dpt& type)
245+
bool GroupObject::value(const KNXValue& value, const Dpt& type)
246246
{
247-
valueNoSend(value, type);
248-
objectWritten();
247+
if (valueNoSend(value, type))
248+
{
249+
// write on successful conversion/setting value only
250+
objectWritten();
251+
return true;
252+
}
253+
return false;
249254
}
250255

251256

@@ -280,9 +285,9 @@ bool GroupObject::tryValue(KNXValue& value)
280285
}
281286

282287

283-
void GroupObject::value(const KNXValue& value)
288+
bool GroupObject::value(const KNXValue& value)
284289
{
285-
this->value(value, _datapointType);
290+
return this->value(value, _datapointType);
286291
}
287292

288293

@@ -292,34 +297,42 @@ KNXValue GroupObject::value()
292297
}
293298

294299

295-
void GroupObject::valueNoSend(const KNXValue& value)
300+
bool GroupObject::valueNoSend(const KNXValue& value)
296301
{
297-
valueNoSend(value, _datapointType);
302+
return valueNoSend(value, _datapointType);
298303
}
299304
#endif
300305

301-
void GroupObject::valueNoSend(const KNXValue& value, const Dpt& type)
306+
bool GroupObject::valueNoSend(const KNXValue& value, const Dpt& type)
302307
{
303-
if (_uninitialized)
308+
const bool encodingDone = KNX_Encode_Value(value, _data, _dataLength, type);
309+
310+
// initialize on succesful conversion only
311+
if (encodingDone && _uninitialized)
304312
commFlag(Ok);
305313

306-
KNX_Encode_Value(value, _data, _dataLength, type);
314+
return encodingDone;
307315
}
308316

309317
bool GroupObject::valueNoSendCompare(const KNXValue& value, const Dpt& type)
310318
{
311319
if (_uninitialized)
312320
{
313321
// always set first value
314-
this->valueNoSend(value, type);
315-
return true;
322+
return valueNoSend(value, type);
316323
}
317324
else
318325
{
319-
// convert new value to given dtp
326+
// convert new value to given DPT
320327
uint8_t newData[_dataLength];
321328
memset(newData, 0, _dataLength);
322-
KNX_Encode_Value(value, newData, _dataLength, type);
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+
}
323336

324337
// check for change in converted value / update value on change only
325338
const bool dataChanged = memcmp(_data, newData, _dataLength);

src/knx/group_object.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,10 @@ class GroupObject
162162
* @param type the datapoint type used for the conversion.
163163
*
164164
* The parameters must fit the group object. Otherwise it will stay unchanged.
165+
*
166+
* @returns true if the value was converted successfully to the datapoint type and the group object was updated.
165167
*/
166-
void value(const KNXValue& value, const Dpt& type);
168+
bool value(const KNXValue& value, const Dpt& type);
167169

168170
/**
169171
* Check if the value (after conversion to dpt) will differ from current value of the group object and changes the state of the group object to ::WriteRequest if different.
@@ -173,18 +175,20 @@ class GroupObject
173175
*
174176
* The parameters must fit the group object. Otherwise it will stay unchanged.
175177
*
176-
* @returns true if the value of the group object has changed
178+
* @returns true if the value of the group object has changed, false if conversion results in same value as stored in group object or failed.
177179
*/
178180
bool valueCompare(const KNXValue& value, const Dpt& type);
179181

180182
/**
181-
* set the current value of the group object.
183+
* set the current value of the group objectand show success.
182184
* @param value the value the group object is set to
183185
* @param type the datapoint type used for the conversion.
184186
*
185187
* The parameters must fit the group object. Otherwise it will stay unchanged.
188+
*
189+
* @returns true if value was converted successfully to the datapoint type and the group object was updated.
186190
*/
187-
void valueNoSend(const KNXValue& value, const Dpt& type);
191+
bool valueNoSend(const KNXValue& value, const Dpt& type);
188192

189193
/**
190194
* Check if the value (after conversion to dpt) will differ from current value of the group object and update if necessary.
@@ -194,7 +198,7 @@ class GroupObject
194198
*
195199
* The parameters must fit the group object. Otherwise it will stay unchanged.
196200
*
197-
* @returns true if the value of the group object has changed
201+
* @returns true if the value of the group object has changed, false if conversion results in same value as stored in group object or failed.
198202
*/
199203
bool valueNoSendCompare(const KNXValue& value, const Dpt& type);
200204

@@ -220,15 +224,19 @@ class GroupObject
220224
* @param value the value the group object is set to
221225
*
222226
* The parameters must fit the group object and dhe datapoint type must be set with dataPointType(). Otherwise it will stay unchanged.
227+
*
228+
* @returns true if the value was converted successfully to the datapoint type and the group object was updated.
223229
*/
224-
void value(const KNXValue& value);
230+
bool value(const KNXValue& value);
225231
/**
226232
* set the current value of the group object.
227233
* @param value the value the group object is set to
228234
*
229-
* The parameters must fit the group object and dhe datapoint type must be set with dataPointType(). Otherwise it will stay unchanged.
235+
* The parameters must fit the group object and the datapoint type must be set with dataPointType(). Otherwise it will stay unchanged.
236+
*
237+
* @returns true if the value was converted successfully to the datapoint type and the group object was updated.
230238
*/
231-
void valueNoSend(const KNXValue& value);
239+
bool valueNoSend(const KNXValue& value);
232240
/**
233241
* set the current value of the group object.
234242
* @param value the value the group object is set to

0 commit comments

Comments
 (0)