Apparent incorrect upload to WU in some cases **solved**
Posted: Thu Sep 01, 2016 10:47 am
I've been running MB (various versions) for well over a year now on a TP-LINK TL-MR3020 taking data from an ObserverIP connected to a Ambient WS-1400-IP. At the moment of this report all versions are current.
Over the last several months I occasionally had scenarios where the WU page for my station (KCAMOUNT75) would not load completely and the map and graph/tables would be missing. Today I finally had enough time to dig into this. I had already noticed, in the past, that when this happens, my browser's console has error messages (seen both on FireFox and Safari), along the lines of: "SyntaxError: Left hand side of operator '=' must be a reference." This error aborts the running JavaScript, which then in turn "kills" the rest of the page.
Today I looked into this a little deeper and found (using the debugger in the webkit inspector) that the problem happens when an Ajax call on the page retrieves the station historical data (so the table and graphs can be produced) and receives syntactically incorrect JSON/Javascript expression back. The line in question that produces the error looks like this:
Looking at the rest of the JSON around it, it appears that entries before and after are (often) free of this problem. Here is a small excerpt (WU apparently produces datapoints 5 minutes apart):
The entry in the middle has two such problem cases, the one before and after are fine. Furthermore it is interesting that the problem entries contains MeteoBridge template variable expressions. It should be noted here that I do not use MB's standard WU upload function, but rather use a custom crafted http request. The relevant portion of the custom URL contains:
So it appears that somehow in the process of forming the actual URL MB failed to substitute a value for the expression and leaves the expression itself instead (this is documented to mean missing or malformed data). To further explain this it must also mean that WU receives all URL parameters and stores their values as text (if not, it would have failed to parse the template expressions left in there, as float values are apparently expected). Furthermore, WU's JSON generator is apparently then also written to render the value stored (the text of the template expression) without quotes because it "believes" it is rendering a float value (which should not have quotes).
One would come to the conclusion that WU is rather brain dead in accepting such obviously non-sense values to begin with, let alone echo them without any check of correctness, causing a browser Javascript crash. Apparently, for reasons I have not yet determined, my sensors, or the ObserverIP, occasionally produce missing/invalid data. I am not going to "fix" that because right now it is helpful in debugging this, and possible solutions, but it is probably as simple as a new battery in the indoor unit.
So the following questions come up:
The third option could be implemented with backwards compatibility. It would require first parsing/deconstructing the URL. Next process all parameter values and if the value is precisely a single template variable expression (starts and ends with brackets), then evaluate and substitute. Then reconstruct, and process the whole URL as a string to catch cases where template expressions where used in other ways. For backwards compatibility we would only have to address the case where no replacement value is specified, and, somehow, the user indicated a new behavior was desired. For example, if we allow a converter to be prefixed by the exclamation mark, it would indicate that a parameter would have to be eliminated if data is missing or malformed. It should be noted that, in many cases, the actual converter is empty: the exclamation by itself would mean "standard converter but leave out if missing/malformed). So my example would then look:
Alternatively would could introduce "#" to replace "=!":
A different approach altogether is to require "{}" instead of "[]" for parameter substitutions that we want to be treated this way:
All of these would be a lot more concise than putting replacement values on everything (except if they are all empty strings, but that would not solve all cases).
The second option could be handled in a similar manner by introducing a "pseudo"variable that, when seen even once in the whole template, if any conversion fails, the whole request would be abandoned. Since we would not want to repeat that for every parameter perhaps we could introduce [nogo] as a special pseudo variable that requests this behavior. Or, if we would like a specific expression to trigger this (but not some others), it could be done with another special prefix before the converter. May be something like "!!". Any single one of such failed "conversion" would drop the request.
Since I believe that even using the replacement string option will not allow me to completely "fix" this problem with this particular service (WU), even if it did it would be extremely tedious and I would prefer if one of the proposed alternatives were implemented (or something like it or equivalent to it).
Over the last several months I occasionally had scenarios where the WU page for my station (KCAMOUNT75) would not load completely and the map and graph/tables would be missing. Today I finally had enough time to dig into this. I had already noticed, in the past, that when this happens, my browser's console has error messages (seen both on FireFox and Safari), along the lines of: "SyntaxError: Left hand side of operator '=' must be a reference." This error aborts the running JavaScript, which then in turn "kills" the rest of the page.
Today I looked into this a little deeper and found (using the debugger in the webkit inspector) that the problem happens when an Ajax call on the page retrieves the station historical data (so the table and graphs can be produced) and receives syntactically incorrect JSON/Javascript expression back. The line in question that produces the error looks like this:
Code: Select all
"temperature_indoor": [thb0temp-act=F.1]
Code: Select all
{
"date": {
"epoch": 1472632320,
"iso8601": "2016-08-31T01:32:00-0700",
"tz_offset_hours": -7.00
},
"temperature":60.8,
"dewpoint":54.7,
"humidity": 80,
"wind_speed":0.0,
"wind_gust_speed":0.0,
"wind_dir_degrees": 306,
"wind_dir": "NW",
"pressure":29.90,
"windchill":null,
"heatindex":null,
"precip":0.00,
"precip_rate":0.00,
"precip_1hr":0.00,
"precip_today":0.00,
"solarradiation": 0.0,
"uv_index": 0.0,
"temperature_indoor": 75.4,
"humidity_indoor": 55.0,
"software_type": "MeteoBridge 3.0/1005"
},
{
"date": {
"epoch": 1472632680,
"iso8601": "2016-08-31T01:38:00-0700",
"tz_offset_hours": -7.00
},
"temperature":60.6,
"dewpoint":54.5,
"humidity": 80,
"wind_speed":0.0,
"wind_gust_speed":0.0,
"wind_dir_degrees": 278,
"wind_dir": "West",
"pressure":null,
"windchill":null,
"heatindex":null,
"precip":0.00,
"precip_rate":0.00,
"precip_1hr":0.00,
"precip_today":0.00,
"solarradiation": 0.0,
"uv_index": 0.0,
"temperature_indoor": [thb0temp-act=F.1],
"humidity_indoor": [thb0hum-act],
"software_type": "MeteoBridge 3.0/1005"
},
{
"date": {
"epoch": 1472632980,
"iso8601": "2016-08-31T01:43:00-0700",
"tz_offset_hours": -7.00
},
"temperature":60.4,
"dewpoint":54.9,
"humidity": 82,
"wind_speed":0.0,
"wind_gust_speed":0.0,
"wind_dir_degrees": 237,
"wind_dir": "WSW",
"pressure":29.89,
"windchill":null,
"heatindex":null,
"precip":0.00,
"precip_rate":0.00,
"precip_1hr":0.00,
"precip_today":0.00,
"solarradiation": 0.0,
"uv_index": 0.0,
"temperature_indoor": 75.0,
"humidity_indoor": 55.0,
"software_type": "MeteoBridge 3.0/1005"
},
Code: Select all
http://rtupdate.wunderground.com/weatherstation/updateweatherstation.php?action=updateraw&ID=KCAMOUNT75&<... stuff deleted ...>&indoorhumidity=[thb0hum-act]&indoortempf=[thb0temp-act=F.1]&<...more deleted...>
One would come to the conclusion that WU is rather brain dead in accepting such obviously non-sense values to begin with, let alone echo them without any check of correctness, causing a browser Javascript crash. Apparently, for reasons I have not yet determined, my sensors, or the ObserverIP, occasionally produce missing/invalid data. I am not going to "fix" that because right now it is helpful in debugging this, and possible solutions, but it is probably as simple as a new battery in the indoor unit.
So the following questions come up:
- What is going wrong in expression eval?
- Is it not receiving any data for these sensor values from the ObserverIP?
- Or incorrect data from the ObserverIP (something that does not parse)?
- Or some rare case with valid data, but a bug in MB code (seems unlikely, but just mentioning it)
- What makes sense to do in these cases? All the other sensors do have good values. I can think of several options:
- Use the "replacement" string option. Without specifying a replacement, we get exactly the behavior described here (and as documented: "When a variable is not defined or there is no data for a specified sensor, information specified as "replacement" string will be represented instead."). Therefore this would require the template creator (user) to specify a value for every sensor where this could possibly happen (which generally will mean all of them). This might work (although may be not for the WU case presented here), but will make templates a lot more tedious.
- Skip the whole HTTP request. This is in contradiction to the current documentation, so would not be backwards compatible. However, for a generic http request facility, this might be desirable behavior. If we would want to enable this, we would need a backwards compatible changes to template processing.
- Leave out the whole URL parameter: instead of producing "indoorhumidity=[thb0hum-act]&" produce just "&". This too contradicts current documentation, might be the desired behavior for a specific case, and would need a template processing change.
The third option could be implemented with backwards compatibility. It would require first parsing/deconstructing the URL. Next process all parameter values and if the value is precisely a single template variable expression (starts and ends with brackets), then evaluate and substitute. Then reconstruct, and process the whole URL as a string to catch cases where template expressions where used in other ways. For backwards compatibility we would only have to address the case where no replacement value is specified, and, somehow, the user indicated a new behavior was desired. For example, if we allow a converter to be prefixed by the exclamation mark, it would indicate that a parameter would have to be eliminated if data is missing or malformed. It should be noted that, in many cases, the actual converter is empty: the exclamation by itself would mean "standard converter but leave out if missing/malformed). So my example would then look:
Code: Select all
<... stuff deleted ...>&indoorhumidity=[thb0hum-act=!]&indoortempf=[thb0temp-act=!F.1]&<...more deleted...>
Code: Select all
<... stuff deleted ...>&indoorhumidity=[thb0hum-act#]&indoortempf=[thb0temp-act#F.1]&<...more deleted...>
Code: Select all
<... stuff deleted ...>&indoorhumidity={thb0hum-act}&indoortempf={thb0temp-act=F.1}&<...more deleted...>
The second option could be handled in a similar manner by introducing a "pseudo"variable that, when seen even once in the whole template, if any conversion fails, the whole request would be abandoned. Since we would not want to repeat that for every parameter perhaps we could introduce [nogo] as a special pseudo variable that requests this behavior. Or, if we would like a specific expression to trigger this (but not some others), it could be done with another special prefix before the converter. May be something like "!!". Any single one of such failed "conversion" would drop the request.
Since I believe that even using the replacement string option will not allow me to completely "fix" this problem with this particular service (WU), even if it did it would be extremely tedious and I would prefer if one of the proposed alternatives were implemented (or something like it or equivalent to it).