Python UDP parsing

I’m 100% new to Python. I’ve been able to get the UDP Broadcast but I don’t know how to parse the data/

The data comes in as follows:
b’{“serial_number”:“ST-00006839”,“type”:“rapid_wind”,“hub_sn”:“HB-00019566”,“ob”:[1591904071,2.59,247]}’
b’{“serial_number”:“ST-00006839”,“type”:“device_status”,“hub_sn”:“HB-00019566”,“timestamp”:1591904071,“uptime”:356173,“voltage”:2.56,“firmware_revision”:129,“rssi”:-91,“hub_rssi”:-94,“sensor_status”:0,“debug”:0}’
b’{“serial_number”:“ST-00006839”,“type”:“obs_st”,“hub_sn”:“HB-00019566”,“obs”:[[1591904071,0.36,1.97,3.17,230,3,1015.44,19.16,97.13,13664,0.47,114,0.127551,1,0,0,2.561,1]],“firmware_revision”:129}’
b’{“serial_number”:“ST-00006839”,“type”:“light_debug”,“hub_sn”:“HB-00019566”,“ob”:[1591904073,2633,207,0,0]}’
b’{“serial_number”:“HB-00019566”,“type”:“hub_status”,“firmware_revision”:“134”,“uptime”:313824,“rssi”:-61,“timestamp”:1591904077,“reset_flags”:“PIN,SFT”,“seq”:31319,“fs”:[1,0,15675411,524288],“radio_stats”:[22,1,0,3],“mqtt_stats”:[16,37]}’

My question for those that know Python, how to I assign the data in “obs” to different variables? I only are about some of the data for this project and it’s all in the UDP broadcast, but I don’t know how to reference it. Thanks!

1 Like

Does this help any?

https://www.w3schools.com/python/python_lists.asp

The contents of each ob/obs field are documented in the WF UDP API:

https://weatherflow.github.io/SmartWeather/api/udp/v114/

1 Like

Thanks. I ended up with this mess:

    data, addr = sock.recvfrom(1024) #gets UDP data
    data2 = json.loads(data) #sets UDP received as JSON

if str(data2[‘type’]) == “obs_st”: #tests for a broadcast with weather data
dirty = str(data2[‘obs’]) #ensures data is a string for future parsing
dirty = dirty.replace("[[", “[”) #strips one of the leading brackets
dirty = dirty.replace("]]", “]”) #strips one of the trailing brackets
clean = dirty.split(",") #splits the resulting string so it can be referensed as a list

        #assigning variables
        air_temperature = clean[7]
        wind_avg = clean[2]
        wind_gust = clean[3]
        wind_direction = clean[4]
        
        #writes to HTML when there's new data and iterates the counter
        output_to_HTML() #writes HTML file
        print('Loops: ', loop_count) #counts how many times this has run
        loop_count = loop_count + 1 # itterates count
        print()#some padding for console
        print()#some padding for console
2 Likes

You could always just run my UDP listener which does this already, or refer to it as one example of how you can do it.

4 Likes

Let me ask a strange question. Have you written code in JavaScript?

I’ve never written any code of any sort. Which may have been why I was scared of vinceskahan‘s UDP listener.

2 Likes

The packets are in JSON. JavaScript Object Notation and there should be a library that can parse the data.

I, for one, am impressed at how far you have advanced in only a few hours!!!

If you want to Python-ify your handling of [[ and ]], “ob” fields in the UDP packets are lists, whereas “obs” are lists of lists. Think [[1,2,3,4,5],[6,7,8,9,10]] . WF never promised that they will not send multiple “obs” lists in a single UDP packet (like in a hub down/reboot recovery catch-up scenario), although it it good to keep UDP packets short to guarantee maximum deliverability since there is no handshaking. I suspect that their intention was to keep the UDP and web packet formats as close as possible, and that seeing multiple lists in an “obs” field is more likely from the web side. For a programming exercise, you may want to treat it as a list of lists and iterate through it just for completeness. Otherwise, dirty = data2[‘obs’][0] should grab the first list from an “obs” field and replace three lines of converting to a string and deleting characters…if I’m still awake. It’s been a long day, and my brain is fried right now…

1 Like

Can you get away with clean = data2[‘obs’][0] ???

1 Like

Someone in the Raspberry Pi forum was kind enough to point me in that direction.

I’ve updated the code to reflect data2[‘obs’][0][6]

I was missing the [0] part. It’s challenging trying to learn to parse json (which it turns out is easy in hindsight) and learn some Python.

My ultimate goal is to have the Raspberry Pi turn servos to mimic analog-weather gauges. While I was waiting for my Tempest to ship I got it up and running by pulling from the demo APIs but I was really hoping to be able to get this (more or less) real-time via UDP. I’m very pleased.

And thank you all for the help. Seems like a great community.

3 Likes

If you got that far never having programmed (let alone in python), you’re doing pretty well as others have said. Many of us bought the WF gear partially for the fun of rolling our own software to see what we could cook up. Go wild !

3 Likes

So I split this into two pieces for ease of use. The first one listens for UDP broadcasts and puts the received data into a Redis database, which is a memory-resident data store. The second one reads the Redis database for interesting data and does stuff with it. Then the program that wants to know the temperature doesn’t have to listen for (and parse) the battery voltage and everything else. Plus, a computer ends up with one listener and more than one data consumer. I did something similar to your project with a Raspberry Pi InspiRing that shows wind direction around the circle and wind speed in the color of the LED.

My UDP listener code is here: http://dotnetdotcom.net/WFrws.py

The WindRose code is here: http://dotnetdotcom.net/WindRose.py

I borrowed heavily from Vince and others. #ShouldersOfGiants

Enjoy!

3 Likes

Need screenshots please !!!