How to get JS transformation to "not return anything"

So, I’m trying to get some data from MQTT, but need to filter it out and return nothing to openhab in some (most) cases. I’m using a JS transform and right now, if I return “null” as in “no data”, I get my logs filled with warnings of the type

[WARN ] [ab.binding.mqtt.generic.ChannelState] - Incoming payload ‘null’ not supported by type ‘NumberValue’

The data comes in the form of

{ sensor_id : number, sensorvalue: value }

(yes, this is domoticz, but data comes on multiple ids and some need to be filtered out as they’re duplicated and/or carrying incorrect data, on some sensor_ids but not on others).

I would like to “multiplex” this data in a thing with different channels. So far, I can get the data, process it in a JS transformation (simple version below) and only output to a specified channel if the index on that sensor maches, and if data is deemed correct (i.e. I do some things under the hood to decide this).

So, to explain further, here’s a thing:

Thing mqtt:topic:domoticz "Domoticz" (mqtt:broker:2af10a50) @ "Domoticz"  {
     Type number : rssi "RSSI" [ stateTopic="domoticz/out", transformationPattern="JS:domo-rssi.js" 
     Type number : voltage "Voltage" [ stateTopic="domoticz/out", transformationPattern="JS:domo-voltage.js" ]
 } // end of thing

And here’s a corresponding JS:

(function(i) {
    var d = JSON.parse(i);
    if ( d.idx == 23 )
        return parseFloat(d.RSSI);
    return null;

Expanding futher (to clarify myself):

Say I have a “voltage” on sensors 10 and 15. I’d like to filter out the sensor id 10 and get the voltage from sensor 15 only. I tried using JSONPATH but failed. Perhaps that is also a path.

At the moment, all javascript transforms will be called for all channels each time new data comes in. Only the channel with the correct ID must return a valid data. All others should “abort” and not return anything to openhab.

And one more issue: It would be enormously beneficial to be able to pass multiple parameters to the JS, as in transformationPattern=“JS:myfunc.js(parameter,…)” where that would expand in:

(function(i,parameter,...) {

It would be such a huge improvement!

BTW, I’m using openhabian2 on a raspberry pi 3B+ and I’m running the latest snapshot from GIT.

That’s what a binding does. I do not think what you want to do is currently possible; you must either move up the tree to create your own binding, or go the other way and accept the sackfull of data in one lump and process it in a rule, where it is easy to make decisions about missing fields etc.

“Custom binding” might be less chore than it looks. openHAB does allow for generic bindings - ‘transport’ I think is the term - on top of which you can add device specific handlers. I do not know if MQTT binding is structured in that way. Perhaps a Domoticz flavour module would be generally useful.

I’m not sure I completely agree. The data comes on the MQTT binding. The “thing” is a domoticz server that happens to report some data on the mqqt network. The specific domoticz server is a “thing” and it’s different data “sensors” are channels to be bound to items.

Not sure if I can chain one binding to another (my guess is guess not) and this will require me to re-implement the MQTT binding, actually duplicate 95% of it’s code.

The fix shall come in the form of more generic transformations. In a normal architecture, there should be a way for the lower layer to signal to the upper layer that something is wrong (there are JS exceptions for that) and thus the call to the js transform can just catch the “ignore” exception. Short of that another way to do it is to return an object in the form of { status: OK|NOT OK, value: } but this would be a breaking change (and bad design too).

Not sure if I just answered my question, in the form of enhancing the transform logic.

Perhaps there is a way to chain multiple tranformations and abort in between in some way ?

You might be able to use something like MQTT 2.5 M1+ How to implement the equivalent to MQTT1 REGEX filters.

Use a REGEX to filter(s) out those messages that are not appropriate for the given Channel and only when they pass the REGEX filter(s) will it get passed to the JS or at that point JSONPATH transform may be sufficient.

Yes you can. This is exactly what rossko57 is describing in his second paragraph. What we don’t know is if MQTT is set up to support that though.

See my link above. You must be running MQTT 2.5 M1 or later though.

I think the OP’s difficulty with a transformation approach is that it is not possible to have a no-action path without a forced error.
You can set up several channels to pick out different bits of the same JSON, but if the field isn’t present, it fails. Pretty sure that is the case with any transform tech. With scripting you could force UNDEF say, but that is not wanted here.

When I coded the linked to article that was one of the requirements. If the REGEX returns nothing than the JSONPATH will not generate an error. So you use the REGEX to filter out those messages that would generate an error because it doesn’t have the right content (in the example case the shelly device ID) without error.

So if the REGEX only returns when the field is present and then chain it to the JSONPATH it should prevent the errors.

It’s actually a little scary if it just blackholes, but it’ll do this job.