"Truth tables" and how to build them - help required

Gee, I am good at digging myself into holes.
(No! Don't say it!) :wink:

I am seeing problem after problem with this recent venture with weather.

Clouds, rain and wind.

That is before the day/night part.

I am seeing confusion everywhere I turn.

I could press on but I think the end will be a messy one with a lot of duplicated stuff which I know can be done an easier way. Or at least I hope.

For now I'll forget about the day/night.

There is are clouds, rain and wind.

Clouds: overcast, broken, scattered, few
Rain: heavy, moderate, rain, light
Wind: calm, slight, strong, gusty Those are my definitions. Though gusting is in the vocabulary of the messages.

What I think would be a lot easier for me to do is build a truth table and parse the message with it, rather than having a whole string of conditional statements that is becoming a bird's nest.

Given: I shall have to ensure there is a valid entry in each message for the values to be checked.

It is hard to explain as there are three dimensions to this, but I am sure it is not beyond people's capacity.

I get the message (more than payload, but for the sake of simplicity) and compare it to the table.

Anything that is true is set and the icon is picked/chosen. (Resolved may be a better term?)

....Next!

Fine in theory. But I lack the brains to understand how to do that just now.
the terms, the commands, and so on.

Someone bored and wouldn't mind poking me in the right direction/s?

Tbh Andrew, I'd probably go one of 2 ways, a self contained function or subflow.

In otherwords, blackbox.

In my mind, this function would take a msg, look at the contents, add the computed icon properties to the msg then return it.

That is how I am going now. But with the three variables and each (ok not the wind) of them having 4 options that is 12 x .... a lot of combinations.

I understand that ultimately it has to be done. But there is the hard way and the easier way.

I know, I have said I like doing the hard yards. So at this point I see there is some function that should exist that allows simplification of this and remove the duplicates.

I'm just not quite seeing it.

No problems. I'll keep trying.

Thanks.

You could create a lookup like this...

var icons = {
  overcast : { 
      heavy : {
          calm : "icon1",
          slight : "icon2",
          ... And so on
      },
      moderate : {
          calm : "icon15",
          slight : "icon16",
          ... And so on
      }
   }
  broken : { 
      heavy : {
          calm : "icon31",
          slight : "icon32",
          ... And so on
      }
      ... And so on
   }
   ... And so on
}

Then access the icon name like this...

try {
  msg.icon = icons[cloud][rain][wind];
catch (e) {
  msg.icon = "some default icon"
 }

Notes.
I have assumed you only want 1 icon for the three elements.

Thanks.

I am really going to have to look at the structure.

I kind of get the structure but also don't.

In the mean time, I have been racking my brain writing stuff. For now it is a flow which I will make into a sub flow.
Just flows are easier to debug.

Was I correct in my assumptions?

You want 1 icon only for the 2way combination.

E.g. overcast heavy calm would be one icon, broken slight calm another icon.

As for not understanding, that's ok, you will when I explain it.

As for flows being easier to debug, not when the solution is 3 statements (because that's what this solution is) and don't forget, you asked for....

Sorry I didn't reply better.

I am really focused on the code.

Yes, I was only wanting one icon.

1 icon for a 3 way combination. Time, wind and rain. Four. Cloud density (broken/scattered/etc)

I sat down with a big piece of paper and thought about which is the better way to do it.
Least number of icon changes and the like.

I don't think I have the best, but it now written down, tested and I am applying it.

Alas that also means I make a lot of mistakes, but with the new layout/structure, they are easier to find.

Again: I do appreciate your time in replying. It is helpful even though you may not see a direct reflection with what I do. That is partly my fault, I know that.

But please understand that I sometimes try a method and don't like it.
Though it is good to have tired it and not just dismissed it "willy nilly".

I'm getting closer to the end - for now.

Alas I can't guess all the outputs the node gives, but again: the structure will allow easy integration when a new word/term is found.

One function, cant get any simpler.

[{"id":"27a1ab00.0b57f6","type":"inject","z":"c9ca6ac7.25b568","name":"fake weather  overcast heavy calm","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"cloud\":\"overcast\",\"rain\":\"heavy\",\"wind\":\"calm\"}","payloadType":"json","x":700,"y":100,"wires":[["60e11c6.aa954e4"]]},{"id":"60e11c6.aa954e4","type":"function","z":"c9ca6ac7.25b568","name":"Get icon from weather","func":"//A 3 deep lookup. Level1=coulds, level2=rain, level3=wind \nvar icons = {\n    overcast: {//clouds\n        heavy: {//rain\n            calm: \"icon1\", slight: \"icon2\", strong: \"icon3\", gusty: \"icon4\"//winds \n        },\n        moderate: {\n            calm: \"icon5\", slight: \"icon6\", strong: \"icon7\", gusty: \"icon8\"\n        },\n        rain: {\n            calm: \"icon9\", slight: \"icon10\", strong: \"icon11\", gusty: \"icon12\"\n        },\n        light: {\n            calm: \"icon13\", slight: \"icon14\", strong: \"icon15\", gusty: \"icon16\"\n        },\n    },\n    broken: {//clouds\n        heavy: {//rain\n            calm: \"icon17\", slight: \"icon18\", strong: \"icon19\", gusty: \"icon20\"\n        },\n        moderate: {\n            calm: \"icon21\", slight: \"icon22\", strong: \"icon23\", gusty: \"icon24\"\n        },\n        rain: {\n            calm: \"icon25\", slight: \"icon26\", strong: \"icon27\", gusty: \"icon28\"\n        },\n        light: {\n            calm: \"icon29\", slight: \"icon30\", strong: \"icon31\", gusty: \"icon32\"\n        },\n    },\n    scattered: {\n        heavy: {\n            calm: \"icon33\", slight: \"icon34\", strong: \"icon35\", gusty: \"icon36\"\n        },\n        moderate: {\n            calm: \"icon37\", slight: \"icon38\", strong: \"icon39\", gusty: \"icon40\"\n        },\n        rain: {\n            calm: \"icon41\", slight: \"icon42\", strong: \"icon43\", gusty: \"icon44\"\n        },\n        light: {\n            calm: \"icon45\", slight: \"icon46\", strong: \"icon47\", gusty: \"icon48\"\n        },\n    },\n    few: {\n        heavy: {\n            calm: \"icon49\", slight: \"icon50\", strong: \"icon51\", gusty: \"icon52\"\n        },\n        moderate: {\n            calm: \"icon53\", slight: \"icon54\", strong: \"icon55\", gusty: \"icon56\"\n        },\n        rain: {\n            calm: \"icon57\", slight: \"icon58\", strong: \"icon59\", gusty: \"icon60\"\n        },\n        light: {\n            calm: \"icon61\", slight: \"icon62\", strong: \"icon63\", gusty: \"icon64\"\n        },\n    }\n}\n\ntry {\n    msg.payload.icon = icons[msg.payload.cloud][msg.payload.rain][msg.payload.wind];\n} catch (e) {\n    msg.payload.icon = \"default_icon\"\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1020,"y":100,"wires":[["8a183408.53dbf8"]]},{"id":"eabea2b8.fd9a5","type":"inject","z":"c9ca6ac7.25b568","name":"fake weather  scattered rain gusty","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"cloud\":\"scattered\",\"rain\":\"rain\",\"wind\":\"gusty\"}","payloadType":"json","x":690,"y":140,"wires":[["60e11c6.aa954e4"]]},{"id":"f7cdef6d.bd38a","type":"inject","z":"c9ca6ac7.25b568","name":"fake weather  few light calm","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"cloud\":\"few\",\"rain\":\"light\",\"wind\":\"strong\"}","payloadType":"json","x":670,"y":180,"wires":[["60e11c6.aa954e4"]]},{"id":"8a183408.53dbf8","type":"debug","z":"c9ca6ac7.25b568","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload.icon","statusType":"msg","x":1050,"y":140,"wires":[]},{"id":"e867e80e.eb51e8","type":"inject","z":"c9ca6ac7.25b568","name":"fake weather  black cats-n-dogs hoollie (bad data)","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"cloud\":\"black\",\"rain\":\"cats-n-dogs\",\"wind\":\"hoollie\"}","payloadType":"json","x":740,"y":220,"wires":[["60e11c6.aa954e4"]]},{"id":"b7747690.2b8d78","type":"comment","z":"c9ca6ac7.25b568","name":"Using injects as test data","info":"","x":670,"y":60,"wires":[]}]

The concept...

  • Make a lookup JS object (or as you might think of it - some JSON)
    • the object has 3 levels of cloud.rain.wind with every possible combination (64 of them)
  • access the required item using bracket notation instead of dots

dot notation examples...

var the_icon = icons.overcast.heavy.gusty;
var another_icon = icons.overcast.moderate.strong;

bracket notation example (note it is EXACTLY the same as the familiar dot notation above)...

var the_icon = icons["overcast"]["heavy"]["gusty"];
var another_icon = icons["overcast"]["moderate"]["strong"];

so using the bracket notation we can dynamically lookup the icon for msg.payload.cloud, msg.payload.rain, msg.payload.wind...

msg.payload.icon = icons[msg.payload.cloud][msg.payload.rain][msg.payload.wind];

Yes, ok.

But that is 4 messages. Mine is one message with all 4 things in it.

Sorry. Saw the reply and am looking now, but am nose down in what I am writing.

I did 4 examples to prove the 4 different weather condition combinations work as expected!

My demo ALSO has 1 msg with all 3 things in! there is 4 demo injects!!!

the 1st inject throws in overcast heavy calm and the icon comes out as icon1
the 2nd inject throws in scattered rain gusty and the icon comes out as icon44

Sorry. Ok.

I seem to now be not getting anywhere and getting stupid errors.

I'll take a break and look at your code.

It looks like you are reinventing the wheel.

Openweathermap privides an ID code that links to icons.


edit and here some code to integrate.
1 Like

Yes, but their mapping is very basic.

There are no day/night differences. No wind difference is there is wind. No changes between broken and overcast clouds.

It does work as is, but only just.

I'm not saying it is bad. But I just thought I would go through this to also help me learn how to do something I have never tried before.

1 Like

Hey Steve.

Ok, new day. I a more awake now. I'm looking at it.

I am starting to get how it works. But that is a big STARTING.

No problems. I get I have to do some leg work to get it all working.

For now I will just have to play with the flow/code you gave me and do things at a micro scale before I use it for real - if you will.

I goofed with some of the words used, and that's my problem for rain qualifiers.

But "at the start" I am not sure where I am.
I get that depending on (the first line) wind speed, the icon could be changed.
But at the start: what are the given conditions?

I'm asking because I'm taking it that the icon is only changed IF there is a match.
Although I guess - just now thinking - the table will have every possible combination, so it doesn't really matter.
Somewhere in the table every condition has to exist.

So, with that understanding, it may be a good idea to make the default icon something like "This condition wasn't found!"

Update/edit

Oh! That's it!

Let's take the first block:

var icons = {
    overcast: {//clouds
        heavy: {//rain
            calm: "icon1", slight: "icon2", strong: "icon3", gusty: "icon4"//winds 
        },
        moderate: {
            calm: "icon5", slight: "icon6", strong: "icon7", gusty: "icon8"
        },
        rain: {
            calm: "icon9", slight: "icon10", strong: "icon11", gusty: "icon12"
        },
        showers: {
            calm: "icon13", slight: "icon14", strong: "icon15", gusty: "icon16"
        },

Working on the "only things that are different are set":
clouds is overcast
rain is heavy.
Then I set it depending on the wind - yes?
Then, the second line is that rain goes from heavy to moderate.
Then rain goes to rain.

Got it!

Ok, with that I will have another look at it.

If this works, it will be so much smaller than the flow I have written now.

I will say it again in a different way. There are 50 plus code numbers, each is a different weather pattern. Assign the icon you wish to an object of code number. Then use the code number from the return json to return any icon you wish for that code. Obviously dependant on time of day.

And again I shall say I have looked at that option.

Maybe I need to look again, but say I pick "brand x" icons:

I go through the list and there are holes in places where I want to use that icon.

So I try "brand y". Same again.

So they would work and where the "holes" are, those icons would never be used by that "brand" of numbering.

So: this is interesting and so I am doing this to LEARN how to do what they did in the higher level where they generate the numbers to be sent to plebs like me to use.

Then I can use the icons I want.

It probably won't come to much for this actually achieving much, but I hope to expand my knowledge.
(Learn is maybe the word)

So it isn't that I am not appreciating the input, but you need to understand why I am doing this and not just the end result of getting icons on a weather screen.

I've gotta go and study the code Steve posted.
Then once I get through that, I then have to work out how to modify it to parse the message from the node.

But that is a whole other journey.

What ever icons you are planning to use now , you can apply to the code numbers. You can have more than one code for the same icon. You can mix brand a,b,c,,d,nth.

I understand you want to learn, what ever you settle on is your choice, just wanted you to have options and think on different ways.

Yes, I use the "different numbers".

But that isn't going to magically happen.

So be it I use the numbers or the icon's name, I still have to write the code.

Or is there a really big hidden elephant I am missing that can magically know which numbers from which set I want to use?

I am open to suggestions - as with Steve's suggestion.

Alas there is a lot of (so far) duplicate icons. But believe me, what he posted and the real thing are orders of magnitude bigger.

His doesn't have a day/night part. But I get it: That's my problem.
With his code I may be able to get that included but another way I found last night.

A simple table lookup example all you neeed to do is create the table.

[{"id":"1ac7ba4.2e908c6","type":"inject","z":"8d22ae29.7df6d","name":"230 id from json","props":[{"p":"payload"},{"p":"icons","v":"{\"200\":{\"label\":\"thunderstorm with light rain\",\"icon\":\"storm-showers\"},\"201\":{\"label\":\"thunderstorm with rain\",\"icon\":\"storm-showers\"},\"202\":{\"label\":\"thunderstorm with heavy rain\",\"icon\":\"storm-showers\"},\"210\":{\"label\":\"light thunderstorm\",\"icon\":\"storm-showers\"},\"211\":{\"label\":\"thunderstorm\",\"icon\":\"thunderstorm\"},\"212\":{\"label\":\"heavy thunderstorm\",\"icon\":\"thunderstorm\"},\"221\":{\"label\":\"ragged thunderstorm\",\"icon\":\"thunderstorm\"},\"230\":{\"label\":\"thunderstorm with light drizzle\",\"icon\":\"storm-showers\"},\"231\":{\"label\":\"thunderstorm with drizzle\",\"icon\":\"storm-showers\"},\"232\":{\"label\":\"thunderstorm with heavy drizzle\",\"icon\":\"storm-showers\"},\"300\":{\"label\":\"light intensity drizzle\",\"icon\":\"sprinkle\"},\"301\":{\"label\":\"drizzle\",\"icon\":\"sprinkle\"},\"302\":{\"label\":\"heavy intensity drizzle\",\"icon\":\"sprinkle\"},\"310\":{\"label\":\"light intensity drizzle rain\",\"icon\":\"sprinkle\"},\"311\":{\"label\":\"drizzle rain\",\"icon\":\"sprinkle\"},\"312\":{\"label\":\"heavy intensity drizzle rain\",\"icon\":\"sprinkle\"},\"313\":{\"label\":\"shower rain and drizzle\",\"icon\":\"sprinkle\"},\"314\":{\"label\":\"heavy shower rain and drizzle\",\"icon\":\"sprinkle\"}}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"230","payloadType":"str","x":140,"y":2360,"wires":[["97554150.eea59"]]},{"id":"97554150.eea59","type":"function","z":"8d22ae29.7df6d","name":"A simple table lookup","func":"msg.payload = msg.icons[msg.payload];\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":440,"y":2360,"wires":[["c6154d5c.e76c58"]]},{"id":"c6154d5c.e76c58","type":"debug","z":"8d22ae29.7df6d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":670,"y":2360,"wires":[]},{"id":"d0a181cb.20af","type":"inject","z":"8d22ae29.7df6d","name":"312 id from json","props":[{"p":"payload"},{"p":"icons","v":"{\"200\":{\"label\":\"thunderstorm with light rain\",\"icon\":\"storm-showers\"},\"201\":{\"label\":\"thunderstorm with rain\",\"icon\":\"storm-showers\"},\"202\":{\"label\":\"thunderstorm with heavy rain\",\"icon\":\"storm-showers\"},\"210\":{\"label\":\"light thunderstorm\",\"icon\":\"storm-showers\"},\"211\":{\"label\":\"thunderstorm\",\"icon\":\"thunderstorm\"},\"212\":{\"label\":\"heavy thunderstorm\",\"icon\":\"thunderstorm\"},\"221\":{\"label\":\"ragged thunderstorm\",\"icon\":\"thunderstorm\"},\"230\":{\"label\":\"thunderstorm with light drizzle\",\"icon\":\"storm-showers\"},\"231\":{\"label\":\"thunderstorm with drizzle\",\"icon\":\"storm-showers\"},\"232\":{\"label\":\"thunderstorm with heavy drizzle\",\"icon\":\"storm-showers\"},\"300\":{\"label\":\"light intensity drizzle\",\"icon\":\"sprinkle\"},\"301\":{\"label\":\"drizzle\",\"icon\":\"sprinkle\"},\"302\":{\"label\":\"heavy intensity drizzle\",\"icon\":\"sprinkle\"},\"310\":{\"label\":\"light intensity drizzle rain\",\"icon\":\"sprinkle\"},\"311\":{\"label\":\"drizzle rain\",\"icon\":\"sprinkle\"},\"312\":{\"label\":\"heavy intensity drizzle rain\",\"icon\":\"sprinkle\"},\"313\":{\"label\":\"shower rain and drizzle\",\"icon\":\"sprinkle\"},\"314\":{\"label\":\"heavy shower rain and drizzle\",\"icon\":\"sprinkle\"}}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"312","payloadType":"str","x":140,"y":2400,"wires":[["97554150.eea59"]]}]

I haven't looked it it yet, but isn't that what Steve posted?

A look up table?

Ok, I did a quick look at the code.

There are a couple of big assumptions:
1 - That all the numbers are unique. As in they are ONLY numbers.
2 - There is no letters in the equation.

Some of the numbers are like:
f004 from one set.

and others:
f00d from another.

I'll look at it, but for now I want to put a bit of time in looking at what Steve posted. To not would be kind of rude.

I do like your suggestion as it has an application in something else which I need doing.
(Maybe of higher priority, but I don't want to open that can of worms this early.)

(you have since posted, so I will put the edit in a new post)