ioBroker.js-controller
ioBroker.js-controller copied to clipboard
Implement "filter" for aliases
Any ideas?
Waht you exactly mean with "filter"?
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....
e.g. write: val < 10 ? null : val
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
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" :)
We have still a question, what the value will be returned on getState if filtered out?
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.
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
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 :-(
This issue is really about filtering functionality
Ok, then ignore the 2nd half of my comment
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.
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.
We have getHistory function in JavaScript adapter for this.
Are there any use cases for this filter functionality? Why should I ignore a whole state change of the related state?
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.
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?
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!?
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.
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
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.
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
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 solutionval == null ? '' : val
No, this is what this ticket is about