Decoding weather underground upload protocol

I have a weather station (ambient weather ws-2000) that allows you to send data to a custom url (other than the wunderground server) using weather underground's upload protocol.
https://ambientweather.com/faqs/question/view/id/1857/
PWS-Upload-Protocol

the data is sent as a url. Here's the example from the wunderground site

https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?ID=KCASANFR5&PASSWORD=XXXXXX&dateutc=2000-01-01+10%3A32%3A35&winddir=230&windspeedmph=12&windgustmph=12&tempf=70&rainin=0&baromin=29.1&dewptf=68.2&humidity=90&weather=&clouds=&softwaretype=vws%20versionxx&action=updateraw

How can I turn this into useable data?

Welcome to the forum!

Here is a simple way to get everything into an array, You can then reference the array by index. Needs a little work!

[
    {
        "id": "7e1067cd7c950158",
        "type": "inject",
        "z": "989d846533e1bd37",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?ID=KCASANFR5&PASSWORD=XXXXXX&dateutc=2000-01-01+10%3A32%3A35&winddir=230&windspeedmph=12&windgustmph=12&tempf=70&rainin=0&baromin=29.1&dewptf=68.2&humidity=90&weather=&clouds=&softwaretype=vws%20versionxx&action=updateraw",
        "payloadType": "str",
        "x": 190,
        "y": 100,
        "wires": [
            [
                "2ea616ccbceab599"
            ]
        ]
    },
    {
        "id": "755fb282d7b8c23b",
        "type": "debug",
        "z": "989d846533e1bd37",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 630,
        "y": 100,
        "wires": []
    },
    {
        "id": "2ea616ccbceab599",
        "type": "split",
        "z": "989d846533e1bd37",
        "name": "",
        "splt": "&",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 330,
        "y": 100,
        "wires": [
            [
                "c6a36064f434c2c0"
            ]
        ]
    },
    {
        "id": "c6a36064f434c2c0",
        "type": "join",
        "z": "989d846533e1bd37",
        "name": "",
        "mode": "custom",
        "build": "array",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 470,
        "y": 100,
        "wires": [
            [
                "755fb282d7b8c23b"
            ]
        ]
    }
]

Thanks! So do I put this into a function to send the string to?

No, if you replace the inject node with the nodes you are using to get the string it should work.

Also , you will learn a lot if you spend a little of your time looking at the following introduction to node red:

Thanks, I had watched some introductory videos, but I'll watch some more. I guess I just didn't realize this was a flow. I suppose I just import this then. Thanks for being patient with me. My end goal is going to be to beacon my weather data over RF using APRS locally on my network. Thanks so much for your help.

This was just a quick idea to separate the values so that you can access them. The format you are getting the data in is not easy to break down. Give it a try. If you cannot get any further, post in this thread again. We are here to help!

1 Like

Hi,

You could easily 'parse' that URL / string data using the 'String' node (node-red-contrib-string).

Install it using 'Manage Palette' in the menu.

