weewx-interceptor icon indicating copy to clipboard operation
weewx-interceptor copied to clipboard

dictionary update sequence element #29 has length 1; 2 is required

Open JC1869 opened this issue 1 year ago • 3 comments

Hello,

I have a sainlogic ws0300 pws that only supports sending to weatherunderground. I'm using dns redirection to send the updates to interceptor in wu-client listen mode. It appears the sainlogic POST adds a trailing & which is breaking everything. I used a packet capture to get the full URL and I can submit it without the trailing character from my browser and it succeeds. Is there a simple modification I can make somewhere to get past this?

Nov 20 12:59:27 weewx[18] ERROR user.interceptor: parse failed for ID=XXXXX&PASSWORD=YYYYY&indoortempf=69.1&indoorhumidity=36&tempf=39.8&humidity=77&temp1f=42.0&humidity1=74&dewptf=33.2&windchillf=37.7&absbaromin=24.49&baromin=30.04&windspeedmph=3.4&windgustmph=4.5&winddir=0&windspdmph_avg2m=3.8&winddir_avg2m=0&windgustmph_10m=2.7&windgustdir_10m=0&rainin=0.0&dailyrainin=0.11&weeklyrainin=0.39&monthlyrainin=0.39&solarradiation=121.58&UV=1&dateutc=2023-11-20%2019:59:27&action=updateraw&realtime=1&rtfreq=5&: dictionary update sequence element #29 has length 1; 2 is required Nov 20 12:59:27 weewx[18] DEBUG user.interceptor: raw packet: {} Nov 20 12:59:27 weewx[18] DEBUG user.interceptor: mapped packet: {} Nov 20 12:59:27 weewx[18] DEBUG user.interceptor: skipping bogus packet {} ('ID=XXXXX&PASSWORD=YYYYY&indoortempf=69.1&indoorhumidity=36&tempf=39.8&humidity=77&temp1f=42.0&humidity1=74&dewptf=33.2&windchillf=37.7&absbaromin=24.49&baromin=30.04&windspeedmph=3.4&windgustmph=4.5&winddir=0&windspdmph_avg2m=3.8&winddir_avg2m=0&windgustmph_10m=2.7&windgustdir_10m=0&rainin=0.0&dailyrainin=0.11&weeklyrainin=0.39&monthlyrainin=0.39&solarradiation=121.58&UV=1&dateutc=2023-11-20%2019:59:27&action=updateraw&realtime=1&rtfreq=5&')

JC1869 avatar Nov 20 '23 20:11 JC1869

I was able to fix this with the added s.rstrip('&') in interceptor.py:

def _cgi_to_dict(s): s=s.rstrip('&') if '=' in s: return dict([y.strip() for y in x.split('=')] for x in s.split('&')) return dict()

JC1869 avatar Nov 21 '23 01:11 JC1869

Nice! Ok, adding this here for others. You had a trailing '&' issue. I had a Leading '&' issue.

ERROR user.interceptor: parse failed for &PASSKEY=xxxxxxxxxxxxxxxxxxx&stationtype=AMBWeatherPro_V5.1.4&dateutc=2024-01-21+19:30:33&tempf=45.3&humidity=99&windspeedmph=0.00&windgustmph=0.00&maxdailygust=5.82&winddir=54&uv=0&solarradiation=54.56&hourlyrainin=0.000&eventrainin=0.441&dailyrainin=0.181&weeklyrainin=0.181&monthlyrainin=4.232&yearlyrainin=4.232&totalrainin=26.961&battout=1&tempinf=67.1&humidityin=45&baromrelin=29.309&baromabsin=29.232&temp1f=58.8&humidity1=62&batt1=1: dictionary update sequence element #0 has length 1; 2 is required

To deal with the leading & just change your code to s=s.lstrip('&')

def _cgi_to_dict(s): s=s.lstrip('&') if '=' in s: return dict([y.strip() for y in x.split('=')] for x in s.split('&')) return dict()

the-butterfry avatar Jan 21 '24 19:01 the-butterfry

Same issue here with a Ambient WS-1965 s=s.lstrip('&') fixed it for me

ryan910 avatar Jan 29 '24 17:01 ryan910