How to dynamically change a property

Hello

I've been browsing through the forum trying to find an answer but didn't find anything I could use. I am a beginner trying to make my way through this gorgeous tool.

I created a flow which read the openweathermap API and expose the weather forecast for five days. I'd like to get the forecast only for tomorrow and to get two values :
the temperature forecast in the morning (let's say at 9 am)
the temperature forecast in the evening (let's say at 6 pm)

the data provided by openweathermap look like this :

Annotation 2020-06-01 223231

the key 0 refers to the next forecast value which will be exposed at 9:00 pm , the key 1 at 00:00 am and so on. This means I'll have to dynamically calculate which keys will match with the forecast of tomorrow 9 am.

Here is the flow I created

[{"id":"de68cc41.48148","type":"tab","label":"change","disabled":false,"info":""},{"id":"d70e517e.06dfe","type":"openweathermap","z":"de68cc41.48148","name":"meteo_future","wtype":"forecast","lon":"","lat":"","city":"Paris","country":"France","language":"en","x":360,"y":200,"wires":[["8fcf2834.8bfff","96da7d6d.bf7d68"]]},{"id":"1711f6c2.5311f9","type":"inject","z":"de68cc41.48148","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":200,"wires":[["d70e517e.06dfe"]]},{"id":"7ffa873f.3d8598","type":"debug","z":"de68cc41.48148","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1230,"y":200,"wires":[]},{"id":"7b9799c.9aa3ee8","type":"change","z":"de68cc41.48148","name":"selectRange","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[7].main","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":810,"y":200,"wires":[["e6923f78.6c97b","fb406463.2ec7"]]},{"id":"e6923f78.6c97b","type":"template","z":"de68cc41.48148","name":"pimpItUp","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Temperature tomorow morning will be : {{payload.temp}} ","output":"str","x":1020,"y":200,"wires":[["7ffa873f.3d8598"]]},{"id":"8fcf2834.8bfff","type":"function","z":"de68cc41.48148","name":"getTrancheHeure","func":"var d = new Date();\nvar n = d.getHours();\nvar a = Math.trunc(n/3);\nflow.set(\"tomorrowMorning\", a);\nmsg.Morning = flow.get(\"tomorrowMorning\")\nreturn msg;","outputs":1,"noerr":0,"x":590,"y":200,"wires":[["7b9799c.9aa3ee8","ac824c7e.f03ff8"]]},{"id":"ac824c7e.f03ff8","type":"debug","z":"de68cc41.48148","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"Morning.$flowContext('tomorrowMorning')","targetType":"jsonata","x":830,"y":320,"wires":[]},{"id":"fb406463.2ec7","type":"debug","z":"de68cc41.48148","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1020,"y":80,"wires":[]},{"id":"96da7d6d.bf7d68","type":"debug","z":"de68cc41.48148","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":570,"y":360,"wires":[]}]

in the selectRange box, I'd like to be able to turn the key[7] in a dynamic one.
The pain is than I manage to create a function (with great pain and a lot of readings) and to determine what value I should calculate. I even manage to extract that value using Jsonata but nothing work when I try to put it in the selectRange box.

Where did I do wrong ?

Well I prefer to make such computations using function node. It's way more simple than using multiple nodes in my opinion.

What You can do, is to get msg.payload from forecast and search for specific value of Your choice.

let forecast1 = msg.payload.find( w=> {
    let datetime = new Date(w.dt)
    return datetime.getHours() === 9
})

//msg.payload = forecast1

In forecast1 variable should be the first forecastData object which has timestamp set to 9 o'clock. You can also use filter function on the array to create new array with those elements that are satisfy filter rules, for example getHours() === 9 || getHours() === 18

thank you so much, I'll try to implement that (although I am not sure I undestand all your code) !

thank you again for your suggestion.
Actually it set me on the way.
I should have thought about it.
A solution is simply to identify the "data set" (don't know if it's the proper word) in the json file in a function.
Here is what I wrote to get what I wanted :

var dateObject = new Date();
var currentHourValue = dateObject.getHours();
var morningRange = 0

if (currentHourValue <= 9) {
    morningRange = Math.trunc((9-currentHourValue)/3);
} else {
    morningRange = Math.trunc((33-currentHourValue)/3)+1;
}

msg.morningRange = morningRange;
msg.morningForecast = msg.payload[morningRange];

The idea is to get in the object morningForecast the content of the json file. Then all its member will be accessible thanks to msg.morningForecast.[aVeryDesirableValue] etc...

I am quite certain it is note the nicest way to handle my problem but I solved it thanks to you :slight_smile:

2 Likes

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