matthewwall / weewx-sdr Goto Github PK
View Code? Open in Web Editor NEWweewx driver for software-defined radio
License: GNU General Public License v3.0
weewx driver for software-defined radio
License: GNU General Public License v3.0
weewx-sdr Copyright 2016-2022 Matthew Wall Distributed under terms of the GPLv3 This is a driver for weewx that captures data from software-defined radio. It works with open source rtl sdr software that in turn works with inexpensive, broad spectrum radio receivers such as the Realtek RTL2838UHIDIR. These devices cost about 20$US and are capable of receiving radio signals from weather stations, energy monitors, doorbells, and many other devices that use unlicensed spectrum such as 433MHz, 838MHz, and 900MHz frequencies. =============================================================================== Hardware Tested with the Realtek RTL2838UHIDIR. Should work with any software-defined radio that is compatible with the rtl-sdr software. Uses the modules in rtl_433 to recognize packets. Output from many different sensors is supported. To see the list of supported sensors, run the driver directly with the list-supported action. If a sensor is supported by rtl_433 but not by weewx-sdr, it is a fairly simple matter of writing a parser for that sensor within weewx-sdr. Things are a bit more complicated if a sensor is not supported by rtl_433. =============================================================================== Installation 0) install pre-requisites a) install weewx http://weewx.com/docs.html b) install rtl-sdr http://sdr.osmocom.org/trac/wiki/rtl-sdr c) install rtl_433 https://github.com/merbanan/rtl_433 1) download the driver wget -O weewx-sdr.zip https://github.com/matthewwall/weewx-sdr/archive/master.zip 2) install the driver sudo wee_extension --install weewx-sdr.zip 3) configure the driver sudo wee_config --reconfigure --driver=user.sdr --no-prompt 4) run the driver directly to identify the packets you want to capture cd /home/weewx sudo PYTHONPATH=bin python bin/user/sdr.py --cmd="rtl_433 -M utc -F json" 5) modify the [SDR] section of weewx.conf using a text editor - create a [[sensor_map]] for the data you want to capture - possibly modify the 'cmd' parameter 6) start weewx sudo /etc/init.d/weewx start =============================================================================== How to run the driver directly Run the driver directly for testing and diagnostics. For example, if weewx was installed using setup.py: sudo PYTHONPATH=/home/weewx/bin python /home/weewx/bin/user/sdr.py --help If weewx was installed from deb or rpm: sudo PYTHONPATH=/usr/share/weewx python /usr/share/weewx/user/sdr.py --help =============================================================================== Configuration Use the [SDR] section of the weewx configuration file (nominally weewx.conf) to adjust the driver configuration. The default configuration uses this command: rtl_433 -M utc -F json Specify different options using the cmd parameter. For example: [SDR] driver = user.sdr cmd = rtl_433 -M utc -F json -R 17 -R 44 -R 50 The rtl_433 executable emits data for many different types of sensors, some of which have similar output. Use the sensor_map to distinguish between sensors and map the output from rtl_433 to the database fields in weewx. Here are some examples: # collect data from Acurite 5n1 sensor 0BFA and t/h sensor 24A4 [SDR] driver = user.sdr [[sensor_map]] windDir = wind_dir.0BFA.Acurite5n1Packet windSpeed = wind_speed.0BFA.Acurite5n1Packet outTemp = temperature.0BFA.Acurite5n1Packet outHumidity = humidity.0BFA.Acurite5n1Packet rain_total = rain_total.0BFA.Acurite5n1Packet inTemp = temperature.24A4.AcuriteTowerPacket inHumidity = humidity.24A4.AcuriteTowerPacket # collect data from Acurite 986 fridge/freezer sensor set 1R and 2F [SDR] driver = user.sdr [[sensor_map]] extraTemp1 = temperature.1R.Acurite986Packet extraTemp2 = temperature.2F.Acurite986Packet # collect data from Acurite 06002RM t/h sensor 3067 [SDR] driver = user.sdr [[sensor_map]] inTemp = temperature.3067.AcuriteTowerPacket inHumidity = humidity.3067.AcuriteTowerPacket # collect data from two Hideki TS04 sensors with channel=1 and channel=2 [SDR] driver = user.sdr [[sensor_map]] outBatteryStatus = battery.1:9.HidekiTS04Packet outHumidity = humidity.1:9.HidekiTS04Packet outTemp = temperature.1:9.HidekiTS04Packet inBatteryStatus = battery.2:9.HidekiTS04Packet inHumidity = humidity.2:9.HidekiTS04Packet inTemp = temperature.2:9.HidekiTS04Packet # collect data from Fine Offset sensor cluster with serial number 0026 [SDR] driver = user.sdr [[sensor_map]] windGust = wind_gust.0026.FOWH1080Packet outBatteryStatus = battery.0026.FOWH1080Packet rain_total = rain_total.0026.FOWH1080Packet windSpeed = wind_speed.0026.FOWH1080Packet windDir = wind_dir.0026.FOWH1080Packet outHumidity = humidity.0026.FOWH1080Packet outTemp = temperature.0026.FOWH1080Packet To figure out the sensor identifiers, run the driver directly, possibly with the --debug option. Another option is to run weewx with the logging options for [SDR] enabled to display the sensors found by rtl_433, the sensor identifiers used by weewx, and the sensors actually recognized by weewx. [SDR] driver = user.sdr log_unknown_sensors = True log_unmapped_sensors = True By default the logging options are False. =============================================================================== How to diagnose problems First try running the rtl_433 application to be sure that it works properly: sudo rtl_433 Be sure that you are capturing data from the sensors you care about. To do this, you might want to experiment with some of the options to rtl_433. For example, this will eliminate extraneous output (-q), and use UTC for timestamps (-M utc): sudo rtl_433 -M utc -F json If you know exactly which sensors you want to monitor, try the -R option to reduce the clutter. For example, sudo rtl_433 -M utc -F json -R 9 -R 31 Once that is working, run the driver directly to be sure that it is collecting data from the rtl_433 application. sudo PYTHONPATH=/home/weewx/bin python /home/weewx/bin/user/sdr.py Make note of the sensor identifiers. Each identifier is a three-part string consisting of the observation, sensor id, and rf packet type, separated by periods. You need these in the sensor map to tell weewx the association between sensors and database fields. In the weewx configuration file, enter the rtl_433 options (if necessary) and the sensor map. Then run weewx directly in one shell while you monitor the weewx log in a separate shell: in shell 1: cd /home/weewx sudo ./bin/weewxd weewx.conf in shell 2: tail -f /var/log/syslog At this point, verify that the mapping you made in the weewx configuration file is working as you intend. You should see data from your sensors in the weewx LOOP and REC output. If not, check the log file. Use the logging options in the [SDR] section of the weewx configuration file to help figure out which sensors are captured, recognized, and parsed. Once you are satisfied with the output when running weewx directly, run weewx as a daemon and configure rc script or systemd to run weewx at system startup. sudo /etc/init.d/weewx start =============================================================================== Environment The driver invokes the rtl_433 executable, so the path to that executable and any shared library linkage must be defined in the environment in which weewx runs. For example, with rtl_433 and rtl-sdr installed like this: /opt/rtl-433/ /opt/rtl-sdr/ one would set the path like this: export PATH=/opt/rtl-433/bin:${PATH} export LD_LIBRARY_PATH=/opt/rtl-sdr/lib Typically this would be done in the rc script that starts weewx. If rtl_433 and rtl-sdr are install to /usr/local or /usr, then there should be no need to set the PATH or LD_LIBRARY_PATH before invoking weewx. If you cannot control the environment in which weewx runs, then you can specify the LD_LIBRARY_PATH and PATH in the weewx-sdr driver itself. For example: [SDR] driver = user.sdr cmd = rlt_433 -M utc -F json path = /opt/rtl-433/bin ld_library_path = /opt/libusb-1.0.20/lib:/opt/rtl-sdr/lib [[sensor_map]] ... =============================================================================== libusb I have had problems running rtl-sdr on systems with libusb 1.0.11. The rtl_433 command craps out with a segmentation fault, and the rtl_test command sometimes leaves the dongle in a weird state that can be cleared only by unplugging then replugging the dongle. Using a more recent version of libusb (e.g., 1.0.20) seems to clear things up. =============================================================================== Detecting new sensors After you have run for awhile, you might want to add new sensors to your system. If you have more than two or three sensors, it can be quite a challenge to pick through all of the output when you run the driver directly. This shows how to display only sensors that are detected but not yet part of your weewx configuration. First, shut down weewx so that you can talk to the SDR directly. Then run the SDR driver directly, but tell it to print out information only about sensors that you have not yet added to your weewx configuration: PYTHONPATH=/home/weewx/bin python /home/weewx/bin/user/sdr.py --config /home/weewx/weewx.conf --hide=out,parsed,mapped As always, unless the sensor identifier is marked on the sensor itself, you should turn on sensors one at a time, marking the outside of the sensor with its identifier. Then you can turn on all the sensors and place them, using the identifier on the sensor to distinguish which sensor is which when you map them to database fields in your weewx configuration. =============================================================================== Support for new sensor types To add support for new sensors, capture the output from rtl_433. To capture output, run the driver directly and hide known packets: PYTHONPATH=/home/weewx/bin python /home/weewx/bin/user/sdr.py --cmd "rtl_433 -M utc -F json" --hide parsed,out,empty This should emit a line for each unparsed type. For example: unparsed: ['{"time" : "2017-01-16 15:44:51", "temperature" : 54.140, "humidity" : 34, "id" : 221, "model" : "LaCrosse TX141TH-Bv2 sensor", "battery" : "OK", "test" : "Yes"}\n'] If there is no json ouput, remove the '-F json' option to see the (deprecated) non-json output: unparsed: ['2016-11-04 16:12:39 :\tFine Offset Electronics, WH2 Temperature/Humidity sensor\n', '\tID:\t 38\n', '\tTemperature:\t 54.4 C\n', '\tHumidity:\t 55 %\n'] If you are not comfortable writing your own parser, post the output to the issues section of the weewx-sdr repository and some helpful person might write the parser for you.
~/weewx-sdr/bin/user# PYTHONPATH=/home/weewx/bin/ python sdr.py --cmd="rtl_433 -q -U -F json -G"
File "sdr.py", line 1797
SyntaxError: Non-ASCII character '\xe2' in file sdr.py on line 1797, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
first double quote
Im trying to install w/ weewx but when following the realm it has me do this:
sudo PYTHONPATH=bin python bin/user/sdr.py
I get the following error:
Traceback (most recent call last):
File "bin/user/sdr.py", line 699, in
[--path=PATH] [--ld_library_path=LD_LIBRARY_PATH]""" % DEFAULT_CMD
ValueError: unsupported format character 'p' (0x70) at index 1
Im relatively new to this and can't figure out where to go from here...
Any help would be appreciated.
Thanks,
Brad
Hi,
I got today a UVN800 from oregon scientific.
Below the code to parse it, and sample data from the sensor :
`
class OSUV800Packet(Packet):
# 2017-01-30 22:00:12 : OS : UV800
# House Code: 207
# Channel: 1
# Battery: OK
# UV Index: 0
IDENTIFIER = "UV800"
PARSEINFO = {
'House Code': ['house_code', None, lambda x: int(x)],
'Channel': ['channel', None, lambda x: int(x)],
'Battery': ['battery', None, lambda x: 0 if x == 'OK' else 1],
'UV Index':
['UVIndex', re.compile('([\d.]+)'), lambda x: float(x)]}
@staticmethod
def parse_text(ts, payload, lines):
pkt = dict()
pkt['dateTime'] = ts
pkt['usUnits'] = weewx.METRICWX
pkt.update(Packet.parse_lines(lines, OSUV800Packet.PARSEINFO))
channel = pkt.pop('channel', 0)
code = pkt.pop('house_code', 0)
sensor_id = "%s:%s" % (channel, code)
pkt = Packet.add_identifiers(pkt, sensor_id, OSWGR800Packet.__name__)
return pkt
`
Hi,
i have an alecto V1 wind sensor.
Since there is no parser for it i would like to implement it but if i launch the sdr.py i can see that the wind sensor is "tagged" as out and not unparsed.
What does it means that is tgged with "out"?is it possible to write a parser for it?
Thank you in advance!
Added a new class for the WH31 Outdoor temperature sensor.
class AmbientWH31EPacket(Packet):
# 2019-02-15 13:37:02 : Ambient Weather WH31E
#"protocol" : 113
# {"time" : "2019-02-14 17:24:41.259441", "protocol" : 113, "model" : "AmbientWeather-WH31E", "id" : 24, "channel" : 1,
# "battery" : "OK", "temperature_C" : 6.000, "humidity" : 42, "data" :"2f00000000", "mic" : "CRC", "mod" : "FSK", "freq1" : 914.984,
# "freq2" : 914.906, "rssi" : -13.328, "snr" : 13.197, "noise" : -26.525}
IDENTIFIER = "AmbientWeather-WH31E"
@staticmethod
def parse_json(obj):
pkt = dict()
pkt['dateTime'] = Packet.parse_time(obj.get('time'))
pkt['usUnits'] = weewx.METRICWX
pkt['station_id'] = obj.get('id')
pkt['temperature'] = Packet.get_float(obj, 'temperature_C')
pkt['humidity'] = Packet.get_float(obj, 'humidity')
pkt['battery'] = 0 if obj.get('battery') == 'OK' else 1
return AmbientWH31EPacket.insert_ids(pkt)
@staticmethod
def insert_ids(pkt):
station_id = pkt.pop('station_id', '0000')
pkt = Packet.add_identifiers(pkt, station_id, AmbientWH31EPacket.__name__)
return pkt
Appears to be working... I'm not big on python so adjust or fix any errors as needed!!
Thank you again for your help and putting the time into this.
weewx-sdr ignores any -f switch in rtl_433 command.
A work around was to set the frequency default in /etc/rtl_433/rtl_433.conf
On 2018-04-23, the Acurite 986 fridge/freezer decoder in rtl_433 was changed to use structured data. Ref: merbanan/rtl_433#709.
Battery status was added. Also reception reliability may be slightly improved due to a workaround for the missing last bit. The decoder is now enabled by default.
New output:
{"time" : "2018-04-22 18:01:03", "model" : "Acurite 986 Sensor", "id" : 43248, "channel" : "1R", "temperature_F" : 69, "battery" : "OK", "status" : 0}
Hello,
I'm having trouble with weewx running weewx-sdr so I can see weewx's output.
I am able to run sdr.py successfully, however, when I try running weewx with the proper sensor_map, I get errors. Please see attached, and I thank you for any insight into what I'm doing wrong.
So - I have an Acurite 5n1 and when I define it as a station, I don't get a barometer reading, because the barometer is in the "base". I have a couple of possible sources, including from a nearby APRS station; but, that means I'd need to somehow get it into weewx.
Has anyone done this, or hacked weewx-sdr to grab data from either a file or a socket?
Hi Matthew,
as per the Alecto V1 Wind sensor,also the rain sensor is not parsed.
Below the output of the sdr.py driver
out: ['{"time" : "2019-01-20 15:29:21", "model" : "AlectoV1 Rain Sensor", "id" : 13, "channel" : 0, "battery" : "OK", "rain_total" : 15.500, "mic" : "CHECKSUM"}\n']
Please consider that the rain_total is the amount of the rain starting from the replacement of the battery.
If you wan to add the parser it will be very appreciated!
Thanks again!
Hi Mathew,
This is a preliminary report pending more information from the logs of the affected installation. It seems since a few days ago weewx is using insane amounts of memory. I had to restart weewx yesterday early morning and could see the RPi running out of both physical memory and swap space.
I now noticed again that the weather station was no longer reporting. Quickly logged in and top produced the following top lines:
top - 00:30:34 up 31 days, 7:13, 1 user, load average: 4,61, 5,79, 6,13
Tasks: 123 total, 1 running, 122 sleeping, 0 stopped, 0 zombie
%Cpu(s): 32,1 us, 5,1 sy, 0,0 ni, 62,7 id, 0,0 wa, 0,0 hi, 0,1 si, 0,0 st
KiB Mem: 882772 total, 866692 used, 16080 free, 34164 buffers
KiB Swap: 102396 total, 102336 used, 60 free. 108372 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20098 root 20 0 1269928 555880 3424 S 116,1 63,0 1037:09 python
19906 mysql 20 0 364808 65220 4160 S 17,4 7,4 140:36.68 mysqld
20102 root 20 0 37312 9688 700 S 8,2 1,1 86:55.60 rtl_433
The only change compared to previous weeks is that I switched to MySQL as a backend and updated weewx-sdr.
I cannot confirm yet the exact source of the problem, but I will be updating this issue later tomorrow when I get time to read the log.
Thanks
Found a few issues from users on the forum and made an attempt to fix. Waiting on test results for the oregon scientific wgr and pgr sensors. I will create a pull request from my fork when done. Added an 'if' statement to get the humidity from the Nexus, not sure if this is correct. Maybe a new device class?
Andy
0.45 10aug18
Thank you for the recent commit that corrects my conversion from lux to solar radiation in the sdr driver. I understand that there is no direct conversion from lux to solar radiation since they are different things. The hardware in question is a Fine Offset WS-2902A. The outdoor sensor array returns lux and the console converts that value to W/M^2, solar radiation. Not ideal, but there it is. So, I'm faced with accounting for this in Weewx. So, I have two questions.
First, I'm trying to grapple with using the StdWXCalculate service to do this, but I'm not clear how that would be done. From the documentation that service doesn't seem to handle radiation. Can you give me a pointer or suggest a better way to do this?
Second, it's clear that rtl_433 sometimes returns no value for light from the WH65B. Where ever this calculation is done, will I have to check for none before performing it? Thanks.
['{"time" : "2019-02-15 13:43:25", "brand" : "OS", "model" : "THGR968", "id" : 187, "channel" : 1, "battery" : "OK", "temperature_C" : 16.500, "humidity" : 11}\n', '{"time" : "2019-02-15 13:43:26", "brand" : "OS", "model" : "THGR968", "id" : 187, "channel" : 1, "battery" : "OK", "temperature_C" : 16.500, "humidity" : 11}\n']
['{"time" : "2019-02-15 14:32:51", "brand" : "OS", "model" : "RGR968", "id" : 48, "channel" : 0, "battery" : "OK", "rain_rate" : 0.000, "total_rain" : 6935.100}\n', '{"time" : "2019-02-15 14:32:51", "brand" : "OS", "model" : "RGR968", "id" : 48, "channel" : 0, "battery" : "OK", "rain_rate" : 0.000, "total_rain" : 6935.100}\n',
I was trying to modify an existing parser for OS, but without success....
Request to incorporate support for the LaCrosse TX4U temperature/humidity sensor into your mainline code branch...
Code attached for sdr.py which adds this support. Happy to figure out how to pull/commit the code directly:
class LaCrosseTXPacket(Packet):
# {"time" : "2017-07-30 21:11:19", "model" : "LaCrosse TX Sensor", "id" : 127, "humidity" : 34.000}\n', '{"time" : "2017-07-30 21:11:19", "model" : "LaCrosse TX Sensor", "id" : 127, "humidity" : 34.000}\n', '{"time" : "2017-07-30 21:11:19", "model" : "LaCrosse TX Sensor", "id" : 127, "temperature_C" : 27.100}\n', '{"time" : "2017-07-30 21:11:19", "model" : "LaCrosse TX Sensor", "id" : 127, "temperature_C" : 27.100}
IDENTIFIER = "LaCrosse TX Sensor"
@staticmethod
def parse_json(obj):
pkt = dict()
pkt['dateTime'] = Packet.parse_time(obj.get('time'))
pkt['usUnits'] = weewx.METRIC
sensor_id = obj.get('id')
pkt['temperature'] = Packet.get_float(obj, 'temperature_C')
pkt['humidity'] = Packet.get_float(obj, 'humidity')
pkt = Packet.add_identifiers(pkt, sensor_id, LaCrosseTXPacket.__name__)
return pkt
I have weewx-sdr working with my Fine Offset WH65B. Everything looks good except for random crashes in weewx with "ZeroDivisionError" errors.
example:
File "./bin/weewxd", line 64, in <module>
weewx.engine.main(options, args)
File "/home/weewx/bin/weewx/engine.py", line 890, in main
engine.run()
File "/home/weewx/bin/weewx/engine.py", line 191, in run
self.dispatchEvent(weewx.Event(weewx.NEW_LOOP_PACKET, packet=packet))
File "/home/weewx/bin/weewx/engine.py", line 224, in dispatchEvent
callback(event)
File "/home/weewx/bin/weewx/engine.py", line 540, in new_loop_packet
self.accumulator = self._new_accumulator(event.packet['dateTime'])
File "/home/weewx/bin/weewx/engine.py", line 650, in _new_accumulator
self.archive_interval)
File "/home/weewx/bin/weeutil/weeutil.py", line 220, in startOfInterval
m = int(time_tt.tm_min // interval_m * interval_m)
ZeroDivisionError: integer division or modulo by zero
what stands out is the "self._new_accumulator(event.packet['dateTime'])" line.
When I run the weewx-sdr driver directly, I see output from my sensor array as follows:
out: ['{"time" : "2019-02-14 01:10:14.653076", "protocol" : 78, "model" : "Fine Offset WH65B", "id" : 10, "temperature_C" : 1.500, "humidity" : 51, "wind_dir_deg" : 283, "wind_speed_ms" : 1.721, "gust_speed_ms" : 2.040, "rainfall_mm" : 407.416, "uv" : 2, "uvi" : 0, "light_lux" : 0.000, "battery" : "OK", "mic" : "CRC", "mod" : "FSK", "freq1" : 914.983, "freq2" : 914.911, "rssi" : -12.775, "snr" : 14.586, "noise" : -27.362}]
parsed: {'rain_total.10.FOWH65BPacket': 407.416, 'uv.10.FOWH65BPacket': 2.0, 'wind_dir.10.FOWH65BPacket': 283.0, 'uv_index.10.FOWH65BPacket': 0.0, 'light.10.FOWH65BPacket': 0.0, 'battery.10.FOWH65BPacket': 0, 'wind_gust.10.FOWH65BPacket': 2.04, 'temperature.10.FOWH65BPacket': 1.5, 'dateTime': 1550106614, 'humidity.10.FOWH65BPacket': 51.0, 'usUnits': 17, 'wind_speed.10.FOWH65BPacket': 1.721}
my sensor map is:
[[sensor_map]]
light = light.10.FOWH65BPacket
uv = uv.10.FOWH65BPacket
rain = rain_total.10.FOWH65BPacket
windDir = wind_dir.10.FOWH65BPacket
windSpeed = wind_speed.10.FOWH65BPacket
windGust = wind_gust.10.FOWH65BPacket
outHumidity = humidity.10.FOWH65BPacket
outTemp = temperature.10.FOWH65BPacket
txBatteryStatus = battery.10.FOWH65BPacket
There are a few items in the "parsed" stanza without sensor identifiers (usUnits, dateTime) I assume that since they do not have identifiers, I do not need to manually map them in the sensor_map? Did not see anything in the documentation to confirm or deny this, however the mention of dateTime in the error has me second guessing...
Any ideas?
Hi,
Anyone willing to add these 2 sensors to sdr.py? Unfortunately my knowledge is limited so I might cause more damage than good if I try.
Nov 3 06:36:26 Weather weewx[16727]: sdr: MainThread: lines=['2016-11-03 04:36:23 \t:\tOS :\tPCR800\n', '\tHouse Code:\t 93\n', '\tChannel:\t 0\n', '\tBattery:\t OK\n', '\tRain Rate:\t 0.0 in/hr\n', '\tTotal Rain:\t 41.0 in\n']
Nov 3 06:36:26 Weather weewx[16727]: sdr: MainThread: ts=1478147783 payload=OS :#011PCR800
Nov 3 06:36:26 Weather weewx[16727]: sdr: MainThread: unhandled message format: ts=1478147783 payload=OS :#011PCR800
Nov 3 06:36:29 Weather weewx[16727]: sdr: MainThread: lines=[]
Nov 3 06:36:32 Weather weewx[16727]: sdr: MainThread: lines=[]
Nov 3 06:36:37 Weather weewx[16727]: sdr: MainThread: lines=['2016-11-03 04:36:34 \t:\tOS :\tWGR800\n', '\tHouse Code:\t 85\n', '\tChannel:\t 0\n', '\tBattery:\t OK\n', '\tGust:\t 1.1 m/s\n', '\tAverage:\t 1.1 m/s\n', '\tDirection:\t 22.5 degrees\n']
Nov 3 06:36:37 Weather weewx[16727]: sdr: MainThread: ts=1478147794 payload=OS :#011WGR800
Nov 3 06:36:37 Weather weewx[16727]: sdr: MainThread: unhandled message format: ts=1478147794 payload=OS :#011WGR800
Thanks
root@WEATHERCAM2:/usr/share/weewx# PYTHONPATH=/usr/share/weewx python /usr/share/weewx/user/sdr.py --cmd="rtl_433 -M utc -F json -G" --hide out,empty
parsed: {'humidity.0:179.OSBTHR968Packet': 54.0, 'pressure.0:179.OSBTHR968Packet': None, 'battery.0:179.OSBTHR968Packet': 1, 'dateTime': 1551877367, 'temperature.0:179.OSBTHR968Packet': 19.9, 'usUnits': 16}
parsed: {'humidity.0:179.OSBTHR968Packet': 54.0, 'pressure.0:179.OSBTHR968Packet': None, 'battery.0:179.OSBTHR968Packet': 1, 'dateTime': 1551877367, 'temperature.0:179.OSBTHR968Packet': 19.9, 'usUnits': 16}
starting plain rtl_433 shows that pressure values are sent:
root@WEATHERCAM2:/usr/share/weewx# rtl_433
rtl_433 version 18.12-91-gcab7ca9 branch master at 201902131710 inputs file rtl_tcp RTL-SDR
Trying conf file at "rtl_433.conf"...
Trying conf file at "/root/.config/rtl_433/rtl_433.conf"...
Trying conf file at "/usr/local/etc/rtl_433/rtl_433.conf"...
Trying conf file at "/etc/rtl_433/rtl_433.conf"...
Registered 96 out of 120 device decoding protocols [ 1-4 8 11-12 15-17 19-21 23 25-26 29-36 38-60 62-64 67-71 73-100 102-103 108-116 119 ]
Detached kernel driver
Found Rafael Micro R820T tuner
Exact sample rate is: 250000.000414 Hz
[R82XX] PLL not locked!
Sample rate set to 250000 S/s.
Tuner gain set to Auto.
Tuned to 433.920MHz.
time : 2019-03-06 14:05:19 brand : OS
model : BHTR968 House Code: 179
Channel : 0 Battery : LOW Celsius : 19.80 C Humidity : 54 % Pressure : 974 hPa
time : 2019-03-06 14:05:19 brand : OS
model : BHTR968 House Code: 179
Channel : 0 Battery : LOW Celsius : 19.80 C Humidity : 54 % Pressure : 974 hPa
json:
{"time" : "2019-03-06 13:27:23", "brand" : "OS", "model" : "BHTR968", "id" : 179, "channel" : 0, "battery" : "LOW", "temperature_C" : 19.800, "humidity" : 54, "pressure_hPa" : 974.000}
Hello,
I recently purchased AcuRite 06044M and would be super appreciative if someone with the skills could write a parser :)
sudo PYTHONPATH=/usr/share/weewx python /usr/share/weewx/user/sdr.py --cmd "rtl_433 -q -U -G" --hide parsed,out,empty
unparsed: ['2017-01-12 01:35:20 :\tAcurite tower sensor \t:\t5585 \t:\tC\n', '\tTemperature:\t 19.2 C\n', '\tHumidity:\t 40\n', '\tBattery:\t 0\n', '\t:\t68\n']
unparsed: ['2017-01-12 01:35:22 :\tAcurite tower sensor \t:\t521 \t:\tA\n', '\tTemperature:\t 1.9 C\n', '\tHumidity:\t 61\n', '\tBattery:\t 0\n', '\t:\t68\n']
Thanks!
This one's kinda bizzare - also going to post in the Google Group. I spent several hours today chasing this.
If I use the SQLite Database, weewx/rtl/sdr runs just fine. But, if I specify a MySQL database, on a different server, the main thread starts, starts rtl_433 and then IMMEDIATELY shuts it down.
Anyone seen this before?
This packet report 10x the fallen rain. the station gives the rain in mm and the driver in cm.
Since DST in Europe, my weewx-sdr is reporting the incorrect timezone
Apr 8 10:38:09 raspberrypi weewx[705]: sdr: MainThread: lines=['{"time" : "2019-04-08 10:38:06", "model" : "Bresser-5in1", "id" : 144, "temperature_C" : 11.300, "humidity" : 83, "wind_gust" : 1.400, "wind_speed" : 1.500, "wind_dir_deg" : 90.000, "rain_mm" : 42.000, "mic" : "CHECKSUM"}\n']
Apr 8 10:38:09 raspberrypi weewx[705]: sdr: MainThread: packet={'outHumidity': 83.0, 'dateTime': 1554719886, 'windDir': 90.0, 'outTemp': 11.3, 'windSpeed': 1.5, 'rain_total': 42.0, 'usUnits': 17}
Apr 8 10:38:10 raspberrypi weewx[705]: extrasensors: found humidity value of 46.4000015259 %
Apr 8 10:38:10 raspberrypi weewx[705]: extrasensors: found temperature value of 20.8999996185 C
Apr 8 10:38:10 raspberrypi weewx[705]: restx: MQTT: Published record 2019-04-08 11:38:06 IST (1554719886)
I can see the time from the weather station is correct (10:38:06) but the EPOCH time on the sdr driver is 1554719886 which is 11:38:06
Any ideas?
root@raspberrypi:~# date
Mon 8 Apr 10:41:19 IST 2019
root@raspberrypi:~#
I have confirmed that my settings are correct on the Pi for timezone and python does print out the correct time
root@raspberrypi:~# python -c "import time; print time.time()"
1554716534.58
root@raspberrypi:~# python -c "import time; print time.timezone"
0
Seems like there is an extra tab at the beginning of the line. Version 0.32, line 1475:
Aug 9 09:12:48 WXpi3 weewx[7950]: **** File "/usr/share/weewx/user/sdr.py", line 1475
Aug 9 09:12:48 WXpi3 weewx[7950]: **** pkt['pressure'] = Packet.get_float(obj, 'pressure_hPa')
Aug 9 09:12:48 WXpi3 weewx[7950]: **** ^
Aug 9 09:12:48 WXpi3 weewx[7950]: **** IndentationError: unexpected indent
Aug 9 09:12:48 WXpi3 weewx[7950]: **** Exiting.
I removed the tab on my installed file, and it appears to be working (with a caveat that I don't use that device on my WX station).....
I get this eeror when i try to run sdr driver:
weewxd /etc/weewx/weewx.conf
Traceback (most recent call last):
File "/usr/bin/weewxd", line 64, in
weewx.engine.main(options, args)
File "/usr/share/weewx/weewx/engine.py", line 859, in main
engine.run()
File "/usr/share/weewx/weewx/engine.py", line 185, in run
self.dispatchEvent(weewx.Event(weewx.NEW_LOOP_PACKET, packet=packet))
File "/usr/share/weewx/weewx/engine.py", line 218, in dispatchEvent
callback(event)
File "/usr/share/weewx/weewx/engine.py", line 313, in new_loop_packet
if event.packet['usUnits'] == self.target_unit: return
KeyError: 'usUnits'
WeatherFlow is finally about to ship their crowd-funded PWS. Their basic architecture is a wireless network hub device, with Bluetooth BLE links to one or more "Air" and "Sky" outdoor devices that each contain groups of sensors. They have already published all kinds of cloud API's (yawn), and are promising to publish their BLE API in the near future.
TL;DR - They are also doing something that is interesting for easily capturing station data, namely broadcasting UDP packets (apparently as they arrive at their wireless network hub) onto the local network segment for any device to see. No fake DNS and web servers, no pass-through network ports, just listen for the UDP packets and decode the JSON goodness! I have simplified rtl_433 down to this:
#!/usr/bin/python
from socket import *
s=socket(AF_INET, SOCK_DGRAM)
s.bind(('255.255.255.255',50222))
while True:
m=s.recvfrom(1024)
print m[0]
This is what an output packet from an "Air" device should look like:
{"serial_number":"AR-00009876","type":"obs_air","obs":[[1502287861,1009.30,21.90,85,0,0,3.46,1]],"firmware_revision":12}
(All of their other status packets are pure JSON, but for some reason they chose to send out observations as a list in the "obs" field. The format is completely documented in their API docs.)
Long story short, this shares so much in common with the SDR broadcast decoder that I'm wondering if this SDR station code should be renamed to a medium-agnostic broadcast decoder, and encourage development of external programs other than rtl_433 as input?
I'm not overly familiar with all of the available weewx station input types, but seeing the simplicity of grabbing broadcast packets off of the wire I think that I may actually start to send similar packets from my growing collection of DIY IoT sensors and use this same basic format. Hence, thinking that the sensor-mapping feature in the SDR station code is way more flexible than my half-finished station driver with everything hard-coded. If there's a more appropriate way of doing this, I'm all ears.....
Approximately once every 2-3 days, weewx dies on me with the following:
Oct 10 09:18:51 nas weewx[30868]: restx: WOW: Failed to publish record 2018-10-10 09:18:00 BST (1539159480): Failed upload after 3 tries
Oct 10 09:18:51 nas weewx[30868]: sdr: MainThread: shutdown process rtl_433 -q -U -F json
Oct 10 09:19:06 nas weewx[30868]: sdr: MainThread: timed out waiting for stderr-thread
Oct 10 09:19:06 nas weewx[30868]: engine: Caught unrecoverable exception in engine:
Oct 10 09:19:06 nas weewx[30868]: **** 'int' object has no attribute 'upper'
Oct 10 09:19:06 nas weewx[30868]: **** Traceback (most recent call last):
Oct 10 09:19:06 nas weewx[30868]: **** File "/home/weewx/bin/weewx/engine.py", line 859, in main
Oct 10 09:19:06 nas weewx[30868]: **** engine.run()
Oct 10 09:19:06 nas weewx[30868]: **** File "/home/weewx/bin/weewx/engine.py", line 182, in run
Oct 10 09:19:06 nas weewx[30868]: **** for packet in self.console.genLoopPackets():
Oct 10 09:19:06 nas weewx[30868]: **** File "/home/weewx/bin/user/sdr.py", line 1921, in genLoopPackets
Oct 10 09:19:06 nas weewx[30868]: **** for packet in PacketFactory.create(lines):
Oct 10 09:19:06 nas weewx[30868]: **** File "/home/weewx/bin/user/sdr.py", line 1792, in create
Oct 10 09:19:06 nas weewx[30868]: **** pkt = PacketFactory.parse_json(lines)
Oct 10 09:19:06 nas weewx[30868]: **** File "/home/weewx/bin/user/sdr.py", line 1808, in parse_json
Oct 10 09:19:06 nas weewx[30868]: **** return parser.parse_json(obj)
Oct 10 09:19:06 nas weewx[30868]: **** File "/home/weewx/bin/user/sdr.py", line 575, in parse_json
Oct 10 09:19:06 nas weewx[30868]: **** return Acurite.insert_ids(pkt, Acurite986Packet.name)
Oct 10 09:19:06 nas weewx[30868]: **** File "/home/weewx/bin/user/sdr.py", line 330, in insert_ids
Oct 10 09:19:06 nas weewx[30868]: **** sensor_id = pkt.pop('hardware_id', '0000').upper()
Oct 10 09:19:06 nas weewx[30868]: **** AttributeError: 'int' object has no attribute 'upper'
Oct 10 09:19:06 nas weewx[30868]: **** Exiting.
Hello,
I attempted to install on a clean copy of Ubuntu 18.04 via the instructions in the readme but I am failing on step 4. Weewx installed itself in /etc/weewx instead of /home/weewx which could be the problem.
I tried running the sudo PYTHONPATH=bin python bin/user/sdr.py --cmd="rtl_433 -M utc -F json -G"
command but sdr.py wasn't found. Using find, i found it in /usr/share/weewx/user/sdr.py and modified the command but now can't import weewx.drivers.
atomicpi1@atomicpi1:/etc/weewx$ sudo PYTHONPATH=bin python /usr/share/weewx/user/sdr.py --cmd="rtl_433 -M utc -F json -G" Traceback (most recent call last): File "/usr/share/weewx/user/sdr.py", line 87, in <module> import weewx.drivers
I tried running through steps 1-4 in my home directory, /etc/weewx, and /usr/share/weewx but no luck.
Any ideas what to try next?
Hi
Could you please add support for Calibeur RF-104?
Data look like this:
out: ['2016-11-01 01:25:28 :\tCalibeur RF-104\n', '\tID:\t 1\n', '\tTemperature:\t 1.8 C\n', '\tHumidity:\t 71 %\n']
Thanks!
I have issues with my weather-station. So I have to restart it from time to time. After resetting it, it starts sending with a new ID and so I have to run the driver directly to get the ID and to edit the weewx.conf.
Is there any possibility to set a wildcard? Like so:
rain_total = rain_total.*.FOWH1080Packet
Regards, Willie
Hello,
unfortunately I can not find any sensor for my ws-1041.
is there any other way?
Running
PYTHONPATH=bin python bin/user/sdr.py --cmd "rtl_433 -q -U -F json -R 32"
with an Ambient Weather WS2080 in the area I'm seeing JSON output as follows:
out: ['{"time" : "2017-06-08 06:27:13",
"model" : "Fine Offset Electronics WH1080/WH3080 Weather Station",
"msg_type" : 0, "id" : 38, "temperature_C" : 20.400, "humidity" : 66,
"direction_str" : "N", "direction_deg" : "0", "speed" : 0.000, "gust" : 1.224,
"rain" : 407.400, "battery" : "OK"}\n']
(and occasionally a second msg_type:1 that seems to be WWVB)
I expected to get output like is discussed in Configuration in the readme; I took the above output to indicate something is wrong with the parser.
If I understand correctly it's intended weewx-sdr supports this device (class FOWHx080Packet) but it looks like the IDENTIFIER value is not an exact match (extra spaces), if not other parts of the mapping like id.
I'd be happy to fix support if you agree that's a starting point. This is the first day I've laid eyes on weewx, rtl-sdr, sdr_433, and weewx-sdr and don't want to take device support down the wrong path. I'd like to get this device working though!
When manually running sudo PYTHONPATH=/usr/share/weewx python /usr/share/weewx/user/sdr.py --cmd="rtl_433 -q -U -F json -G"
I receive the following:
out: ['AcuRite Rain Gauge Total Rain is 1350.5mm\n', 'Raw Message: 34 4a 8d 00 00\n', '{"time" : "2017-09-14 20:24:43", "model" : "WT450 sensor", "id" : 1, "channel" : 2, "battery" : "OK", "temperature_C" : 25.090, "humidity" : 49}\n', '{"time" : "2017-09-14 20:24:44", "model" : "WT450 sensor", "id" : 1, "channel" : 2, "battery" : "OK", "temperature_C" : 25.110, "humidity" : 49}\n', '{"time" : "2017-09-14 20:24:44", "model" : "WT450 sensor", "id" : 1, "channel" : 2, "battery" : "OK", "temperature_C" : 25.120, "humidity" : 49}\n']
When running the weewx service I see "parse_json: unknown model WT450 sensor" in my syslog on my Rpi.
I think I need a parser, anyone ?:)
brg
Magnus
/Noob
5n1 parsing changed:
https://groups.google.com/d/msg/weewx-user/lwgSFCjMyEc/b1m6B1tkDgAJ
Command sysntax changed
root@KCAMEADO21:~# PYTHONPATH=/home/weewx/bin/ python sdr.py --cmd="rtl_433 -q -U -F json -G"
err: rtl_433 version 18.12-60-gccbc568 branch master at 201812311225
err: quiet option (-q) is default and deprecated. See -v to increase verbosity
err: UTC mode option (-U) is deprecated. Please use "-M utc"
This seems to work
root@KCAMEADO21:~# PYTHONPATH=/home/weewx/bin/ python sdr.py --cmd="rtl_433 -q -M utc -F json -G"
Hi,
I started using sdr on my pi over the week-end. I found a new hardware.
Below is the parser:
`
class RubicsonTempPacket(Packet):
# 2017-01-15 14:49:03 : Rubicson Temperature Sensor
# House Code: 14
# Channel: 1
# Battery: OK
# Temperature: 4.5 C
# CRC: OK
IDENTIFIER = "Rubicson Temperature Sensor"
PARSEINFO = {
'House Code': ['house_code', None, lambda x: int(x)],
'Channel': ['channel', None, lambda x: int(x)],
'Battery': ['battery', None, lambda x: 0 if x == 'OK' else 1],
'Temperature': ['temperature', re.compile('([\d.]+) C'), lambda x: float(x)]}
@staticmethod
def parse_text(ts, payload, lines):
pkt = dict()
pkt['dateTime'] = ts
pkt['usUnits'] = weewx.METRICWX
pkt.update(Packet.parse_lines(lines, RubicsonTempPacket.PARSEINFO))
channel = pkt.pop('channel', 0)
code = pkt.pop('house_code', 0)
sensor_id = "%s:%s" % (channel, code)
pkt = Packet.add_identifiers(pkt, sensor_id, RubicsonTempPacket.__name__)
return pkt
`
Battling to get a parser for my Bresser 5in1 weather station working
class Bresser5in1(Packet):
# 'time' => '2018-12-15 16:04:04',
# 'model' => 'Bresser-5in1',
# 'id' => 118,
# 'temperature_C' => 6.4000000000000003552713678800500929355621337890625,
# 'humidity' => 87,
# 'wind_gust' => 2.79999999999999982236431605997495353221893310546875,
# 'wind_speed' => 2.899999999999999911182158029987476766109466552734375,
# 'wind_dir_deg' => 315,
# 'rain_mm' => 10.800000000000000710542735760100185871124267578125,
# 'data' => 'e7897fd71fd6ef9bff78f7feff18768028e02910640087080100',
# 'mic' => 'CHECKSUM',
# ’{“time" : "2018-12-15 16:04:04", "model" : "Bresser-5in1", "id" : 118, "temperature_C" : 6.400, "humidity" : 87, "wind_gust" : 2.800, "wind_speed" : 2.900, "wind_dir_deg" : 315.000, "rain_mm" : 10.800, "data" : "e7897fd71fd6ef9bff78f7feff18768028e02910640087080100", "mic" : "CHECKSUM"}#012'
IDENTIFIER = "Bresser-5in1"
@staticmethod
def parse_json(obj):
pkt = dict()
pkt['dateTime'] = Packet.parse_time(obj.get('time'))
pkt['usUnits'] = weewx.METRICWX
pkt['station_id'] = obj.get('id')
pkt['temperature'] = Packet.get_float(obj, 'temperature_C')
pkt['humidity'] = Packet.get_float(obj, 'humidity')
pkt['wind_gust'] = Packet.get_float(obj, 'gust_speed_ms')
pkt['wind_speed'] = Packet.get_float(obj, 'wind_speed_ms')
pkt['wind_dir'] = Packet.get_float(obj, 'wind_dir_deg')
pkt['rain_total'] = Packet.get_float(obj, 'rainfall_mm')
pkt['uv'] = Packet.get_float(obj, 'uv')
pkt['uv_index'] = Packet.get_float(obj, 'uvi')
return Bresser5in1Packet.insert_ids(pkt)
@staticmethod
def insert_ids(pkt):
station_id = pkt.pop('station_id', '0000')
pkt = Packet.add_identifiers(pkt, station_id, Bresser5in1Packet.__name__)
return pkt
But it just returns errors:
Dec 15 17:21:56 raspberrypi weewx[13906]: sdr: MainThread: lines=['{"time" : "2018-12-15 17:21:52", "model" : "Bresser-5in1", "id" : 118, "temperature_C" : 6.300, "humidity" : 89, "wind_gust" : 2.400, "wind_speed" : 2.400, "wind_dir_deg" : 292.500, "rain_mm" : 11.200, "data" : "e5897fe12fdbef9cff76edfeff1a76801ed02410630089120100", "mic" : "CHECKSUM"}\n']
Dec 15 17:21:56 raspberrypi weewx[13906]: sdr: MainThread: parse_json: unknown model Bresser-5in1
Dec 15 17:21:56 raspberrypi weewx[13906]: sdr: MainThread: punt unrecognized line '{"time" : "2018-12-15 17:21:52", "model" : "Bresser-5in1", "id" : 118, "temperature_C" : 6.300, "humidity" : 89, "wind_gust" : 2.400, "wind_speed" : 2.400, "wind_dir_deg" : 292.500, "rain_mm" : 11.200, "data" : "e5897fe12fdbef9cff76edfeff1a76801ed02410630089120100", "mic" : "CHECKSUM"}#12'
Dec 15 17:21:59 raspberrypi weewx[13906]: sdr: MainThread: lines=[]
Dec 15 17:22:02 raspberrypi weewx[13906]: sdr: MainThread: lines=[]
Dec 15 17:22:05 raspberrypi weewx[13906]: sdr: MainThread: lines=[]
Dec 15 17:22:08 raspberrypi weewx[13906]: sdr: MainThread: lines=['{"time" : "2018-12-15 17:22:04", "model" : "Bresser-5in1", "id" : 118, "temperature_C" : 6.100, "humidity" : 89, "wind_gust" : 2.800, "wind_speed" : 2.200, "wind_dir_deg" : 22.500, "rain_mm" : 11.200, "data" : "ea897fd7efddef9eff76edfeff15768028102210610089120100", "mic" : "CHECKSUM"}\n']
Dec 15 17:22:08 raspberrypi weewx[13906]: sdr: MainThread: parse_json: unknown model Bresser-5in1
Dec 15 17:22:08 raspberrypi weewx[13906]: sdr: MainThread: punt unrecognized line '{"time" : "2018-12-15 17:22:04", "model" : "Bresser-5in1", "id" : 118, "temperature_C" : 6.100, "humidity" : 89, "wind_gust" : 2.800, "wind_speed" : 2.200, "wind_dir_deg" : 22.500, "rain_mm" : 11.200, "data" : "ea897fd7efddef9eff76edfeff15768028102210610089120100", "mic" : "CHECKSUM"}#12'
Dec 15 17:22:11 raspberrypi weewx[13906]: sdr: MainThread: lines=[]
Dec 15 17:22:14 raspberrypi weewx[13906]: sdr: MainThread: lines=[]
Dec 15 17:22:19 raspberrypi weewx[13906]: sdr: MainThread: lines=['{"time" : "2018-12-15 17:22:16", "model" : "Bresser-5in1", "id" : 118, "temperature_C" : 6.200, "humidity" : 88, "wind_gust" : 2.800, "wind_speed" : 2.500, "wind_dir_deg" : 337.500, "rain_mm" : 11.200, "data" : "e7897fd70fdaef9dff77edfeff18768028f02510620088120100", "mic" : "CHECKSUM"}\n']
I have 8 wH31E that I use with WeeWx. 7 of them work as expected.
Ive added them to my database schema but one of them is throwing celsius values in for fahrenheit.
My 'freezer' is showing that its say -14F, when its actually -14 temp_C
From my log and weewx
Apr 12 14:32:19 raspberrypi weewx[11956]: sdr: MainThread: lines=['{"time" : "2019-04-12 18:32:15", "model" : "AmbientWeather-WH31E", "id" : 94, "channel" : 8, "battery" : "OK", "temperature_C" : -11.800, "humidity" : 69, "data" : "9b00000000", "mic" : "CRC"}\n', '{"time" : "2019-04-12 18:32:15", "model" : "AmbientWeather-WH31E", "id" : 94, "channel" : 8, "battery" : "OK", "temperature_C" : -11.800, "humidity" : 69, "data" : "9b00000000", "mic" : "CRC"}\n']
LOOP: 2019-04-12 14:33:23 EDT (1555094003) dateTime: 1555094003, extraTemp8: -12.0, maxSolarRad: None, rainRate: 0, usUnits: 1
I wish to add a WT0124 Pool Thermometer to my Weewx system, the sensor is now supported in rtl_433 but not in sdr.py.
The only output when manually running sdr.py is an 'out' line.
$ sudo PYTHONPATH=bin python bin/user/sdr.py --cmd="rtl_433 -M utc -F json -R 109"
out: ['{"time" : "2019-04-23 12:28:52", "model" : "WT0124 Pool Thermometer", "rid" : 122, "channel" : 1, "temperature_C" : 22.800, "mic" : "CHECKSUM", "data" : 172}\n']
$ sudo PYTHONPATH=bin python bin/user/sdr.py --cmd="rtl_433 -M utc -R 109"
out: ['_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n', 'time : 2019-04-23 12:40:22\n', 'model : WT0124 Pool Thermometer Random ID : 122 Channel : 1 Temperature: 23.0 C Integrity : CHECKSUM\n', 'Data : 172\n']
Any chance of adding this ??
Gary
Current logging of unmapped packets looks like this:
loginf("unmapped: %s (%s)" % (lines, packet))
But due to the surrounding logic, we already know that "packet" will always be empty. It would be more useful to log the original "packet" before it underwent map_to_fields() that makes it empty.
(This is especially useful if you want to make a fake sensor mapping entry for something that you know about but just don't care about, but you still want to log truly unmapped sensors. For example, I see some other weather stations on my radio, but I don't map them. Without the fake sensor mapping entries, they clutter my log file.)
Jan 22 05:40:46 weewx-prod weewx[9670]: **** File "/home/weewx/bin/user/sdr.py", line 493, in parse_json
Jan 22 05:40:46 weewx-prod weewx[9670]: **** pkt['wind_speed'] = get_wind_speed(obj)
Hi!
I can´t publish the sensors map, perhaps my weewx directory root is strange!?
Pse, look for the attach... errors!Any help?
Tks!
Jo
Hi,
I'm using a FineOffset WH3080 USB station to record values for a while but now it's broken and i switched to SDR. Now I'm having in the weewx db rain values in centimeters instead of millimeters:
This is the db query:
select datetime(datetime,'unixepoch','localtime') dt, rain,rainRate from archive where dt>'2018-04-1 00:00' and rain>0 order by datetime;
With USB station:
2018-04-10 07:48:01|0.0300000000000011|0.120000000000005
2018-04-11 22:47:51|0.029999999999994|0.119999999999976
2018-04-12 12:27:52|0.0300000000000011|0.120000000000005
2018-04-12 13:07:52|0.0300000000000011|0.120000000000005
2018-04-12 13:17:58|0.0300000000000011|0.240000000000009
With SDR:
2018-05-15 22:50:00|0.299999999999997|4.799999995104
2018-05-15 23:00:00|3.6|4.82608695159913
2018-05-15 23:10:00|2.7|23.0297872105522
2018-05-15 23:20:00|2.4|15.8869565055345
2018-05-15 23:30:00|3.9|16.1749999835015
2018-05-15 23:40:00|3.9|22.621276572671
2018-05-15 23:50:00|5.7|29.249999970165
2018-05-16 00:00:00|2.09999999999999|26.6347825815281
2018-05-16 03:20:00|0.600000000000009|1.17391304228089
2018-05-16 03:30:00|0.299999999999997|2.54693877291235
2018-05-16 03:40:00|0.299999999999997|1.42499999854649
2018-05-16 10:30:00|0.299999999999997|0.834782607844166
This is the weewx output:
LOOP: 2018-05-16 10:26:11 CEST (1526459171) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459171, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 96.847296, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
LOOP: 2018-05-16 10:26:11 CEST (1526459171) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459171, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 96.847296, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
LOOP: 2018-05-16 10:27:11 CEST (1526459231) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459231, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 97.248561, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
LOOP: 2018-05-16 10:27:11 CEST (1526459231) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459231, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 97.248561, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
LOOP: 2018-05-16 10:27:30 CEST (1526459250) altimeter: None, appTemp: 18.38178938, barometer: None, cloudbase: 791.20635095, dateTime: 1526459250, dewpoint: 13.394742377, heatindex: 19.7, humidex: 22.7168635756, inDewpoint: None, maxSolarRad: None, outBatteryStatus: 0, outHumidity: 67.0, outTemp: 19.7, pressure: None, rain: 0.0, rain_total: 66.6, rainRate: 1.2, usUnits: 16, windchill: 19.7, windDir: 180.0, windGust: 18.3600456336, windSpeed: 12.2400304224
LOOP: 2018-05-16 10:27:30 CEST (1526459250) altimeter: None, appTemp: 18.14378938, barometer: None, cloudbase: 791.20635095, dateTime: 1526459250, dewpoint: 13.394742377, heatindex: 19.7, humidex: 22.7168635756, inDewpoint: None, maxSolarRad: None, outBatteryStatus: 0, outHumidity: 67.0, outTemp: 19.7, pressure: None, rain: 0.0, rain_total: 66.6, rainRate: 1.2, usUnits: 16, windchill: 19.7, windDir: 180.0, windGust: 18.3600456336, windSpeed: 13.4640334647
LOOP: 2018-05-16 10:28:11 CEST (1526459291) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459291, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 98.651181, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
LOOP: 2018-05-16 10:28:11 CEST (1526459291) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459291, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 98.651181, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
LOOP: 2018-05-16 10:28:18 CEST (1526459298) altimeter: None, appTemp: 18.4573384752, barometer: None, cloudbase: 762.808509235, dateTime: 1526459298, dewpoint: 13.6224888303, heatindex: 19.7, humidex: 22.8465459062, inDewpoint: None, maxSolarRad: None, outBatteryStatus: 0, outHumidity: 68.0, outTemp: 19.7, pressure: None, rain: 0.0, rain_total: 66.6, rainRate: 1.2, usUnits: 16, windchill: 19.7, windDir: 90.0, windGust: 17.1360425914, windSpeed: 12.2400304224
LOOP: 2018-05-16 10:29:06 CEST (1526459346) altimeter: None, appTemp: 18.14378938, barometer: None, cloudbase: 791.20635095, dateTime: 1526459346, dewpoint: 13.394742377, heatindex: 19.7, humidex: 22.7168635756, inDewpoint: None, maxSolarRad: None, outBatteryStatus: 0, outHumidity: 67.0, outTemp: 19.7, pressure: None, rain: 0.0, rain_total: 66.6, rainRate: 1.2, usUnits: 16, windchill: 19.7, windDir: 135.0, windGust: 19.5840486759, windSpeed: 13.4640334647
LOOP: 2018-05-16 10:29:11 CEST (1526459351) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459351, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 100.411686, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
LOOP: 2018-05-16 10:30:11 CEST (1526459411) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459411, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 100.557732, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
LOOP: 2018-05-16 10:30:12 CEST (1526459412) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459412, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 100.557732, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
LOOP: 2018-05-16 10:30:12 CEST (1526459412) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459412, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 100.557732, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
LOOP: 2018-05-16 10:31:11 CEST (1526459471) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1526459471, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, radiation: 100.696548, rainRate: 1.2, usUnits: 16, uv: 5.0, windchill: None, windDir: None, windGustDir: None
REC: 2018-05-16 10:30:00 CEST (1526459400) altimeter: None, appTemp: 18.4517977758, barometer: None, boilerTemp: 17.1, cloudbase: 791.018840775, dateTime: 1526459400.0, dewpoint: 13.3587461807, ET: 0.00149506532808, heatindex: 19.6625, humidex: 22.6596625763, inDewpoint: None, interval: 10, maxSolarRad: None, outBatteryStatus: 0.0, outHumidity: 67.0, outTemp: 19.6625, pressure: None, radiation: 93.9994954, rain: 0.3, rain_total: 66.5625, rainRate: 0.834782607844, upsCharge: 100.0, upsLoad: 6.0, usUnits: 16, uv: 4.8, windchill: 19.6625, windDir: 152.193694786, windGust: 19.5840486759, windGustDir: None, windrun: 21.2319748416, windSpeed: 11.6280289013
LOOP: 2018-05-16 10:31:30 CEST (1526459490) altimeter: None, appTemp: 18.61978938, barometer: None, cloudbase: 791.20635095, dateTime: 1526459490, dewpoint: 13.394742377, heatindex: 19.7, humidex: 22.7168635756, inDewpoint: None, maxSolarRad: None, outBatteryStatus: 0, outHumidity: 67.0, outTemp: 19.7, pressure: None, rain: 0.0, rain_total: 66.6, rainRate: 1.2, usUnits: 16, windchill: 19.7, windDir: 135.0, windGust: 20.8080517181, windSpeed: 11.0160273802
LOOP: 2018-05-16 10:33:06 CEST (1526459586) altimeter: None, appTemp: 18.14378938, barometer: None, cloudbase: 791.20635095, dateTime: 1526459586, dewpoint: 13.394742377, heatindex: 19.7, humidex: 22.7168635756, inDewpoint: None, maxSolarRad: None, outBatteryStatus: 0, outHumidity: 67.0, outTemp: 19.7, pressure: None, rain: 0.0, rain_total: 66.6, rainRate: 1.2, usUnits: 16, windchill: 19.7, windDir: 180.0, windGust: 24.4800608448, windSpeed: 13.4640334647
At Line
Line 694 in 1df6925
I am a noob for sure, but I am enjoying working through the issues and learning something new.
When installing your driver I get the following error:
Driver user.sdr failed to load: Non-ASCII character '\xc2' in file /usr/share/weewx/user/sdr.py on line 727, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details (sdr.py, line 727)
As I researched the error it looked to me, could be wrong, that the encoding is expected in the diver it self and not something I can fix or did wrong.
Any help would be greatly appreciated. Not sure what other info I can give that might be a help. I am setting up a Raspberry Pi with weewx.
Thanks
Craig
In this issue:
support was added for the Fine Offset WH65B sensor array. Could that be added to sdr.py? Currently, I'm using the following. Of course, I've also added an entry to the KNOWN_PACKETS list. Thanks.
class FOWH65BPacket(Packet):
# 2018-10-10 13:37:02 : Fine Offset WH65B
# id : 89
# temperature_C : 17.600
# humidity : 93
# wind_dir_deg : 224
# wind_speed_ms : 1.540
# gust_speed_ms : 2.240
# rainfall_mm : 325.500
# uv : 130
# uvi : 0
# light_lux : 13454.000
# battery : OK
# mic : CRC
# This is for a WH65B which is the sensor array for an Ambient Weather WS-2902A.
# The same sensor array is used for several models.
# {"time" : "2018-10-10 13:37:02", "model" : "Fine Offset WH65B", "id" : 89, "temperature_C" : 17.600, "humidity" : 93, "wind_dir_deg" : 224, "wind_speed_ms" : 1.540, "gust_speed_ms" : 2.240, "rainfall_mm" : 325.500, "uv" : 130, "uvi" : 0, "light_lux" : 13454.000, "battery" : "OK", "mic" : "CRC"}
IDENTIFIER = "Fine Offset WH65B"
@staticmethod
def parse_json(obj):
pkt = dict()
pkt['dateTime'] = Packet.parse_time(obj.get('time'))
pkt['usUnits'] = weewx.METRICWX
pkt['station_id'] = obj.get('id')
pkt['temperature'] = Packet.get_float(obj, 'temperature_C')
pkt['humidity'] = Packet.get_float(obj, 'humidity')
pkt['wind_dir'] = Packet.get_float(obj, 'wind_dir_deg')
pkt['wind_speed'] = Packet.get_float(obj, 'wind_speed_ms')
pkt['wind_gust'] = Packet.get_float(obj, 'gust_speed_ms')
pkt['rain_total'] = Packet.get_float(obj, 'rainfall_mm')
pkt['uv'] = Packet.get_float(obj, 'uv')
pkt['uv_index'] = Packet.get_float(obj, 'uvi')
pkt['light'] = Packet.get_float(obj, 'light_lux') * 0.007893
pkt['battery'] = 0 if obj.get('battery') == 'OK' else 1
return FOWH65BPacket.insert_ids(pkt)
@staticmethod
def insert_ids(pkt):
station_id = pkt.pop('station_id', '0000')
pkt = Packet.add_identifiers(pkt, station_id, FOWH65BPacket.__name__)
return pkt
Modified sdr.py to support the a different sensor format. I called themAcuriteTowerPacketV2 and Acurite5n1PacketV2. Adding new classes seemed cleaner than continuing to add to the existing formats. Also, I included all the fields. I find the SNR and such helpful. Anyway hope this might help someone else. I would check this into the repository but do not think I have access.
Hi,
I have weewx (3.8.0) running with weewx-sdr, rtl-sdr, and rtl_433. rtl_433 is reading a stream from an AcuRite 5n1 sensor (model 02032C). After some tinkering, I have a clean feed coming into to weewx, but it's not posting to my wunderground pws site.
weewx running with debug=1 shows the main loop picking up the feed, but no attempts to post to WU. FWIW, I had WU posting working intermittently when using the acurite driver with the usb/console setup, but that was intermittent and unreliable, so I'm attempting to get an rtl-sdr setup going instead.
I think the issue is with weewx-sdr possibly not parsing the rtl_433 output correctly or otherwise weewx-sdr and weewx somehow not connecting the dots to trigger the post. Here's the relevant weewx.conf config:
[Station]
...
# Set to type of station hardware. There must be a corresponding stanza
# in this file with a 'driver' parameter indicating the driver to be used.
station_type = SDR
[AcuRite]
# This section is for AcuRite weather stations.
# The station model, e.g., 'AcuRite 01025' or 'AcuRite 02032C'
# model = AcuRite 02032C
# The driver to use:
# driver = weewx.drivers.acurite
[[Wunderground]]
# This section is for configuring posts to the Weather Underground.
# If you wish to do this, set the option 'enable' to true,
# and specify a station (e.g., 'KORHOODR3') and password.
enable = true
station = KORPORTL962
# To guard against parsing errors, put your password in quotes:
password = redacted
# Set the following to True to have weewx use the WU "Rapidfire"
# protocol. Not all hardware can support it. See the User's Guide.
rapidfire = False
NOTE: I am pretty sure weewx no longer needs the [AcuRite] section because it's now using [SDR], but included it anyway
[Engine]
[[Services]]
# This section specifies the services that should be run. They are
# grouped by type, and the order of services within each group
# determines the order in which the services will be run.
prep_services = weewx.engine.StdTimeSynch
data_services = ,
process_services = weewx.engine.StdConvert, weewx.engine.StdCalibrate, weewx.engine.StdQC, weewx.wxservices.StdWXCalculate
archive_services = weewx.engine.StdArchive
restful_services = weewx.restx.StdStationRegistry, weewx.restx.StdWunderground, weewx.restx.StdPWSweather, weewx.restx.StdCWOP, weewx.restx.StdWOW, weewx.restx.StdAWEKAS
report_services = weewx.engine.StdPrint, weewx.engine.StdReport
[SDR]
# This section is for the software-defined radio driver.
# The rtl-sdr driver to use
driver = user.sdr
cmd = rtl_433 -q -U -F json -R 40
log_unknown_sensors = True
log_unmapped_sensors = True
# Sensor map section
[[sensor_map]]
# AcuRite 5n1 Professional Weather Station
windDir = wind_dir.0BFA.Acurite5n1Packet
windSpeed = wind_speed.0BFA.Acurite5n1Packet
outTemp = temperature.0BFA.Acurite5n1Packet
outHumidity = humidity.0BFA.Acurite5n1Packet
rain_total = rain_total.0BFA.Acurite5n1Packet
And here is the /var/log/syslog output:
Jan 7 11:41:27 DietPi weewx[20393]: engine: Initializing weewx version 3.8.0
Jan 7 11:41:27 DietPi weewx[20393]: engine: Using Python 2.7.13 (default, Nov 24 2017, 17:33:09) #12[GCC 6.3.0 20170516]
Jan 7 11:41:27 DietPi weewx[20393]: engine: Platform Linux-4.9.0-4-amd64-x86_64-with-debian-9.3
Jan 7 11:41:27 DietPi weewx[20393]: engine: Locale is 'en_GB.UTF-8'
Jan 7 11:41:27 DietPi weewx[20393]: engine: Using configuration file /etc/weewx/weewx.conf
Jan 7 11:41:27 DietPi weewx[20393]: engine: debug is 1
Jan 7 11:41:27 DietPi weewx[20393]: engine: Initializing engine
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading station type SDR (user.sdr)
Jan 7 11:41:27 DietPi weewx[20393]: sdr: MainThread: driver version is 0.39
Jan 7 11:41:27 DietPi weewx[20393]: sdr: MainThread: sensor map is {'windDir': 'wind_dir.0BFA.Acurite5n1Packet', 'windSpeed': 'wind_speed.0BFA.Acurite5n1Packet', 'outTemp': 'temperature.0BFA.Acurite5n1Packet', 'outHumidity': 'humidity.0BFA.Acurite5n1Packet', 'rain_total': 'rain_total.0BFA.Acurite5n1Packet'}
Jan 7 11:41:27 DietPi weewx[20393]: sdr: MainThread: deltas is {'strikes': 'strikes_total', 'rain': 'rain_total'}
Jan 7 11:41:27 DietPi weewx[20393]: sdr: MainThread: startup process 'rtl_433 -q -U -F json -R 40'
Jan 7 11:41:27 DietPi weewx[20393]: sdr: stdout-thread: start async reader for stdout-thread
Jan 7 11:41:27 DietPi weewx[20393]: sdr: stderr-thread: start async reader for stderr-thread
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.engine.StdTimeSynch
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.engine.StdTimeSynch
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.engine.StdConvert
Jan 7 11:41:27 DietPi weewx[20393]: engine: StdConvert target unit is 0x1
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.engine.StdConvert
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.engine.StdCalibrate
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.engine.StdCalibrate
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.engine.StdQC
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.engine.StdQC
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.wxservices.StdWXCalculate
Jan 7 11:41:27 DietPi weewx[20393]: wxcalculate: The following values will be calculated: barometer=prefer_hardware, windchill=prefer_hardware, dewpoint=prefer_hardware, appTemp=prefer_hardware, rainRate=prefer_hardware, windrun=prefer_hardware, heatindex=prefer_hardware, maxSolarRad=prefer_hardware, humidex=prefer_hardware, pressure=prefer_hardware, inDewpoint=prefer_hardware, ET=prefer_hardware, altimeter=prefer_hardware, cloudbase=prefer_hardware
Jan 7 11:41:27 DietPi weewx[20393]: wxcalculate: The following algorithms will be used for calculations: altimeter=aaNOAA, maxSolarRad=RS
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.wxservices.StdWXCalculate
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.engine.StdArchive
Jan 7 11:41:27 DietPi weewx[20393]: engine: Archive will use data binding wx_binding
Jan 7 11:41:27 DietPi weewx[20393]: engine: Record generation will be attempted in 'hardware'
Jan 7 11:41:27 DietPi weewx[20393]: engine: Using archive interval of 300 seconds (specified in weewx configuration)
Jan 7 11:41:27 DietPi weewx[20393]: engine: Use LOOP data in hi/low calculations: 1
Jan 7 11:41:27 DietPi weewx[20393]: manager: Daily summary version is 2.0
Jan 7 11:41:27 DietPi weewx[20393]: engine: Using binding 'wx_binding' to database 'weewx.sdb'
Jan 7 11:41:27 DietPi weewx[20393]: manager: Starting backfill of daily summaries
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.engine.StdArchive
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.restx.StdStationRegistry
Jan 7 11:41:27 DietPi weewx[20393]: restx: StationRegistry: Station will not be registered: no station_url specified.
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.restx.StdStationRegistry
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.restx.StdWunderground
Jan 7 11:41:27 DietPi weewx[20393]: restx: Wunderground-PWS: Data for station KORPORTL962 will be posted
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.restx.StdWunderground
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.restx.StdPWSweather
Jan 7 11:41:27 DietPi weewx[20393]: restx: PWSweather: Posting not enabled.
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.restx.StdPWSweather
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.restx.StdCWOP
Jan 7 11:41:27 DietPi weewx[20393]: restx: CWOP: Posting not enabled.
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.restx.StdCWOP
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.restx.StdWOW
Jan 7 11:41:27 DietPi weewx[20393]: restx: WOW: Posting not enabled.
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.restx.StdWOW
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.restx.StdAWEKAS
Jan 7 11:41:27 DietPi weewx[20393]: restx: AWEKAS: Posting not enabled.
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.restx.StdAWEKAS
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.engine.StdPrint
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.engine.StdPrint
Jan 7 11:41:27 DietPi weewx[20393]: engine: Loading service weewx.engine.StdReport
Jan 7 11:41:27 DietPi weewx[20393]: engine: Finished loading service weewx.engine.StdReport
Jan 7 11:41:27 DietPi weewx[20393]: engine: Starting up weewx version 3.8.0
Jan 7 11:41:27 DietPi weewx[20393]: engine: Station does not support reading the time
Jan 7 11:41:27 DietPi weewx[20393]: engine: Starting main packet loop.
Jan 7 11:41:27 DietPi weewx[20393]: manager: Daily summary version is 2.0
Jan 7 11:41:27 DietPi acpid: input device has been disconnected, fd 8
Jan 7 11:41:27 DietPi kernel: [403072.154268] r820t 1-001a: destroying instance
Jan 7 11:41:27 DietPi kernel: [403072.154611] dvb_usb_v2: 'Realtek RTL2832U reference design:2-1' successfully deinitialized and disconnected
Jan 7 11:41:30 DietPi weewx[20393]: sdr: MainThread: lines=[]
Jan 7 11:41:33 DietPi weewx[20393]: sdr: MainThread: lines=[]
Jan 7 11:41:37 DietPi weewx[20393]: sdr: MainThread: lines=['{"time" : "2018-01-07 19:41:34", "model" : "Acurite 5n1 sensor", "sensor_id" : 3048, "channel" : "B", "sequence_num" : 0, "battery" : "OK", "message_type" : 56, "wind_speed_mph" : 0.000, "temperature_F" : 45.000, "humidity" : 90}\n']
Jan 7 11:41:37 DietPi weewx[20393]: sdr: MainThread: unmapped: [] ({})
Jan 7 11:41:40 DietPi weewx[20393]: sdr: MainThread: lines=[]
Jan 7 11:41:45 DietPi weewx[20393]: sdr: MainThread: lines=['{"time" : "2018-01-07 19:41:42", "model" : "Acurite 5n1 sensor", "sensor_id" : 3048, "channel" : "B", "sequence_num" : 0, "battery" : "OK", "message_type" : 56, "wind_speed_mph" : 0.000, "temperature_F" : 45.100, "humidity" : 90}\n', '{"time" : "2018-01-07 19:41:42", "model" : "Acurite 5n1 sensor", "sensor_id" : 3048, "channel" : "B", "sequence_num" : 1, "battery" : "OK", "message_type" : 56, "wind_speed_mph" : 0.000, "temperature_F" : 45.100, "humidity" : 90}\n', '{"time" : "2018-01-07 19:41:42", "model" : "Acurite 5n1 sensor", "sensor_id" : 3048, "channel" : "B", "sequence_num" : 2, "battery" : "OK", "message_type" : 56, "wind_speed_mph" : 0.000, "temperature_F" : 45.100, "humidity" : 90}\n']
Jan 7 11:41:45 DietPi weewx[20393]: sdr: MainThread: unmapped: ['{"time" : "2018-01-07 19:41:42", "model" : "Acurite 5n1 sensor", "sensor_id" : 3048, "channel" : "B", "sequence_num" : 1, "battery" : "OK", "message_type" : 56, "wind_speed_mph" : 0.000, "temperature_F" : 45.100, "humidity" : 90}\n', '{"time" : "2018-01-07 19:41:42", "model" : "Acurite 5n1 sensor", "sensor_id" : 3048, "channel" : "B", "sequence_num" : 2, "battery" : "OK", "message_type" : 56, "wind_speed_mph" : 0.000, "temperature_F" : 45.100, "humidity" : 90}\n'] ({})
Jan 7 11:41:45 DietPi weewx[20393]: sdr: MainThread: unmapped: ['{"time" : "2018-01-07 19:41:42", "model" : "Acurite 5n1 sensor", "sensor_id" : 3048, "channel" : "B", "sequence_num" : 2, "battery" : "OK", "message_type" : 56, "wind_speed_mph" : 0.000, "temperature_F" : 45.100, "humidity" : 90}\n'] ({})
Jan 7 11:41:45 DietPi weewx[20393]: sdr: MainThread: unmapped: [] ({})
Jan 7 11:41:48 DietPi weewx[20393]: sdr: MainThread: lines=[]
Jan 7 11:41:51 DietPi weewx[20393]: sdr: MainThread: lines=[]
...
And this last part just continues indefinitely--the sdr: MainThread lines repeat, picking up the feed from the acurite every 10 seconds or so, but I never see weewx trying to post.
A packet capture on the network shows no signs of traffic toward wunderground, and the host (DietPi) has no issues with internet connectivity (dns lookups work, wget works, git clone works, etc.).
Are the weewx-srd field mappings correct? Is there data or format missing or wrong that should otherwise be triggering weewx to post?
After several days of working with it, success feels so close! :-D
Thanks,
MF
ps. Matthew--thanks for developing a way to use SDR with weewx. I was pulling my hair out trying to get the acurite console/USB to work and was ready to throw in the towel when I ran across your git.
upon further research this is unrelated to previous issue - I See @StephenR0 had the same problem in #34 (comment)
After changing update_interval WeeWX ran for an hour or so before crashing again with the following error:
Traceback (most recent call last):
File "./bin/weewxd", line 64, in <module>
weewx.engine.main(options, args)
File "/home/weewx/bin/weewx/engine.py", line 890, in main
engine.run()
File "/home/weewx/bin/weewx/engine.py", line 188, in run
for packet in self.console.genLoopPackets():
File "/home/weewx/bin/user/sdr.py", line 2114, in genLoopPackets
for packet in PacketFactory.create(lines):
File "/home/weewx/bin/user/sdr.py", line 1985, in create
pkt = PacketFactory.parse_json(lines)
File "/home/weewx/bin/user/sdr.py", line 2001, in parse_json
return parser.parse_json(obj)
File "/home/weewx/bin/user/sdr.py", line 1143, in parse_json
pkt['light'] = Packet.get_float(obj, 'light_lux') * 0.007893
TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'
line 1143 in sdr.py states:
pkt['light'] = Packet.get_float(obj, 'light_lux') * 0.007893
nothing earth shattering there... the math adds up whenever I plug in the values, even if the packet read 0 it would still be a float so not sure why it's throwing an error.
Hi,
First of all thanks a lot for writing this driver! I'm currently using this nearly flawlessly on a RPi2 to process data with an SDR dongle coming off an Acurite 5-in-1 weather station.
I'm experiencing problems with restarting weewx, where the rtl_433 process stays on, thus preventing the weewx-sdr driver from being properly relaunched. For example, I end up with entries like the following on the weewx log:
Jan 12 18:38:12 framboesa weewx[6866]: engine: Starting up weewx version 3.6.2
Jan 12 18:38:12 framboesa weewx[6866]: engine: Starting main packet loop.
Jan 12 18:38:12 framboesa weewx[6866]: sdr: MainThread: err: ['usb_claim_interface error -6\n', 'Failed to open rtlsdr device #0.\n']
Jan 12 18:38:12 framboesa weewx[6866]: sdr: MainThread: shutdown process /usr/local/bin/rtl_433 -q -U -R 9 -R 39 -R 12
Jan 12 18:38:12 framboesa weewx[6866]: engine: Caught WeeWxIOError: rtl_433 process is not running
Jan 12 18:38:12 framboesa weewx[6866]: **** Waiting 60 seconds then retrying...
Instead, I usually have to stop weewx before starting it again. This way the driver initializes rtl_433 properly with only one instance running. It seems like there is some race condition of sorts. It most recently happened when the weewx engine for some reason restarted itself.
Let me know if there are any other details which would be helpful to identify the problem.
Thanks
In this thread:
https://groups.google.com/forum/#!topic/rtl_433/nsZsA7Boggw
it was discovered that the WH25 sensor has a battery low bit. Could that be added to sdr.py? I'm using this. Thanks.
class FOWH25Packet(Packet):
# 2018-10-09 19:45:12 : Fine Offset Electronics, WH25
# id : 21
# temperature_C : 20.900
# humidity : 65
# pressure_hPa : 980.400
# battery : OK
# mic : CHECKSUM
# {"time" : "2018-10-10 13:37:11", "model" : "Fine Offset Electronics, WH25", "id" : 21, "temperature_C" : 21.600, "humidity" : 66, "pressure_hPa" : 972.800, "battery" : "OK", "mic" : "CHECKSUM"}
IDENTIFIER = "Fine Offset Electronics, WH25"
@staticmethod
def parse_json(obj):
pkt = dict()
pkt['dateTime'] = Packet.parse_time(obj.get('time'))
pkt['usUnits'] = weewx.METRIC
pkt['station_id'] = obj.get('id')
pkt['temperature'] = Packet.get_float(obj, 'temperature_C')
pkt['humidity'] = Packet.get_float(obj, 'humidity')
pkt['pressure'] = Packet.get_float(obj, 'pressure_hPa')
pkt['battery'] = 0 if obj.get('battery') == 'OK' else 1
return FOWH25Packet.insert_ids(pkt)
@staticmethod
def insert_ids(pkt):
station_id = pkt.pop('station_id', '0000')
pkt = Packet.add_identifiers(pkt, station_id, FOWH25Packet.__name__)
return pkt
Hi
It seems like it's only parsing humidity for the WT450 sensor.
When running as a service I get "ignoring duplicate" packet for humidity
Sep 18 00:22:52 raspberrypi weewx[1395]: sdr: MainThread: lines=['{"time" : "2017-09-17 22:22:49", "model" : "WT450 sensor", "id" : 1, "channel" : 2, "battery" : "OK", "temperature_C" : 26.880, "humidity" : 46}\n', '{"time" : "2017-09-17 22:22:49", "model" : "WT450 sensor", "id" : 1, "channel" : 2, "battery" : "OK", "temperature_C" : 26.900, "humidity" : 46}\n', '{"time" : "2017-09-17 22:22:49", "model" : "WT450 sensor", "id" : 1, "channel" : 2, "battery" : "OK", "temperature_C" : 26.930, "humidity" : 46}\n']
Sep 18 00:22:52 raspberrypi rsyslogd-2007: action 'action 18' suspended, next retry is Mon Sep 18 00:23:52 2017 [try http://www.rsyslog.com/e/2007 ]
Sep 18 00:22:52 raspberrypi weewx[1395]: sdr: MainThread: packet={'outHumidity': 46.0, 'usUnits': 16, 'dateTime': 1505686969}
Sep 18 00:22:52 raspberrypi weewx[1395]: sdr: MainThread: ignoring duplicate packet {'outHumidity': 46.0, 'usUnits': 16, 'dateTime': 1505686969}
Sep 18 00:22:52 raspberrypi weewx[1395]: sdr: MainThread: ignoring duplicate packet {'outHumidity': 46.0, 'usUnits': 16, 'dateTime': 1505686969}
Humidity is parsed and database is updated with this but not temperature.
When running the command manually, it states that it will parse both, so this part seems to be correct:
sudo PYTHONPATH=/usr/share/weewx python /usr/share/weewx/user/sdr.py --cmd="rtl_433 -q -U -F json -R 33"
out: ['{"time" : "2017-09-17 22:34:49", "model" : "WT450 sensor", "id" : 1, "channel" : 2, "battery" : "OK", "temperature_C" : 25.400, "humidity" : 45}\n', '{"time" : "2017-09-17 22:34:49", "model" : "WT450 sensor", "id" : 1, "channel" : 2, "battery" : "OK", "temperature_C" : 25.420, "humidity" : 45}\n', '{"time" : "2017-09-17 22:34:49", "model" : "WT450 sensor", "id" : 1, "channel" : 2, "battery" : "OK", "temperature_C" : 25.450, "humidity" : 45}\n']
parsed: {'battery.1:2.AcuriteWT450Packet': 0, 'dateTime': 1505687689, 'channel.1:2.AcuriteWT450Packet': 2, 'humidity.1:2.AcuriteWT450Packet': 45.0, 'usUnits': 16, 'sensor_id.1:2.AcuriteWT450Packet': 1, 'temperature.1:2.AcuriteWT450Packet': 25.4}
parsed: {'battery.1:2.AcuriteWT450Packet': 0, 'dateTime': 1505687689, 'channel.1:2.AcuriteWT450Packet': 2, 'humidity.1:2.AcuriteWT450Packet': 45.0, 'usUnits': 16, 'sensor_id.1:2.AcuriteWT450Packet': 1, 'temperature.1:2.AcuriteWT450Packet': 25.42}
parsed: {'battery.1:2.AcuriteWT450Packet': 0, 'dateTime': 1505687689, 'channel.1:2.AcuriteWT450Packet': 2, 'humidity.1:2.AcuriteWT450Packet': 45.0, 'usUnits': 16, 'sensor_id.1:2.AcuriteWT450Packet': 1, 'temperature.1:2.AcuriteWT450Packet': 25.45}
brg
Magnus
I'm trying to add the strikes total for an archive period to the database, but is always getting a null value. I don't see anything about the strikes_total in the packet.
`Jul 9 23:06:31 raspberrypi weewx[19366]: sdr: MainThread: lines=['{"time" : "2019-07-10 03:06:28", "model" : "Acurite Lightning 6045M", "id" : 14052, "channel" : "B", "temperature_F" : 66.500, "humidity" : 78, "strike_count" : 18, "storm_dist" : 15, "active" : 0, "rfi" : 0, "ussb1" : 1, "battery" : "OK", "exception" : 0, "raw_msg" : "b6e46f4e90f512cfbd"}\n', '{"time" : "2019-07-10 03:06:28", "model" : "Acurite Lightning 6045M", "id" : 14052, "channel" : "B", "temperature_F" : 66.500, "humidity" : 78, "strike_count" : 18, "storm_dist" : 15, "active" : 0, "rfi" : 0, "ussb1" : 1, "battery" : "OK", "exception" : 0, "raw_msg" : "b6e46f4e90f512cfbd"}\n'
I could add strike_count to the database, but i think this value is the counter that gets reset after 127. I don't know if this a issue or I have something wrong in my configuration.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.