Bug: ecowitt_http collector terminates permanently after ConnectionResetError

36 views
Skip to first unread message

TheCableGuy96

unread,
Jul 24, 2026, 7:53:10 AM (9 days ago) Jul 24
to weewx-user

Hi,

I believe I have found a recoverability bug in the Ecowitt Local HTTP service.

Environment

WeeWX: 5.4.0
Python: 3.12.3
Operating system: Ubuntu 24.04.4 LTS
Architecture: x86_64
Virtualisation: KVM
Installation: Python virtual environment under /opt/weewx
Ecowitt extension: ecowitt_http.py 0.1.0a28
Gateway: Ecowitt GW1200
Connection: Local HTTP
Poll interval: 20 seconds

Relevant configuration

[Engine]
[[Services]]
data_services = user.ecowitt_http.EcowittHttpService

[EcowittHttp]
ip_address = 192.168.10.24
poll_interval = 20
driver = user.ecowitt_http

Problem

At 02:52:33 on 23 July 2026, the GW1200 reset an HTTP connection while ecowitt_http was reading get_livedata_info.

The relevant portion of the system log is:

Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** Traceback (most recent call last):
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** File "/opt/weewx/weewx-data/bin/user/ecowitt_http.py", line 5231, in run
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** self.client.collect()
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** File "/opt/weewx/weewx-data/bin/user/ecowitt_http.py", line 5106, in collect
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** queue_data = self.get_current_data()
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** File "/opt/weewx/weewx-data/bin/user/ecowitt_http.py", line 5169, in get_current_data
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** curr_data = self.device.get_live_data()
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** File "/opt/weewx/weewx-data/bin/user/ecowitt_http.py", line 10341, in get_live_data
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** live_data = self.api.get_livedata_info()
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** File "/opt/weewx/weewx-data/bin/user/ecowitt_http.py", line 5387, in get_livedata_info
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** return self.request('get_livedata_info')
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** File "/opt/weewx/weewx-data/bin/user/ecowitt_http.py", line 5320, in request
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** with urllib.request.urlopen(req, timeout=self.timeout) as w:
Jul 23 02:52:33 weather weewxd[37665]: CRITICAL user.ecowitt_http: **** ConnectionResetError: [Errno 104] Connection reset by peer

The main WeeWX process continued running, but the EcowittHttpCollector thread terminated and did not restart.

Fields supplied by the service then stopped being added to archive records. In my case, lightning_strike_count was stored as 0.0 until 02:55, then became NULL in every subsequent archive record.

Restarting WeeWX immediately restored collection.

Debug was not enabled when the connection reset occurred, but the complete exception traceback was captured in the system journal.

Apparent cause

The retry loop in EcowittHttpApi.request() catches socket.timeout, but it does not catch ConnectionResetError.

The exception therefore escapes the retry loop and reaches the collector thread’s outer exception handler. The traceback is logged, but the collector thread then terminates permanently.

The HTTP request and retry block in my installed file matched the current upstream version before this change.

My local file also contains a separate modification for missing lightning-distance values such as "--.-", but that is unrelated to this connection failure.

Tested local patch

I added the following handler immediately after the existing socket.timeout handler:

except ConnectionResetError as e:  
    # Treat a device TCP reset as a temporary failure and allow  
    # the existing retry loop to make another attempt.  
    log.warning(  
        'Device connection reset on attempt %d of %d: %s' %  
        (attempt + 1, self.max_tries, e)  
    )  

  I also changed the exhausted-retry block to return cleanly:  

else:  
    log.debug(  
        'Failed to get device data after %d attempts' %  
        self.max_tries  
    )  
    return None  

Results after applying the patch

Python syntax validation passed.

WeeWX restarted normally.

ecowitt_http resumed polling the GW1200.

New archive records again contained lightning_strike_count = 0.0.

No further ecowitt_http errors were logged.

WeeWX report generation completed successfully.

The affected lightning chart began working normally again.

Question

Would catching the broader ConnectionError class be preferable to catching only ConnectionResetError, so related temporary TCP failures are also retried?


Reply all
Reply to author
Forward
0 new messages