weatherflow-udp Copyright 2017-2020 Arthur Emerson, vreihen@yahoo.com Distributed under terms of the GPLv3 This is a driver for weewx, that captures data from the WeatherFlow bridge via the bridge's UDP broadcasts on the local subnet. I believe that I have correctly followed the instructions provided by weewx in order to provide the complete weewx extension package layout here. https://github.com/weewx/weewx/wiki/extensions#how-to-install-an-extension Installation should be as simple as grabbing a .ZIP download of this entire project from the GitHub web interface, and then running this command: wee_extension --install weatherflow-udp-master.zip Worst case, a manual install is simple enough. At least on my Raspberry Pi, copy weatherflowudp.py from bin/user to /usr/share/weewx/user/weatherflowudp.py, and then edit /etc/weewx/weewx.conf and add the new station driver settings per the info below. (If you are starting with a fresh weewx installation, choose the "Simulator" station driver during the package install process. The wee_extension command above will replace the simulator station driver with this one.) Please let me know if I made a mistake with the packaging. I am not a weewx expert, and do not claim to be a programmer or more than a casual user of GitHub. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Description: This driver detects different sensors packets broadcast using the WeatherFlow UDP JSON protocol, and it includes a mechanism to filter the incoming data and map the filtered data onto the weewx database schema and identify the type of data from each sensor. Sensors are filtered based on a tuple that identifies uniquely each sensor. A tuple consists of the observation name, a unique identifier for the hardware, and the packet type, separated by periods: <observation_name>.<hardware_id>.<packet_type> The filter and data types are specified in a sensor_map stanza in the driver stanza in your weewx.conf file. For example, on an Air/Sky setup: [WeatherFlowUDP] driver = user.weatherflowudp log_raw_packets = False udp_address = <broadcast> # udp_address = 0.0.0.0 # udp_address = 255.255.255.255 udp_port = 50222 udp_timeout = 90 share_socket = False [[sensor_map]] outTemp = air_temperature.AR-00004444.obs_air outHumidity = relative_humidity.AR-00004444.obs_air pressure = station_pressure.AR-00004444.obs_air # lightning_strikes = lightning_strike_count.AR-00004444.obs_air # avg_distance = lightning_strike_avg_distance.AR-00004444.obs_air outTempBatteryStatus = battery.AR-00004444.obs_air windSpeed = wind_speed.SK-00001234.rapid_wind windDir = wind_direction.SK-00001234.rapid_wind # lux = illuminance.SK-00001234.obs_sky UV = uv.SK-00001234.obs_sky rain = rain_accumulated.SK-00001234.obs_sky windBatteryStatus = battery.SK-00001234.obs_sky radiation = solar_radiation.SK-00001234.obs_sky # lightningYYY = distance.AR-00004444.evt_strike # lightningZZZ = energy.AR-00004444.evt_strike ==> If no sensor_map is specified, no data will be collected! <== For a sample Tempest sensor_map, see the file sample_Tempest_sensor_map on GitHub: https://github.com/captain-coredump/weatherflow-udp/blob/master/sample_Tempest_sensor_map To identify sensors, run the driver directly. For example: cd /home/weewx PYTHONPATH=/home/weewx/bin python ./bin/user/weatherflowudp.py To see the various options that are available when running the driver directly: PYTHONPATH=/home/weewx/bin python ./bin/user/weatherflowudp.py --help To identify the various observation_name options, start weewx with this station driver installed and it will write the entire matrix of available observation_names and sensor_types to syslog (or wherever weewx is configured to send log info). Apologies for the long observation_names, but I figured that it would be best if I used the documented field names from WeatherFlow's UDP packet specs (v37 at the time of writing) with underscores between words so that the names were consistent with their protocol documentation. See https://weatherflow.github.io/SmartWeather/api/udp.html Options: log_raw_packets = False Enable writing all raw UDP packets received to syslog, (or wherever weewx is configured to send log info). Will fill up your logs pretty quickly, so only use it as a debugging tool or to identify sensors. udp_address = <broadcast> # udp_address = 0.0.0.0 # udp_address = 255.255.255.255 This is the broadcast address that we should be listening on for packets. If the driver throws an error on start, try one of the other commented-out options (in order). This seems to be platform-specific. All three work on Debian Linux and my Raspberry Pi, but only 0.0.0.0 works on my Macbook running OS-X or MacOS. Don't ask about Windows, since I don't have a test platform to see if it will even work. udp_port = 50222 The IP port that we should be listening for UDP packets from. WeatherFlow's default is 50222. udp_timeout = 90 The number of seconds that we should wait for an incoming packet on the UDP socket before we give up and log an error into syslog. I cannot determine whether or not weewx cares whether a station driver is non-blocking or blocking, but encountered a situation in testing where the WeatherFlow Hub rebooted for a firmware update and it caused the driver to throw a timeout error and exit. I have no idea what the default timeout value even is, but decided to make it configurable in case it is important to someone else. My default of 90 seconds seems reasonable, with the Air sending observations every 60 seconds. If you are an old-school programmer like me who thinks that computers should wait forever until they receive data, the Python value "None" should disable the timeout. In any case, the driver will just log an error into syslog and keep on processing. It isn't like it is the end of the world if you pick a wrong value, but you may have a better chance of missing packets during the brief error trapping time with a really short duration. share_socket = False Whether or not the UDP socket should be shared with other local programs also listening for WeatherFlow packets. Default is False because I suspect that some obscure Python implementation will have problems sharing the socket. Feel free to set it to True if you have other apps running on your weewx host listening for WF UDP packets. Finally, let me add a thank you to Matthew Wall for the sensor map naming logic that I borrowed from his weewx-SDR station driver code: https://github.com/matthewwall/weewx-sdr I guess that I should also thank David St. John and the "dream team" at WeatherFlow for all of the hard work and forethought that they put into making this weather station a reality. I can't sing enough praises for whoever came up with the idea to send observation packets out live via UDP broadcasts, and think that they should be nominated for a Nobel Prize or something. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- This is the part where I am supposed to put in a PayPal link and ask for donations if you find this code useful. Since I am financially solvent (and would starve to death if I had to make a living as a programmer), :-) I would like to encourage anyone reading this to make a small donation to a local not-for-profit school, hospital, animal shelter, or other charity of your choice who appreciates philanthropic support.