Get the URL into a variable of type string (e.g. Global.URL' or something).

Now start ripping chunks of data from the URL into individual variables by adding a 'Method' and saving as a different variable.
Keep adding String nodes with different Methods until you have what you want.

Use debug after each String node to ensure the contents are correct.

Cheers,

Paul

There is a much better solution - use the native JavaScript URL to parse it...

OK, well, since this is node-red server-side code, we need to use the NODE JS implementation of URL

Result...

Demo flow

[{"id":"459f926df5d2e666","type":"inject","z":"185020e89716d363","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":1180,"y":120,"wires":[["5efadffc9fbcd46c"]]},{"id":"5efadffc9fbcd46c","type":"function","z":"185020e89716d363","name":"function 1","func":"const myURL = new url.URL('https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?ID=KCASANFR5&PASSWORD=XXXXXX&dateutc=2000-01-01+10%3A32%3A35&winddir=230&windspeedmph=12&windgustmph=12&tempf=70&rainin=0&baromin=29.1&dewptf=68.2&humidity=90&weather=&clouds=&softwaretype=vws%20versionxx&action=updateraw')\nconst params = {}\nmyURL.searchParams.forEach((v, n, sp) => {\n    params[n] = v\n})\n\nmsg.payload = {\n    searchParams: params,\n    hostname: myURL.hostname,\n    host: myURL.host,\n    hash: myURL.hash,\n    href: myURL.href,\n    origin: myURL.origin,\n    pathname: myURL.pathname,\n    port: myURL.port,\n    protocol: myURL.protocol,\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"url","module":"url"}],"x":1340,"y":120,"wires":[["69970a527e10f4b5"]]},{"id":"69970a527e10f4b5","type":"debug","z":"185020e89716d363","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1340,"y":180,"wires":[]}]
1 Like

well I beat my head against the wall on this until 3am last night after I put the kiddo to bed. For some reason I can't use HTTP IN to get the data. (I can send an example url from a browser and it comes in through the HTTP IN just fine, but not from the weather station controller) If I use a TCP node with a different port It receives the data, but then It handles the data differently it seems. I can send the data out as a single string but then I can't figure out how to turn the data into an object.

Well I finally got it to receive the HTTP IN. I added a question mark after the forward slash in the path on the weather station setup and it started getting data. I had to use tcpdump to look at the http coming in to find the problem. after that I did the split like you said and copied the key to topic. then used a switch to get it all where I need it to go. Thank you all so much for your help.


[
    {
        "id": "dad735ba0e17874e",
        "type": "tab",
        "label": "Flow 2",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "252c421746d95007",
        "type": "debug",
        "z": "dad735ba0e17874e",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 650,
        "y": 140,
        "wires": []
    },
    {
        "id": "1dd09b69420d10ec",
        "type": "http in",
        "z": "dad735ba0e17874e",
        "name": "",
        "url": "/wx/",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 300,
        "y": 140,
        "wires": [
            [
                "252c421746d95007",
                "3185df85801ab956"
            ]
        ]
    },
    {
        "id": "fb23cb718866639f",
        "type": "ui_gauge",
        "z": "dad735ba0e17874e",
        "name": "",
        "group": "a751d160373373d5",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "Humidity",
        "label": "%",
        "format": "{{value}}",
        "min": 0,
        "max": "100",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "className": "",
        "x": 760,
        "y": 300,
        "wires": []
    },
    {
        "id": "3752a712a9ea9973",
        "type": "debug",
        "z": "dad735ba0e17874e",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 770,
        "y": 340,
        "wires": []
    },
    {
        "id": "3185df85801ab956",
        "type": "split",
        "z": "dad735ba0e17874e",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "topic",
        "x": 290,
        "y": 200,
        "wires": [
            [
                "2e02cdb6df116104"
            ]
        ]
    },
    {
        "id": "2e02cdb6df116104",
        "type": "switch",
        "z": "dad735ba0e17874e",
        "name": "",
        "property": "topic",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "humidity",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "tempf",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "indoortempf",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "windspeedmph",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "rainin",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "dailyrainin",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "weeklyrainin",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "monthlyrainin",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "yearlyrainin",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "solarradiation",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 10,
        "x": 370,
        "y": 380,
        "wires": [
            [
                "3752a712a9ea9973",
                "219575085aa6a868",
                "fb23cb718866639f"
            ],
            [
                "478a5f654f7d26db"
            ],
            [
                "dda4466a8af71ec0"
            ],
            [
                "da72ada05380193c"
            ],
            [
                "262a0667b6fd6024"
            ],
            [
                "b3a9339b62b0f384"
            ],
            [
                "304cd3c45d03e537"
            ],
            [
                "bc3fa5ddb9b2ee25"
            ],
            [
                "7b58e13f1b7989ae"
            ],
            [
                "601efb4cd723fa27"
            ]
        ]
    },
    {
        "id": "219575085aa6a868",
        "type": "ui_chart",
        "z": "dad735ba0e17874e",
        "name": "",
        "group": "cbdd18db629934b9",
        "order": 3,
        "width": 0,
        "height": 0,
        "label": "Humidity",
        "chartType": "line",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "0",
        "ymax": "100",
        "removeOlder": 1,
        "removeOlderPoints": "",
        "removeOlderUnit": "3600",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "x": 760,
        "y": 260,
        "wires": [
            []
        ]
    },
    {
        "id": "478a5f654f7d26db",
        "type": "ui_gauge",
        "z": "dad735ba0e17874e",
        "name": "",
        "group": "a751d160373373d5",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "Outside Temperature",
        "label": "F",
        "format": "{{value}}",
        "min": "-30",
        "max": "110",
        "colors": [
            "#90f1fe",
            "#19cee6",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "className": "",
        "x": 800,
        "y": 380,
        "wires": []
    },
    {
        "id": "dda4466a8af71ec0",
        "type": "ui_gauge",
        "z": "dad735ba0e17874e",
        "name": "",
        "group": "cbdd18db629934b9",
        "order": 3,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "Indoor Temp",
        "label": "f",
        "format": "{{value}}",
        "min": "50",
        "max": "100",
        "colors": [
            "#00d5ff",
            "#00b500",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "className": "",
        "x": 770,
        "y": 420,
        "wires": []
    },
    {
        "id": "da72ada05380193c",
        "type": "ui_gauge",
        "z": "dad735ba0e17874e",
        "name": "",
        "group": "a751d160373373d5",
        "order": 4,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "Wind Speed",
        "label": "mph",
        "format": "{{value}}",
        "min": 0,
        "max": "60",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "className": "",
        "x": 770,
        "y": 460,
        "wires": []
    },
    {
        "id": "262a0667b6fd6024",
        "type": "ui_text",
        "z": "dad735ba0e17874e",
        "group": "cbdd18db629934b9",
        "order": 3,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Rain",
        "format": "{{msg.payload}}in",
        "layout": "col-center",
        "className": "",
        "x": 750,
        "y": 500,
        "wires": []
    },
    {
        "id": "304cd3c45d03e537",
        "type": "ui_text",
        "z": "dad735ba0e17874e",
        "group": "cbdd18db629934b9",
        "order": 3,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Weekly Rain",
        "format": "{{msg.payload}}in",
        "layout": "col-center",
        "className": "",
        "x": 770,
        "y": 580,
        "wires": []
    },
    {
        "id": "b3a9339b62b0f384",
        "type": "ui_text",
        "z": "dad735ba0e17874e",
        "group": "cbdd18db629934b9",
        "order": 3,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Daily Rain",
        "format": "{{msg.payload}}in",
        "layout": "col-center",
        "className": "",
        "x": 770,
        "y": 540,
        "wires": []
    },
    {
        "id": "bc3fa5ddb9b2ee25",
        "type": "ui_text",
        "z": "dad735ba0e17874e",
        "group": "cbdd18db629934b9",
        "order": 3,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Monthly Rain",
        "format": "{{msg.payload}}in",
        "layout": "col-center",
        "className": "",
        "x": 770,
        "y": 620,
        "wires": []
    },
    {
        "id": "7b58e13f1b7989ae",
        "type": "ui_text",
        "z": "dad735ba0e17874e",
        "group": "cbdd18db629934b9",
        "order": 3,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Yearly Rain",
        "format": "{{msg.payload}}in",
        "layout": "col-center",
        "className": "",
        "x": 770,
        "y": 660,
        "wires": []
    },
    {
        "id": "be39ae3fd54d5975",
        "type": "ui_text",
        "z": "dad735ba0e17874e",
        "group": "cbdd18db629934b9",
        "order": 3,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Solar Radiation (Sunshines)",
        "format": "{{msg.payload}}",
        "layout": "col-center",
        "className": "",
        "x": 820,
        "y": 700,
        "wires": []
    },
    {
        "id": "0c685d21dff69ea7",
        "type": "change",
        "z": "dad735ba0e17874e",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "Aint No Sunshine!",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 590,
        "y": 760,
        "wires": [
            [
                "be39ae3fd54d5975"
            ]
        ]
    },
    {
        "id": "601efb4cd723fa27",
        "type": "switch",
        "z": "dad735ba0e17874e",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "neq",
                "v": "0.00",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "0.00",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 450,
        "y": 600,
        "wires": [
            [
                "be39ae3fd54d5975"
            ],
            [
                "0c685d21dff69ea7"
            ]
        ]
    },
    {
        "id": "a751d160373373d5",
        "type": "ui_group",
        "name": "",
        "tab": "3b76e27343632c45",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "cbdd18db629934b9",
        "type": "ui_group",
        "name": "",
        "tab": "3b76e27343632c45",
        "order": 2,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "3b76e27343632c45",
        "type": "ui_tab",
        "name": "Home",
        "icon": "dashboard",
        "disabled": false,
        "hidden": false
    }
]
2 Likes