gjr80 / weewx-realtime_gauge-data Goto Github PK
View Code? Open in Web Editor NEWNear realtime support for updating of SteelSeries Weather Gauges by WeeWX
License: GNU General Public License v3.0
Near realtime support for updating of SteelSeries Weather Gauges by WeeWX
License: GNU General Public License v3.0
Refer this weewx-development post.
Hi,
I'm trying to use the rtgd extension and I'm getting what appears to be double conversion. I am using the Acurite driver that I've customized to use an external temp sensor. The temp data works fine with weewx except it the degF value gets converted as if it's degC to degF in the gauges when I enable rtgd.
Where do I set the conversion? I've changed line 374 to be Degree_F and it didn't make a difference. I also tried changing most places the code calls for Degree_C to Degree_F and it also didn't fix it.
In WeeWX 4.4.0 and earlier as_value_tuple()
used .get()
to obtain a field from a packet now it uses packet[field]
meaning that if the field is not present in packet an exception is raised causing rtgd to exit.
The solution is likely to check existence of field in packet before calling as_value_tuple()
but this has other flow on consequences.
Whitespace typically makes up about 10% of the gauge-data.txt contents, whilst the file size is small the (potential) frequency of upload means a significant amount of data could be saved from unnecessary transfer.
json.dump()
is used to create the JSON string, and that results in whitespace. Applying .replace(" ","")
to the JSON string would remove the spaces but would also corrupt any forecast text. Applying .replace(": ",":")
followed by .replace(", ",",")
would be safe to the forecast text but you need to traverse the string twice. Or maybe we just leave it as is.
This is a great plugin to weewx.
I'd like to request two new values be added to the output: TUVTH and TSolarTM. These are the times associated with the maximum of UVTH and SolarTM during the day. These values aren't needed by the standard gauges, but I'd like them to be available for other uses of the data available in this plugin.
Thanks!
When calculating a trend value if the historical record obtained from the archive contains the observation field concerened and it's value is None then the code will fail with a TypeError. The fix is to expand an exisiting conditional check to detect the None value and return None.
This link refers.
Using 0.6.3 rainrate produces output some 25 times the correct value in inches.
"rfall":"1.85","rrate":"18.00","rrateTM":"180.6",
when the rate was 0.71 in/hr
rainfall is correct
Rainrate gauge reads 18.00 in/hr
Occasionally when I restart weewx I see this error:
Apr 27 22:00:15 HOSTNAME weewx[16906]: rtgdthread: **** Traceback (most recent call last):
Apr 27 22:00:15 HOSTNAME weewx[16906]: rtgdthread: **** File "/usr/share/weewx/user/rtgd.py", line 926, in process_packet
Apr 27 22:00:15 HOSTNAME weewx[16906]: rtgdthread: **** data = self.calculate(cached_packet)
Apr 27 22:00:15 HOSTNAME weewx[16906]: rtgdthread: **** File "/usr/share/weewx/user/rtgd.py", line 1519, in calculate
Apr 27 22:00:15 HOSTNAME weewx[16906]: rtgdthread: **** fromBearing = max((self.windDirAvg-d) if ((d-self.windDirAvg) < 0 < s) else None for x, y, s, d, t in self.buffer.wind_dir_list)
Apr 27 22:00:15 HOSTNAME weewx[16906]: rtgdthread: **** ValueError: max() arg is an empty sequence
I installed your extension today for the first time and tested it a bit. Thereby I noticed this error:
Nov 4 12:20:59 weewx weewx[3083708] CRITICAL user.rtgd: Unexpected exception of type <class 'TypeError'>
Nov 4 12:20:59 weewx weewx[3083708] DEBUG user.rtgd: rtgdthread: **** Traceback (most recent call last):
Nov 4 12:20:59 weewx weewx[3083708] DEBUG user.rtgd: rtgdthread: **** File "/home/weewx/bin/user/rtgd.py", line 1831, in run
Nov 4 12:20:59 weewx weewx[3083708] DEBUG user.rtgd: rtgdthread: **** self.process_packet(_package['payload'])
Nov 4 12:20:59 weewx weewx[3083708] DEBUG user.rtgd: rtgdthread: **** File "/home/weewx/bin/user/rtgd.py", line 1886, in process_packet
Nov 4 12:20:59 weewx weewx[3083708] DEBUG user.rtgd: rtgdthread: **** cached_packet = self.packet_cache.get_packet(_conv_packet['dateTime'],
Nov 4 12:20:59 weewx weewx[3083708] DEBUG user.rtgd: rtgdthread: **** File "/home/weewx/bin/user/rtgd.py", line 3019, in get_packet
Nov 4 12:20:59 weewx weewx[3083708] DEBUG user.rtgd: rtgdthread: **** packet[obs] = self.get_value(obs, ts, max_age)
Nov 4 12:20:59 weewx weewx[3083708] DEBUG user.rtgd: rtgdthread: **** File "/home/weewx/bin/user/rtgd.py", line 3005, in get_value
Nov 4 12:20:59 weewx weewx[3083708] DEBUG user.rtgd: rtgdthread: **** if obs in self.cache and ts - self.cache[obs]['ts'] <= max_age:
Nov 4 12:20:59 weewx weewx[3083708] DEBUG user.rtgd: rtgdthread: **** TypeError: '<=' not supported between instances of 'float' and 'str'
Nov 4 12:20:59 weewx weewx[3083708] CRITICAL user.rtgd: Thread exiting. Reason: '<=' not supported between instances of 'float' and 'str'
i have temporarily corrected it that way:
if obs in self.cache and ts - self.cache[obs]['ts'] <= float(max_age):
I do not know if this is correct, but then the error no longer occurred.
Henry
Edit: If you need more information, here are all the configurations: GitHub
Hi,
I followed the instructions written in comments on the top of rtgd.py, but it seems that the gauges aren't working, because I don'tn see any update. By rtgd engine I get the following messages:
rtgd: RealTimeGaugeData scroller text will use a fixed string rtgd: RealTimeGaugeData will generate gauge-data.txt. min_interval is 2 seconds rtgd: KeyError: Could not determine sensor contact state
can you help me?
gauge-data.txt includes a number of average values; some are (defined) 10 minute averages otehrs are not defined. The approach taken in calculating these averages is not consistent. Some are taken from archive data only and some use values derived from the archive and until the loop buffer is full later at which time it reverts to loop data derived values.
This is largely an issue that only affects wind related obs.
There is a compromise to be made between complexity, accuracy, consistency and speed of calculation. Consistency should be maintained and speed is probaly not such an issue.
I recently upgraded to 0.3.0. I noticed that the CPU usage spiked on my system. I think, inside of the RealtimeGaugeDataThread::run() method, if there is nothing in either queue the while loop continuously checks each queue over and over again (unlike what happened in 0.2.14 where there was only one queue and it blocked indefinitely).
Here is a potential fix: Block on the control_queue, but only block on it for a relatively short amount of time (say 1 second). This way the system will still service the control_queue immediately (like it did in older versions), it will service the result_queue with a 1 second delay.
diff --git a/bin/user/rtgd.py b/bin/user/rtgd.py
index 99135a7..7639488 100644
--- a/bin/user/rtgd.py
+++ b/bin/user/rtgd.py
@@ -931,7 +931,7 @@ class RealtimeGaugeDataThread(threading.Thread):
self.forecast_text = _package['payload']
# now deal with the control queue
try:
- _package = self.control_queue.get_nowait()
+ _package = self.control_queue.get(True, 1.0) # block for one second waiting for package; if none throw Queue.Empty
except Queue.Empty:
# nothing in the queue so continue
pass
Currently this extension can write the gauge data file at the same time a webserver is reading the file. This can lead to the client getting an incomplete file. I'd suggest writing the file to a temporary file and then moving it atomically into place. Something like the following...
diff --git a/bin/user/rtgd.py b/bin/user/rtgd.py
index e7d3cc3..4860126 100644
--- a/bin/user/rtgd.py
+++ b/bin/user/rtgd.py
@@ -374,6 +374,7 @@ import errno
import httplib
import json
import math
+import os
import os.path
import socket
import syslog
@@ -678,6 +679,7 @@ class RealtimeGaugeDataThread(threading.Thread):
self.rtgd_path_file = os.path.join(self.rtgd_path,
rtgd_config_dict.get('rtgd_file_name',
'gauge-data.txt'))
+ self.rtgd_tmp_path_file = self.rtgd_path_file + "~"
# get the remote server URL if it exists, if it doesn't set it to None
self.remote_server_url = rtgd_config_dict.get('remote_server_url', None)
@@ -1140,9 +1142,11 @@ class RealtimeGaugeDataThread(threading.Thread):
if error.errno != errno.EEXIST:
raise
# now write to file
- with open(self.rtgd_path_file, 'w') as f:
+ with open(self.rtgd_tmp_path_file, 'w') as f:
json.dump(data, f, separators=(',', ':'), sort_keys=True)
+ os.rename(self.rtgd_tmp_path_file, self.rtgd_path_file)
+
def get_scroller_text(self):
"""Obtain the text string to be used in the scroller.
The following log excerpt may be symptomatic of an issue since fixed (it didn't happen just after midnight on 26 Feb) but it needs to be checked:
Feb 25 00:00:29 stormbird weewx[16139]: rtgdthread: **** Traceback (most recent call last):
Feb 25 00:00:29 stormbird weewx[16139]: rtgdthread: **** File "/home/weewx/bin/user/rtgd.py", line 835, in process_packet
Feb 25 00:00:29 stormbird weewx[16139]: rtgdthread: **** data = self.calculate(cached_packet)
Feb 25 00:00:29 stormbird weewx[16139]: rtgdthread: **** File "/home/weewx/bin/user/rtgd.py", line 1305, in calculate
Feb 25 00:00:29 stormbird weewx[16139]: rtgdthread: **** data['wgustTM'] = self.wind_format % wgustTM
Feb 25 00:00:29 stormbird weewx[16139]: rtgdthread: **** TypeError: float argument required, not NoneType
An unexpected restart lead to the following error:
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: processor: 3
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: model name: ARMv7 Processor rev 4 (v7l)
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: BogoMIPS: 51.20
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: Features: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: CPU implementer: 0x41
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: CPU architecture: 7
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: CPU variant: 0x0
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: CPU part: 0xd03
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: CPU revision: 4
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: Hardware: BCM2835
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: Revision: a22082
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: Serial: 000000001d027eb8
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.cmon: cpuinfo: Model: Raspberry Pi 3 Model B Rev 1.2
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO weewx.engine: Archive will use data binding wx_binding
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO weewx.engine: Record generation will be attempted in 'hardware'
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO weewx.engine: Using archive interval of 300 seconds (specified by hardware)
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.wd: WdArchive will use data binding wd_binding
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.wd: Using binding 'wd_binding' to database 'weewxwd'
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.wd: Starting backfill of daily summaries
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO weewx.manager: Starting backfill of daily summaries
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO weewx.manager: Daily summaries up to date
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.wd: Daily summaries up to date.
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.wd: WdSuppArchive will use data binding 'wdsupp_binding'
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.wd: Using binding 'wdsupp_binding' to database 'wdsupp'
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.wd: max_age=691200 vacuum=86400
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.wd: Source 'WU' not enabled.
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.wd: Dark Sky API will be used for forecast and current conditions data
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.wd: Source 'File' not enabled.
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO weewx.restx: StationRegistry: Station will be registered.
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO weewx.restx: Wunderground-PWS: Data for station IQUEENSL336 will be posted
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO weewx.restx: PWSWeather: Data for station NARANGBAVP2 will be posted
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO weewx.engine: 'pyephem' detected, extended almanac data is available
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.low_battery: LowConsoleBattery alarm turned on. Voltage threshold 3.50, count threshold 5
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.rtgd: version is 0.6.0
Dec 13 00:01:47 cockatoo weewx-vantage[5737] INFO user.rtgd: RealTimeGaugeData scroller text will use Darksky forecast data
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: Caught unrecoverable exception:
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** float() argument must be a string or a number, not 'ValueTuple'
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** Traceback (most recent call last):
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** File "/home/weewx/bin/weewxd", line 147, in main
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** engine = weewx.engine.StdEngine(config_dict)
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** File "/home/weewx/bin/weewx/engine.py", line 93, in __init__
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** self.loadServices(config_dict)
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** File "/home/weewx/bin/weewx/engine.py", line 161, in loadServices
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** obj = weeutil.weeutil.get_object(svc)(self, config_dict)
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** File "/home/weewx/bin/user/rtgd.py", line 1109, in __init__
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** self.rtgd_thread = RealtimeGaugeDataThread(self.rtgd_ctl_queue,
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** File "/home/weewx/bin/user/rtgd.py", line 1583, in __init__
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** _vt = ValueTuple(float(_default[0]), self.units_dict[_group], _group)
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** TypeError: float() argument must be a string or a number, not 'ValueTuple'
Dec 13 00:01:47 cockatoo weewx-vantage[5737] CRITICAL __main__: **** Exiting.
I got this error:
Nov 19 16:41:46 pi weewx[8218] INFO user.rtgd: rtgdthread: **** Traceback (most recent call last):
Nov 19 16:41:46 pi weewx[8218] INFO user.rtgd: rtgdthread: **** File "/home/pi/4.0.0b1/bin/user/rtgd.py", line 1242, in process_packet
Nov 19 16:41:46 pi weewx[8218] INFO user.rtgd: rtgdthread: **** data = self.calculate(cached_packet)
Nov 19 16:41:46 pi weewx[8218] INFO user.rtgd: rtgdthread: **** File "/home/pi/4.0.0b1/bin/user/rtgd.py", line 1845, in calculate
Nov 19 16:41:46 pi weewx[8218] INFO user.rtgd: rtgdthread: **** wgust_tm = max(wgust_m_loop, wgust_tm, 0.0)
Nov 19 16:41:46 pi weewx[8218] INFO user.rtgd: rtgdthread: **** TypeError: unorderable types: float() > NoneType()
Nov 19 16:41:48 pi weewx[8218] INFO user.rtgd: rtgdthread: **** Traceback (most recent call last):
Nov 19 16:41:48 pi weewx[8218] INFO user.rtgd: rtgdthread: **** File "/home/pi/4.0.0b1/bin/user/rtgd.py", line 1242, in process_packet
Nov 19 16:41:48 pi weewx[8218] INFO user.rtgd: rtgdthread: **** data = self.calculate(cached_packet)
Nov 19 16:41:48 pi weewx[8218] INFO user.rtgd: rtgdthread: **** File "/home/pi/4.0.0b1/bin/user/rtgd.py", line 1845, in calculate
Nov 19 16:41:48 pi weewx[8218] INFO user.rtgd: rtgdthread: **** wgust_tm = max(wgust_m_loop, wgust_tm, 0.0)
Nov 19 16:41:48 pi weewx[8218] INFO user.rtgd: rtgdthread: **** TypeError: unorderable types: float() > NoneType()
Nov 19 16:41:50 pi weewx[8218] INFO user.rtgd: rtgdthread: **** Traceback (most recent call last):
Nov 19 16:41:50 pi weewx[8218] INFO user.rtgd: rtgdthread: **** File "/home/pi/4.0.0b1/bin/user/rtgd.py", line 1242, in process_packet
Nov 19 16:41:50 pi weewx[8218] INFO user.rtgd: rtgdthread: **** data = self.calculate(cached_packet)
Nov 19 16:41:50 pi weewx[8218] INFO user.rtgd: rtgdthread: **** File "/home/pi/4.0.0b1/bin/user/rtgd.py", line 1845, in calculate
Nov 19 16:41:50 pi weewx[8218] INFO user.rtgd: rtgdthread: **** wgust_tm = max(wgust_m_loop, wgust_tm, 0.0)
Nov 19 16:41:50 pi weewx[8218] INFO user.rtgd: rtgdthread: **** TypeError: unorderable types: float() > NoneType()
Nov 19 16:41:52 pi weewx[8218] INFO user.rtgd: rtgdthread: **** Traceback (most recent call last):
Nov 19 16:41:52 pi weewx[8218] INFO user.rtgd: rtgdthread: **** File "/home/pi/4.0.0b1/bin/user/rtgd.py", line 1242, in process_packet
Nov 19 16:41:52 pi weewx[8218] INFO user.rtgd: rtgdthread: **** data = self.calculate(cached_packet)
Nov 19 16:41:52 pi weewx[8218] INFO user.rtgd: rtgdthread: **** File "/home/pi/4.0.0b1/bin/user/rtgd.py", line 1845, in calculate
Nov 19 16:41:52 pi weewx[8218] INFO user.rtgd: rtgdthread: **** wgust_tm = max(wgust_m_loop, wgust_tm, 0.0)
Nov 19 16:41:52 pi weewx[8218] INFO user.rtgd: rtgdthread: **** TypeError: unorderable types: float() > NoneType()
Note, weeutil has a max_with_none function.
Hello!
The upload to a webserver worked for over two months, but suddenly it stopped and in the logs I find the error "rtgdthread: Failed to post data: Unexpected response".
Do you have an idea how to debug this problem?
Dear,
Bernhard
Update: I think, that I have found the problem. My hoster activated a autoredirection to https. Is that a possible cause?
Not displayed irresepcive of debug setting
Hi,
I did the manual installation as described but I always get following error. I didn't manage to find out what the issue is, sounds like some config is missing but I didn't find anything about the windGust.
Thanks for your help
weewx | Aug 26 21:02:07 weewx[19] INFO user.rtgd: rtgdthread: **** File "/home/weewx/bin/user/rtgd.py", line 1815, in process_packet
weewx | Aug 26 21:02:07 weewx[19] INFO user.rtgd: rtgdthread: **** data = self.calculate(cached_packet)
weewx | Aug 26 21:02:07 weewx[19] INFO user.rtgd: rtgdthread: **** File "/home/weewx/bin/user/rtgd.py", line 2079, in calculate
weewx | Aug 26 21:02:07 weewx[19] INFO user.rtgd: rtgdthread: **** wgust = self.buffer['windGust'].history_max(ts, age=600).value
weewx | Aug 26 21:02:07 weewx[19] INFO user.rtgd: rtgdthread: **** AttributeError: 'NoneType' object has no attribute 'value'
SteelSeries Weather Gauges derive windrun units from wind speed units whereas with rtgd the user can specify the windrun units independent of wind speed. Similarly, rain rate units are tied to rain units. This could cause a conflict if the user set, say, group_speed=km_per_hour
and group_distance=mile
or group_rain=mm
and group_rainrate=inch_per_hour
.
Solution is for rtgd to derive windrun and rainrate units in the same manner as the SteelSeries Weather Gauges. Need to make sure that formatting options are sufficiently flexible though.
When [RealtimeGaugeData] scroller_source
is set to Zambretti
nothing is displayed in the scroller despite a current and valid Zambretti forecast existing in the forecast database.
This weewx-user thread refers.
It would be great if there were an option to create the directory for gauge-data.txt if it doesn't exist (I use this option to create a directory under /dev/shm).
This is a small request to reduce the amount of logging that rtgd creates when debug = 1. I'd like to suggest changing the logging of the gauge-data.txt generation to only be for debug >= 2.
So changing:
logdbg("rtgdthread", "packet (%s) gauge-data.txt generated in %.5f seconds" % (cached_packet['dateTime'], (self.last_write-t1)))
To:
logdbg2("rtgdthread", "packet (%s) gauge-data.txt generated in %.5f seconds" % (cached_packet['dateTime'], (self.last_write-t1)))
Just after midnight, before the archive has been processed rtgdthread produces these errors:
Apr 25 00:00:16 HOSTNME weewx[29890]: rtgdthread: **** Traceback (most recent call last):
Apr 25 00:00:16 HOSTNME weewx[29890]: rtgdthread: **** File "/usr/share/weewx/user/rtgd.py", line 926, in process_packet
Apr 25 00:00:16 HOSTNME weewx[29890]: rtgdthread: **** data = self.calculate(cached_packet)
Apr 25 00:00:16 HOSTNME weewx[29890]: rtgdthread: **** File "/usr/share/weewx/user/rtgd.py", line 1560, in calculate
Apr 25 00:00:16 HOSTNME weewx[29890]: rtgdthread: **** self.wind_group).value/self.day_stats['wind'].count
Apr 25 00:00:16 HOSTNME weewx[29890]: rtgdthread: **** ZeroDivisionError: float division by zero
I believe this is because self.day_stats['wind'].count is zero because there is no wind data between midnight and 5 minutes after midnight.
Hi!
I would like to use your extension with a Davis Vantage Pro and a meteoStick.
The pressure data is observed by the meteoStick, because the Vantage sensor unit has no own pressure sensor.
In gauge-data.txt the values of pressH and pressL are correct, but the value of press is 0.0. Do you know the cause?
Dear
Bernhard
windGust data should be coming into the buffer but...
INFO user.rtgd: rtgdthread: **** Traceback (most recent call last):
INFO user.rtgd: rtgdthread: **** File "/usr/share/weewx/user/rtgd.py", line 1889, in process_packet
INFO user.rtgd: rtgdthread: **** data = self.calculate(cached_packet)
INFO user.rtgd: rtgdthread: **** File "/usr/share/weewx/user/rtgd.py", line 2157, in calculate
INFO user.rtgd: rtgdthread: **** wgust = self.buffer['windGust'].history_max(ts, age=600).value
INFO user.rtgd: rtgdthread: **** AttributeError: 'NoneType' object has no attribute 'value'
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.