Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CONDITIONAL_REPORT in conjunction with setvaluedelta causes the value to never be transferred #434

Closed
MHofer opened this issue Oct 18, 2018 · 8 comments
Labels

Comments

@MHofer
Copy link

MHofer commented Oct 18, 2018

hi, excuse my english (google translation)
I have noticed that it is possible with only minimal changes of the value below the delta limit the value is never sent. an example: start value = 20 delta = 0.2 every 5 min it is checked whether the value is above 20.2 or below 19.8 and stored as _last_value, e.g. 20.15
at the next check the limits are 20,35 and 19,95, the value 20,30 is not sent again because under the limit, next run with the limits 20,50 and 20,10 is worth 20,45 and it will not work Posted
it goes on forever and nothing is ever sent

I have changed the child.cpp to the effect that the value _last_value is only set when it is sent, so it is always compared against the last reported value and an unnoticed drift is not possible

I hope my execution was understandable

// send the value back to the controller
void Child::sendValue(bool force) {
// do not send if no samples have been collected, unless instructed otherwise
if (! _send_without_value && _samples == 0) return;
#if NODEMANAGER_CONDITIONAL_REPORT == ON
// ignore conditional reporting settings if forced to report or if it is the first run
if (! force || ! _sensor->getFirstRun()) {
// if the value is a number
if (_format != STRING) {
// if below or above the thresholds, do not send the value
if (_value < _min_threshold || _value > _max_threshold) return;
// if the force update timer is over, send the value regardless and restart it
if (_force_update_timer->isOver()) _force_update_timer->start();
else {
// if the value does not differ enough from the previous one, do not send the value
if (_value > (_last_value - _value_delta) && _value < (_last_value + _value_delta)) {
return;
}
}
}
// if the value is a string
else {
// if a delta is configured, do not report if the string is the same as the previous one
if (_value_delta > 0 && strcmp(_value_string, _last_value_string) == 0) {
return;
}
}
}
// keep track of the previous value
// if (_format != STRING) _last_value = _value;
// else _last_value_string = _value_string;
#endif
// send the value to the gateway
if (_format == INT) nodeManager.sendMessage(_child_id,_type,(int)_value);
if (_format == FLOAT) nodeManager.sendMessage(_child_id,_type,(float)_value,_float_precision);
if (_format == DOUBLE) nodeManager.sendMessage(_child_id,_type,_value,_float_precision);
if (_format == STRING) nodeManager.sendMessage(_child_id,_type,_value_string);
// reset the counters
reset();
}

// reset the counters
void Child::reset() {
if (_format != STRING) {
if (_value_processing != NONE) {
if (_format != STRING) _last_value = _value;
else _last_value_string = _value_string;
// reset the counters
_total = 0;
_value = 0;
#if NODEMANAGER_EEPROM == ON
// if the value is supposed to be persisted in EEPROM, save it
if (_persist_value) saveValue();
#endif
}
} else _value_string = "";
_samples = 0;
}

@user2684
Copy link
Contributor

Hi, this behavior is there on purpose but I understand there can be situations when it is not meeting the requirements. Instead of changing the code, I'll try and see if I can add an option to customize the behavior if e.g. updating last value at every change or only when sending out the value. I'll keep you posted. Thanks!

@user2684 user2684 added bug and removed enhancement labels Oct 21, 2018
@Akubi
Copy link
Contributor

Akubi commented Nov 1, 2018

Hi,
Sorry but I don't agree. This problem was already fixed.

The actual version of Child.cpp only set _last_value = _value; just before sending the data.
All the function return conditions are now before the _last_value = _value;

Actual situation:

delta = 0.2
first value = 20.00 data sended, limit changed. Limits 19.80-20.20
new value = 20.15 data not sended, limits not changed. Limits 19.80-20.20
new value = 20.35 data sended, limits changed. Limits 20.15-20.55

Can you please explain ? Maby I don't see something but what ?

@user2684
Copy link
Contributor

user2684 commented Nov 3, 2018

@Akubi my understanding is that the request is about having an option to keep the behavior you have just described or alternatively with the limits updated even if no data is sent (just like before the fix) but keeping the current as the default. @MHofer is my understanding correct?

@Akubi
Copy link
Contributor

Akubi commented Nov 3, 2018

@user2684, ok I'm interested on the scenario. Not sure to understand the idea.

@user2684
Copy link
Contributor

user2684 commented Nov 3, 2018

I guess the idea behind the request is related to a scenario in which highlighting significant changes only and ignore little changes e.g. growing slowly but continuously. But I want to be sure this is really the scenario @MHofer had in mind before applying any change. Thanks!

@Akubi
Copy link
Contributor

Akubi commented Nov 3, 2018

@user2684, ok if my understanding is ok the scenario is:

If we have a stable or slow drifting value, we let the value drift and don't send any sample. We only send if we have a cosequent step. So a kind of discontinuity detection.

I'm right ?

Ok wait for @MHofer input.

@user2684
Copy link
Contributor

I understood something simpler than that. something like having the old implementation before your fix or the current. What you pointed out here is actually interesting and I'd keep track of it in a separate feature request for the next release since I guess could require a bit more coding but I like this discontinuity detection idea a lot

@user2684
Copy link
Contributor

I've added the following to Child in #438:

	// set when the last value is updated. Possible values are UPDATE_ALWAYS (at every cycle), UPDATE_ON_SEND (only after sending) (default: UPDATE_ON_SEND)
	void setUpdateLastValue(last_value_mode value);

This should open up the door to additional behaviors in the future like discontinuity detection (for which I've opened up #439

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants