Specific Time format?

So I'm trying to follow the instructions on the MET Office API to upload my weatherdata to their global site and I've joined all my different mqtt flows etc. but having problem with the time format.

In their manual they state:

The date must be in the following format: YYYY-mm-DD HH:mm:ss, where ':' is encoded as %3A, and the space is encoded as either '+' or %20. An example, valid date would be: 2011-02-29+10%3A32%3A55, for the 2nd of Feb, 2011 at 10:32:55. Note that the time is in 24 hour format. Also note that the date must be adjusted to UTC time - equivalent to the GMT time zone.. This is especially important for users outside the UK, and British users must also take note of the difference between British Summer Time and UTC

I added the node-red-contrib-momentand set the output to their YYYY-MM-DD+HH%3Amm%3Ass but in the output it get's formatted as 2018-12-18%2019%3PM12%3PM47, ie %3Aget converted to %3PM and the site throws me a bad request!

Probably easier to do it in a function node where you can use a javascript date object
https://www.w3schools.com/jsref/jsref_obj_date.asp

and then build exactly what you want from that.

Or, if you use node-red-contrib-simpletime you can format it however you want by using a template node.

I'm afraid that since I don't know any java I can't go with your suggestion @ukmoose even if it might be the better way...

Tried that just now @Paul-Reed but it looks like it can only print the month with letters and not numbers?

its javascript.

I could look towards adding month 'numbers' as well, if you think it would be of benefit.

doesn't help, don't understand javascript either! :smiley:

I actually got it working by using a change node to replace the :with %3A still getting a "bad request" tough through node-red but the url works in a browser

if I have a function that looks like this:

msg.siteid = "24855254-ce02-e911-9462-0003ff598847";
msg.auth = "36EHNrR5Vwrp4HSW";
msg.url = "http://wow.metoffice.gov.uk/automaticreading?";
msg.payload = "siteid=24855254-ce02-e911-9462-0003ff598847&siteAuthenticationKey=36EHNrR5Vwrp4HSW&dateutc=" + msg.payload.dateutc + "&humidity=" + msg.payload["/Climate/BME280/Humidity"] + "&baromin=" + msg.payload["/Climate/BME280/Pressure"] + "&tempf=" + msg.payload["/Climate/BME280/Temperature"];
return msg;

and after that a HTTP POST with the url (http://wow.metoffice.gov.uk/automaticreading?) shouldn't that be working?

if I just paste the payload after the url in a browserwindow it works just fine siteid=24855254-ce02-e911-9462-0003ff598847&siteAuthenticationKey=36EHNrR5Vwrp4HSW&dateutc=2018-12-18+20%3A58%3A09&humidity=100.00&baromin=1025.19&tempf=-0.33

That is because moment is interpreting the A character to give AM/PM.

The correct approach is to get moment (or something else) to give you the formatted text string as normal with the ":"s embedded then replace the ':' strings.

This flow should do the trick.

Update: I've also added an alternative - instead of a function node, you can use a change
node with JSONata which is actually easier in this case.

[{"id":"1cc3c847.b678f8","type":"inject","z":"586832c7.9dc7fc","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":340,"wires":[["48c0750.0ea8f8c"]]},{"id":"cded485f.9ad718","type":"debug","z":"586832c7.9dc7fc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":690,"y":340,"wires":[]},{"id":"94bc128b.91385","type":"function","z":"586832c7.9dc7fc","name":"","func":"/** Uses a Regular Expression search with\n *  the global flag to return all occurances\n *  which are then replaced with the URL encoded\n *  equivalent.\n **/\n\nmsg.payload = msg.payload.replace(/\\:/g,'%3A')\n\nreturn msg;","outputs":1,"noerr":0,"x":490,"y":340,"wires":[["cded485f.9ad718"]]},{"id":"48c0750.0ea8f8c","type":"moment","z":"586832c7.9dc7fc","name":"","topic":"","input":"payload","inputType":"msg","inTz":"Europe/London","adjAmount":0,"adjType":"days","adjDir":"add","format":"YYYY-mm-DD HH:mm:ss","locale":"en_GB","output":"","outputType":"msg","outTz":"Europe/London","x":320,"y":340,"wires":[["94bc128b.91385","9e32d543.f8fce8"]]},{"id":"9e32d543.f8fce8","type":"change","z":"586832c7.9dc7fc","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$replace(payload, \":\", \"%3A\")\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":380,"wires":[["cded485f.9ad718"]]}]

WOW! $replace(payload, ":", "%3A") looks awsome, that's going to come in handy in the future! kudos @TotallyInformation

Just for info, I've just updated npm node-red-contrib-simpletime to also include a 2 digit month number.

v2.4.0 should appear in the node-RED library very shortly Now in node-RED library.

Paul

2 Likes

@Naesstrom Is that your correct api siteid & authenticationKey in the above post?

If so, it may be wise to edit your post, so nobody else can use it....

Paul

Thanks @Paul-Reed for the concern, the site-id is public and available on their site and I've changed the key!

A follow up question that's not related to the date/time tough since I got it working now... I'm still getting a Bad Request reply when trying to use the HTTP request?
The function produces a payload that works since I can paste it in the adress bar of a browsertab and all I should need in the http node is the adress?
image

If you read the Info panel for the http request node you'll find the following:

url string
If not configured in the node, this optional property sets the url of the request.

so set the full url you want to msg.url and feed that to the http request node

tried that to, used msg.url = "http://wow.metoffice.gov.uk/automaticreading?"; in the function and left the http node empty but I'm still getting bad request!

But you still need to add the data to that.

so after you have defined it you need

msg.url=msg.url+msg.payload;

(assuming your data line is msg.payload)

Ahh ok, so it looks like this now:

msg.siteid = "123456789";
msg.auth = "987654321";
msg.url = "http://wow.metoffice.gov.uk/automaticreading?";
msg.payload = "siteid=" + msg.siteid + "&siteAuthenticationKey=" + msg.auth + "&dateutc=" + msg.payload.dateutc + "&humidity=" + msg.payload.humidity + "&baromin=" + msg.payload.pressure + "&tempf=" + msg.payload.temp + "&dewptf=" + msg.payload.dewpoint +"&softwaretype=weathersoftware1.0";
return msg;

Shuld I add msg.url=msg.url+msg.payload just before return msg;then?

Complete noob but so far this thread has been a great learning experience! :smiley:

Yep. You said that it works if you paste it all into the browser window.
So what you are now doing is the equivalent. Putting it all on one long Website address ( as you did in the browser window) and sending that on to the next node.

1 Like

Awsome, thanks for the help! Reporting weather data now!