ioBroker.js-controller icon indicating copy to clipboard operation
ioBroker.js-controller copied to clipboard

Implement "filter" for aliases

Open GermanBluefox opened this issue 4 years ago • 22 comments

Any ideas?

GermanBluefox avatar Nov 15 '19 14:11 GermanBluefox

Waht you exactly mean with "filter"?

Apollon77 avatar Nov 15 '19 14:11 Apollon77

Option 1: Use read/write function. If null is returned, the value will be ignored. Option 1.5 add filter flag for aliases and only if filter is true, null will be ignored. Option 2: implement filterRead and filterWrite options...

Normally the last valid value should be delivered....

GermanBluefox avatar Nov 15 '19 14:11 GermanBluefox

e.g. write: val < 10 ? null : val

GermanBluefox avatar Nov 15 '19 14:11 GermanBluefox

how about a property on the object with some predefined methods that can be used? e.g.

filter: "ifGreaterThanOrEqual(10)" // equivalent to val >= 10 ? val : null
filter: "ifLessThan(9)" // equivalent to val < 9 ? val : null
...

Thinking about it, I would probably call that option transform, so we could also do stuff like:

transform: "multiply(5)" // equivalent to val * 5
transform: "not()" // equivalent to !val

AlCalzone avatar Nov 15 '19 14:11 AlCalzone

how about a property on the object with some predefined methods that can be used? e.g.

filter: "ifGreaterThanOrEqual(10)" // equivalent to val >= 10 ? val : null
filter: "ifLessThan(9)" // equivalent to val < 9 ? val : null
...

Thinking about it, I would probably call that option transform, so we could also do stuff like:

transform: "multiply(5)" // equivalent to val * 5
transform: "not()" // equivalent to !val

transform, convert, converter ... This more accurately describes the action. I vote on "converter" :)

om2804 avatar Nov 15 '19 14:11 om2804

We have still a question, what the value will be returned on getState if filtered out?

GermanBluefox avatar Nov 15 '19 14:11 GermanBluefox

We have still a question, what the value will be returned on getState if filtered out?

If it's a converter. That obligation to return the value lies with the implementation of the converter. The converter always returns a value.

om2804 avatar Nov 15 '19 15:11 om2804

We have still a question, what the value will be returned on getState if filtered out?

If it's a converter. That obligation to return the value lies with the implementation of the converter. The converter always returns a value.

This functionality is implemented yet: https://www.iobroker.net/#en/documentation/dev/aliases.md

This issue is really about filtering functionality

GermanBluefox avatar Nov 15 '19 15:11 GermanBluefox

We have still a question, what the value will be returned on getState if filtered out?

Stays old value, just noch update :-) But this is nt working with the current alias concept :-(

Apollon77 avatar Nov 15 '19 15:11 Apollon77

This issue is really about filtering functionality

Ok, then ignore the 2nd half of my comment

AlCalzone avatar Nov 15 '19 15:11 AlCalzone

Filtering almost always assumes we know the current and previous value. Only in this case we can implement some simple filtering such as
FillLinear - get previous state FillAverage - calculate mean of previous and current etc... Everything we can do with only having current val is already implemented in read/write - I don't think we need to complicate things further here.

algar42 avatar Nov 16 '19 09:11 algar42

A little bit crazy idea... Can we check if one of the history adapter (history, influx, sql) is enabled at state level (btw, not only for aliases) and if so make getState/getStates return current state as usual and the last saved state from DB (or even N last saved states as an array)? e.g. { "val":false, "ack":false, "ts":1573896039569, "q":0, "from":"system.adapter.admin.0", "user":"system.user.admin", "lc":1573896039569, "oldStates":[ { "val":false, "ts":1234 }, { "val":true, "ts":1234 } ]} Request to get states from DB and how much to get can be passed to getState as options object (switched off by default). This will definitely extend the functionality and will make getState more flexible.

... and probably the same thing can be implemented in javaScript adapted. This will give users more control on their states and data, because it is sometimes really required to get previous value, but currently it is possible only thru subscription to state which is not always required.

algar42 avatar Nov 16 '19 09:11 algar42

We have getHistory function in JavaScript adapter for this.

Apollon77 avatar Nov 16 '19 10:11 Apollon77

Are there any use cases for this filter functionality? Why should I ignore a whole state change of the related state?

foxriver76 avatar Mar 22 '20 17:03 foxriver76

Some real world examples would be great yes ;-) I only can think of „sorting out invalid sensor responses“ ...

On „how“ I would go with „undefined“ as value because null is an allowed value for iobroker. Undefined is kind of not allowed as state value. So if script returns undefined as value it is handled as it would have not happened.

Apollon77 avatar Mar 22 '20 17:03 Apollon77

For this to work, we would need to create the alias as real state (write it in db) because when value is filtered out and now someone wants to get the value, we can not reconstruct it with the alias function, because it will only give us undefined.

IMHO it would be a nice thing for us as devs to write the alias as a real state, because it would make the alias concept more consistent to the existing states concept. E. g. we would not have to convert the alias state with the read function when someone wants to get the states value. Also we would not have to explicitly emit the alias state on state change because it would be done automatically on low level if its written to the db.

But I guess, that it has a reason, that we haven't done this until now. So will this procedure have any downsides @GermanBluefox?

foxriver76 avatar Mar 23 '20 21:03 foxriver76

One of the topics is that we would need to hold "n" real alias states in sync with the real value ... in any case - also in edge cases. We currently do not have "atomic" logic, everything is async. Also we would need to define "who" is doing this ... The writing instance/adapter/cli would need to make sure!?

Apollon77 avatar Mar 23 '20 21:03 Apollon77

The only possibility I see is to enhance the existing state object with its current alias state. Otherwise we cannot stay 100 % in sync, and we simply need to store the alias somwhere if we cannot get it's value by transforming the current state. Also ts and lc, ack etc. have to stay at the values of the last not filtered value.

foxriver76 avatar Oct 22 '20 13:10 foxriver76

You are completely right, I also see this as the only way. Beside other options where we would limit the usecases. But in fact exactly this was what @GermanBluefox wanted to avoid because in fact you never really hold that in sync in all cases

Apollon77 avatar Dec 06 '20 22:12 Apollon77

So here we should decide if we want aliases to be really stored instead of being just a transform function as it is currently. If we keep aliases as transformers, then we can close it as it is technically not possible.

foxriver76 avatar Jun 08 '22 09:06 foxriver76

Is there a way to have no value change of alias for specific values of source e.g. null An empty string value with this rule isn't a real solution val == null ? '' : val

Diginix avatar Aug 29 '23 13:08 Diginix

Is there a way to have no value change of alias for specific values of source e.g. null An empty string value with this rule isn't a real solution val == null ? '' : val

No, this is what this ticket is about

foxriver76 avatar Aug 29 '23 13:08 foxriver76