Route filtering

Is there a way of filtering which devices get routed where, other than by Notefile name? If not, could this please be considered as a feature request? It seems to me Notefile name is a bit of a blunt filter and there will be times when you’d like data from some devices routed elsewhere. So, a device name filter?

Hi @rberkelm,

Great question - and yes this is definitely possible by using JSONata expressions in your Notehub routes.

For example, let’s say you only want a specific DeviceUID to route data to one of your routes. Starting with an abbreviated Note like this:

{
    "device": "dev:123456789",
    "file": "sensor.qo",
    "body": {
        "temp": 30
    }
}

…you could write a JSONata expression like this:

(
  $result := {
    "temp": body.temp
  };
  $result := (device = "dev:123456789") ? $result : $doNotRoute();
)

…which basically says if the DeviceUID matches, route the temp, if not, call the Notehub-specific custom function $doNotRoute() which prevents routing of the event.

JSONata is super powerful. I also recommend reading more about using JSONata transforms in Notehub routes too.

Rob

1 Like

Thanks Rob,
I’ll have to play with that one a bit. No luck on the first round…

Hi @rberkelm,

If you want to share with me an example Note and a scenario (e.g. you only want certain devices to route the Note) I’d be happy to take a stab at a JSONata expression. FYI the JSONata Exerciser is a critical tool to use when building complex JSONata expressions!

Rob

It’s hard to love JSONata when it gobbles up so much of your time. Gimme a button any day!
Anyway, I did eventually get this to work even though the Exerciser threw up an error:

ERROR IN INPUT DATA: Unexpected token ‘(’,
(
$resul"… is not valid JSON

… more wasted time…

(
  $result := {
    "weight": body.weight,
     "temp": body.temp,
     "bat": body.bat,
     "soc": body.soc,
     "netrawwt": body.netrawwt
  };

  $result := (device = "dev:867648043000111") ? $result : $doNotRoute();
)

So, I guess if I wanted to route 3 devices I would do this?

$result := (device = "dev:867648043000111", "dev:867648043000222", "dev:867648043000333") ? $result : $doNotRoute();

Hey @rberkelm,

Correct, but the syntax would be slightly different as you need to use or.

$result := (device = "dev:867648043000111" or "dev:867648043000222" or "dev:867648043000333") ? $result : $doNotRoute();

As another option, Notehub’s JSONata supports using environment variables (see Using JSONata to Transform JSON - Blues Wireless Developers), so you could use the existence of an environment variable to determine whether to route.

For example, you could set a routingEnabled environment variable to true on those three devices, and then use the following JSONata.

$result := ($routingEnabled = "true") ? $result : $doNotRoute();

This approach would give you some flexibility, as you’d be managing environment variables on devices rather than going into your JSONata every time you want to update the list.

TJ

Thanks TJ for the correct syntax and the suggestion.
As it turns out, there was still more to be done. The route was successful on the Notehub end but nothing was getting processed at the Datacake end. I eventually worked out that they don’t just want the “body” data, they want the whole thing… Ok, got it now.

What if I wanted to include the rsrp of that particular sensor in the route? I would have to tick the system notefiles box, but how to change the JSONata?

What if I wanted to include the rsrp of that particular sensor in the route? I would have to tick the system notefiles box, but how to change the JSONata?

Instead of including all system Notefiles, you probably just want to list _session.qo in the “Include Other Notefiles” box, as that’s the Notefile that contains the various fields related to cellular network state (such as rspr).

For _session.qo events the rspr is available as rspr in JSONata. If you want to keep with the same structure you’re using above you could do something like this.

$result := {
    "rspr": rspr
};

You can either create a new route that’s specifically for handling _session.qo events, or you can introduce some conditional logic in your JSONata that looks at the event’s file, and gathers different pieces of data depending on whether you’re dealing with a session event or a sensor event.

TJ

Thanks TJ. Sounds like a separate _session.qo route is the easiest to implement.