Switch Nodes - Regex

Guys,

Trying to make some decisions on weather data that i am parsing and storing - it looks like this when stored

image

I am wanting to use a switch node to look for permutations with the word sunny in the description.

There does not seem to be a concise list of these on the website (typical Govt data feed !)

but so far i have seen

Sunny
sunny
mostly sunny
occasional sun
and others !

What i want to do is have a number of tests that will dictate how much charge i put into my battery system overnight - based on the proposed amount of sun (there will be other things that factor in - but this is one of the first tests)

I have setup a switch node so far as such

image

But there does not appear to be much (in the online help) about what is acceptable in the Regex field - i have tried various permutations but not getting far - i have checked online with various Regex parsers - its just it is difficult to work out what is acceptable to NR in this field ?

I am happy (wanting) for instance for the first field to match (case insensitive) on Sunny - but not to match on partly sunny or mostly sunny etc

ANy pointers please ?

Craig

The original source data does not contain anything else useful ? like cloud coverage or something ?

You can try something like this ^(?!(partly|mostly))(.*)?(sun|sunny)$

Test Flow:

[{"id":"2867986b801a84ef","type":"inject","z":"54efb553244c241f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Sunny","payloadType":"str","x":350,"y":2440,"wires":[["55f3dc4cf3381a83","fdb3a07b1b44fac6"]]},{"id":"06216f8bb3498d19","type":"inject","z":"54efb553244c241f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"sunny","payloadType":"str","x":350,"y":2480,"wires":[["55f3dc4cf3381a83","fdb3a07b1b44fac6"]]},{"id":"35bc525d1b098bb6","type":"inject","z":"54efb553244c241f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"mostly sunny","payloadType":"str","x":330,"y":2520,"wires":[["55f3dc4cf3381a83","fdb3a07b1b44fac6"]]},{"id":"ade067739695c3f8","type":"inject","z":"54efb553244c241f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"occasional sun","payloadType":"str","x":320,"y":2560,"wires":[["55f3dc4cf3381a83","fdb3a07b1b44fac6"]]},{"id":"d40de17f9ae67bc8","type":"debug","z":"54efb553244c241f","name":"debug 27","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":700,"y":2520,"wires":[]},{"id":"794f2e8679226d6c","type":"inject","z":"54efb553244c241f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"cloudy","payloadType":"str","x":350,"y":2620,"wires":[["55f3dc4cf3381a83","fdb3a07b1b44fac6"]]},{"id":"cb72167ecfe5c3f5","type":"inject","z":"54efb553244c241f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"partly sunny","payloadType":"str","x":330,"y":2680,"wires":[["55f3dc4cf3381a83","fdb3a07b1b44fac6"]]},{"id":"55f3dc4cf3381a83","type":"function","z":"54efb553244c241f","name":"TEST","func":"\nconst regex =/^(?!(partly|mostly))(.*)?(sun|sunny)$/i;\n\nmsg.payload = regex.test(msg.payload)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":2520,"wires":[["d40de17f9ae67bc8"]]},{"id":"fdb3a07b1b44fac6","type":"switch","z":"54efb553244c241f","name":"","property":"payload","propertyType":"msg","rules":[{"t":"regex","v":"^(?!(partly|mostly))(.*)?(sun|sunny)$","vt":"str","case":true}],"checkall":"true","repair":false,"outputs":1,"x":570,"y":2640,"wires":[["71af1eb89582ad6f"]]},{"id":"71af1eb89582ad6f","type":"debug","z":"54efb553244c241f","name":"debug 28","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":700,"y":2640,"wires":[]}]

No unfortunately not - it is the most accurate - but sparse on detail !

OK will give that a try - do you know if there is a list of what is acceptable though in the switch node regex field ?

Craig

You can check out the Javascript regex documentation - if you really want to go down that rabbit hole... just keep in mind that in Javascript the expressions are inside slashes, which are not used in Node-RED.

Another way is to use a JSONata expression that returns a true or false... for instance, here is a case-insensitive check for determining if the payload contains the string 'sun':

Put that expression in the Property field, and add output ports for the boolean values:

3 Likes

I assume that the i in \sun\i is to ignore the case. So both sunny & SUNNY, etc would be 'true'.

No unfortunately not - it is the most accurate - but sparse on detail !

"occasional sun" could be the equivalent of "shower or two", doesn't sound very reliable.

Yep but they are the most accurate 12 hours - 24 hours out - so i can use this in the low solar months to enable precharging of my batteries overnight to enable peak shaving the next day.

As it gets closer i then find that 4-8 hours OpenWeathermap is good and their cloud forecasts are pretty accurate also.

Craig

Thanks thats given me a good head start - and probably easier to decipher in a years time than the regex i would end up with

Craig

@shrickus OK what you had sort of works for me - but what i wanted to do was reference the property as a Global Context object - the reason being that i could then reference multiple values in the tests such as Sun (to match all the sun conditions), Cloud to match all the cloud conditions etc

Using your suggestion it appears i can only do a True/False test ? And so would have to cascade multiple switch nodes for that to work ?

Now i have done a search and @knolleary had responded that this was not the behaviour he was expecting - in this thread - Problem with global json object variable and JSONata switch decision - #4 by knolleary

i am wondering if that has been resolved now - does the switch node still ignore what is in the Property field if i reference a Global/Flow context variable and i have to build up the whole jsonata in the test rules - or is this now resolved ?

Craig

In that case, I would set the switch property to be the global object value (assuming that works, of course), converted to a single case -- and then use a separate contains check for each output port:

It would be nice if the contains check had an ignore case option, like regex does... and you will probably have to tweak the order of your port checking if the incoming strings are like "Cloudy with some sun" :*(

1 Like

Good one thanks - i guess i would put a change node before this to get the Global context variable into the payload as i can not find a way to reference the Global context in the property field

Appreciate your time and will play with this and some other permutations and report back what works

Craig

Contains with added ignore case sounds like a nice pull request if someone felt like contributing.

1 Like

Does this property expression not get what you expect?

$globalContext('Weather.Today.Description').$uppercase()

Tbh, I never use context vars -- so IF that doesn't get the value you need, you could try getting the full Weather object from global context, and then just pull its fields using expression syntax, like so:

$globalContext('Weather').Today.Description.$uppercase()

I will play around with those suggestions thanks - i could not find a syntax that would work for me int he expression field - but will give those a go and let you know

Craig

Nope tried both permutations and no good

Looks like i am going to have to cascade a few switch nodes together or do it in a function block

thanks for trying to help out

Craig

I don't think there is an issue with the switch property expression -- the problem is that your regex does not match the string stored in your global context... Is there a reason you are using such a complex regex?

Notice how the context var ends with a period . ? But your regex states that the value must end with either 'sun' or 'sunny' -- which it does not. Either take the ^ and $ anchors off the regex so it can match anywhere in the text string, OR use the contains operator instead of a regex, as I tried to show previously.

OK will try to mess around - i added that complex regex in (another member earlier in the thread posted that up and a test flow that seemed to work with inject nodes for testing) - i then went to the contains - but will step through it all again and just confirm and report back

Craig

Yep looks like you were right - went back to a simple contains and put SUN in uppercase and it is matching now - now i will just need to code up all the edge cases

Thanks for hanging in and helping out with this one

Craig

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.