openhab-core
openhab-core copied to clipboard
Add reject filter for websockets
I'd like to get all events except the ItemStateEvent (because with OH4 the ItemStateUpdateEvent is available).
Currently the websocket filter works like a whitelist which means I have to know all events and pass a list of them.
However I'd like to receive all events except the ItemStateEvent so it would be nice to specify an action in case of a filter match (e.g. "block" or "pass").
I agree this would be nice to have, but I am currently wondering how this block/pass parameter could be sent. We only have the payload available for sending this to keep compatibility with events in general ...
I don't understand what you are trying to say.
If you look at the docs the filter is created by sending a WebSocketEvent with a magic topic.
The easiest way is to add support for a new payload (I don't even think we need to keep the old one for backwards compatibility).
Instead of
["ItemStateUpdatedEvent", "ItemStateChangedEvent"]
it could be
{
"allow": ["ItemStateUpdatedEvent", "ItemStateChangedEvent"],
"reject": ["ItemStateEvent"]
}
Additionally it's not clear to me how I can cancel a filter during runtime.
Additionally it's not clear to me how I can cancel a filter during runtime.
Looking at the code, you should be able to cancel all filters by sending an empty array in the payload.
What about specifying reject filters like the following:
["!ItemStateEvent"]
This way we could keep full API compatibility, and add this new functionality.
However what still needs to be though about is how these filters behave:
- source filter:
- positive values: exclude source
- negative values (new): include source -> does it make sense to provide this? Many events don't have a source specified.
- type filter:
- positive value: include type
- negative value: exclude type -> what if both positive and negative values are specified??
- topic filter:
- positive value: include topic
- negative value: exclude topic -> if both are defined, you could specify something like
["openhab/items/*/command", "openhab/items/test/command"]to get all Item command except for the Itemtest
Looking at the code, you should be able to cancel all filters by sending an empty array in the payload.
What if I want to only cancel only one filter?
This way we could keep full API compatibility, and add this new functionality.
Since this will land in 5.0 and websockets don't seem to be widespread in use I think full API compatibility is not important.
Or how about using the a new topic openhab/websocket/filters That way the old one can be kept?
A filter could be created like this:
{
"filter": "create/remove",
"action": "pass/reject",
"target": "topic/type/source",
"value": "filter value"
}
e.g.
[
{
"filter": "create",
"action": "pass",
"target": "topic",
"value": "openhab/items/.*/command"
},
{
"filter": "create",
"action": "pass",
"target": "type",
"value": "MyType"
},
]
what if both positive and negative values are specified??
If a contradicting filter for an existing type filter is sent an error should be returned
What if I want to only cancel only one filter?
Sorry, I wasn’t clear enough. You should be able to cancel an individual filter by sending an empty array in its payload, this should work for all filter types.
Or how about using the a new topic openhab/websocket/filters That way the old one can be kept? A filter could be created like this:
IMO having the existing two filters + the topic filter and reject functionality for the topic and type filters should be enough functionality wise. Those filters can be updated during runtime, just set them to a new value.
Your proposal seems a bit over the top to me, more complex to implement than the status quo server-side.
You should be able to cancel an individual filter by sending an empty array in its payload, this should work for all filter types.
I try to make my question clearer with the following example:
I create the following filter:
["openhab/items/*/command", "!openhab/items/test/command"]
How can I remove the !openhab/items/test/command while keeping openhab/items/*/command
If I send an empty value I'll loose both filters and will be out of sync.
Your proposal seems a bit over the top to me, more complex to implement than the status quo server-side.
But it would provide a nice filter API which should be generic enough for all websocket activities including logging and can be reused accordingly.
How can I remove the !openhab/items/test/command while keeping openhab/items/*/command If I send an empty value I'll loose both filters and will be out of sync.
Okay now I understood what you mean. That's a valid use case, currently you would need to handle this client-side: Put your filters in an array, update that array and send the updated array.
But it would provide a nice filter API which should be generic enough for all websocket activities including logging and can be reused accordingly.
Logs and events are a bit different, not sure how much can be reused between them. Nothing against your proposal, but I won't implement it, my focus is primarily on Main UI development and my core development often is caused by the UI needing something.