New Plugin: SiteSensor

Hi Rigapapa,
I am using your twilight recipe with the sitesensor plugin. The local time offset is incorrectly returned as -4 hours in expression 3 & 4. The timezone offset is clearly -3 hours in the get function. Can you have a look why this is happening?

08:31:37: SiteSensor: “GET” “https://api.sunrise-sunset.org/json?lat=44.6453&lng=-63.5724&date=2019-03-26T12:00:00%2B0300&formatted=0”, headers={ }
08:31:37: SiteSensor: Eval #1: “response.results.civil_twilight_begin”=(“string”)“2019-03-26T09:36:06+00:00”
08:31:37: SiteSensor: Eval #2: “response.results.civil_twilight_end”=(“string”)“2019-03-26T23:03:33+00:00”
08:31:37: SiteSensor: Eval #3: “strftime("%x %X", time(expr[1]))”=(“string”)“03/26/19 05:36:06”
08:31:37: SiteSensor: Eval #4: “strftime("%x %X", time(expr[2]))”=(“string”)“03/26/19 19:03:33”
08:31:37: SiteSensor: Eval trip expression: “! ((time() >= time(response.results.civil_twilight_begin)) & (time() < time(response.results.civil_twilight_end)))”=(“boolean”)false

OK. Try installing the latest release in the Github stable branch.

Instructions, if you need them:

  1. Go to the above link;
  2. Click the green “Download or clone” button and choose Download ZIP;
  3. Save the ZIP file somewhere;
  4. UnZIP the file;
  5. Upload the unzipped contents using the uploader at Apps > Develop apps > Luup files. Be sure to turn off the “Restart after upload” checkbox until the last file, and then turn it back on for the last file. If you forget, no worries, just check the box and upload the file again.
  6. Hard-refresh your browser (CTRL-F5 for Chrome/Win, SHIFT-F5 for Firefox/Win, CMD+SHIFT+R for most Mac browsers)

Hi Rigpapa,

The stable branch version of sitesensor is now working correctly for the time zone offset.

Thank you so much for the quick response and your continued and significant contribution to the Vera community.

2 Likes

Hi Rigpapa!
I am trying to use Site Sensor to extract data from my Weather Underground PWS with their new free API for contributors.
I can get Site Sensor to successfully obtain the data in JSON format with the following URL:

https://api.weather.com/v2/pws/observations/current?stationId=KCOLOVEL129&format=json&units=e&apiKey=myAPIKey

The JSON returned looks like this:

observations
0
stationID “KCOLOVEL129”
obsTimeUtc “2019-04-05T17:02:53Z”
obsTimeLocal “2019-04-05 11:02:53”
neighborhood “Buckhorn Village”
softwareType “”
country “US”
solarRadiation null
lon -105.12919617
realtimeFrequency null
epoch 1554483773
lat 40.43574524
uv null
winddir 102
humidity 46
qcStatus 1
imperial
temp 61
heatIndex 61
dewpt 41
windChill 61
windSpeed 4
windGust 9
pressure 30.06
precipRate 0
precipTotal 0
elev 5208

What I am having trouble with is coming up with the correct expressions for reading the JSON values for stationID:, humidity:, temp:, windSpeed:, pressure:, and precipTotal.

I am working from your recipe for openweathermap. Can you provide any guidance on one of the expressions? With one working example, I should be able to get the idea for the rest.
Thanks,
Jeff

I’ll be happy to help, but I need to see the actual raw JSON output. Please post, putting three backticks (``` ASCII 96) on lines by themselves both before and after.

Thanks for the help, Rigppa.
Here is the raw data with three backtics before and after. Hope this is the format you wanted.

{"observations":[{"stationID":"KCOLOVEL129","obsTimeUtc":"2019-04-05T17:39:18Z","obsTimeLocal":"2019-04-05 11:39:18","neighborhood":"Buckhorn Village","softwareType":"","country":"US","solarRadiation":null,"lon":-105.12919617,"realtimeFrequency":null,"epoch":1554485958,"lat":40.43574524,"uv":null,"winddir":122,"humidity":43,"qcStatus":1,"imperial":{"temp":64,"heatIndex":64,"dewpt":42,"windChill":64,"windSpeed":9,"windGust":11,"pressure":30.04,"precipRate":0.00,"precipTotal":0.00,"elev":5208}}]}

Thanks again.
Jeff

Perfection! OK. The challenge that makes this just a bit harder than a straight reference to each subkey is that observations is an array (of just one element, but an array nonetheless), so to get at the data inside, you have to go through the array. SiteSensor puts the entire response under a key called response, so the first element of the observations array can be accessed using response.observations[1] or first( response.observations ).

From there, you can hit the elements directly: response.observations[1].humidity for example.

The current temperature, barometric pressure, and wind speed are all under a subkey called imperial, so you get them by doing response.observations[1].imperial.temp, etc.

If you want the sensor to trip on a value or range, you can build that into the trip expression. For example, if you want the sensor to trip when the temp drops below 35F, we just build an expression that results in boolean true: response.observations[1].imperial.temp < 35

Worked like a champ! Hit your tip jar via PayPal. Now, I can begin building a replacement for the WU plugin for my stations. Thanks again.
Jeff

1 Like

Does the first expression in Site Sensor have to be response.observations[1] or can it be a direct call for the response.observations[1].imperial.temp or does the array have to be loaded with the response.observations[1] before the other responses can be called?

Each expression must begin with response.observations[1], and from there you add a dot and the next subkey name…

response.observations[1].humidity
response.observations[1].neighborhood
response.observations[1].imperial.temp
response.observations[1].imperial.windSpeed 
etc.

Also note that case is important. Look at your JSON to get the correct spelling/case for the key.

I am having an issue getting json data from www.alphavantage.co

My log shows the following. (I have removed my key.)

14:56:42: SiteSensor: Requesting JSON data
14:56:42: SiteSensor: Set up for HTTPS request, verify=“none”, protocol=nil, options=nil
14:56:42: SiteSensor: “GET” “https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=.dji&apikey=???”, headers={ }
14:56:42: SiteSensor: Eval #1: “response.GlobalQuote”=(“table”){ __type=“null” }

The json data looks like this:
{
“Global Quote”: {
“01. symbol”: “^DJI”,
“02. open”: “26357.8000”,
“03. high”: “26436.7000”,
“04. low”: “26309.7200”,
“05. price”: “26376.4600”,
“06. volume”: “278756696”,
“07. latest trading day”: “2019-04-12”,
“08. previous close”: “26143.1000”,
“09. change”: “233.4102”,
“10. change percent”: “0.8928%”
}
}

So the GlobalQuote table does not contain anything. Are the elements with a period causing an issue? is there a workaround.

It’s storing the table in evaluation 1. What do your expressions 2 through 8 look like?

That is the problem. No matter what I try I get an error. It looks like the table has null entries.
For example:
If expression 2 is: response.GlobalQuote{‘01. symbol’}

The log shows:
17:24:15: SiteSensor: Requesting JSON data
17:24:15: SiteSensor: Set up for HTTPS request, verify=“none”, protocol=nil, options=nil
17:24:15: SiteSensor: “GET” “https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=.dji&apikey=”, headers={ }
17:24:15: SiteSensor: Eval #1: “response.GlobalQuote”=(“table”){ __type=“null” }
17:24:15: SiteSensor: Failed to parse expression `“response.GlobalQuote{‘01. symbol’}”', { location=21, __source=“luaxp”, message=“Invalid operator”, type=“compile” }
17:24:15: SiteSensor: Eval #2: “response.GlobalQuote{‘01. symbol’}”=(“nil”)nil

I think it’s a simple fix. You’re using the wrong characters to quote the subreference.

Try this: response.GlobalQuote['01. symbol'] (square brackets, not curly).

Unfortunately that did not work…

19:02:54: SiteSensor: Requesting JSON data
19:02:54: SiteSensor: Set up for HTTPS request, verify=“none”, protocol=nil, options=nil
19:02:54: SiteSensor: “GET” “https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=.dji&apikey=”, headers={ }
19:02:54: SiteSensor: Failed to execute `“response.GlobalQuote[‘01. symbol’]”', { location=34, __source=“luaxp”, message=“Can’t index null”, type=“evaluation” }
19:02:54: SiteSensor: Eval #1: “response.GlobalQuote[‘01. symbol’]”=(“nil”)nil

I appreciate your time on this. I really like your app.

Sorry, I did not see that “GlobalQuote” is actually “Global Quote”–there’s a space between. So you have to do this:

response['Global Quote']['01. symbol']

Tried that a few a few others.
I have used your app with other websites and it works fine.
For some reason, this one has issues.
Is the period in the json code an issue?

Here are some more results:
12:52:10: SiteSensor: Requesting JSON data
12:52:10: SiteSensor: Set up for HTTPS request, verify=“none”, protocol=nil, options=nil
12:52:10: SiteSensor: “GET” “https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=.dji&apikey=”, headers={ }
12:52:10: SiteSensor: Eval #1: “response.Global_Quote”=(“table”){ __type=“null” }
12:52:10: SiteSensor: Eval #2: “response[‘Global Quote’]”=(“table”){ __type=“null” }
12:52:10: SiteSensor: Eval #3: “response.GlobalQuote”=(“table”){ __type=“null” }
12:52:10: SiteSensor: Failed to parse expression `“response[‘Global Quote’][‘01. symbol’]”', { location=25, __source=“luaxp”, message=“Invalid operator”, type=“compile” }
12:52:10: SiteSensor: Eval #4: “response[‘Global Quote’][‘01. symbol’]”=(“nil”)nil

OK. Let’s try this:

Expr1: temp=response['Global Quote']
Expr2: temp['01. symbol']

14:07:53: SiteSensor: Requesting JSON data
14:07:53: SiteSensor: Set up for HTTPS request, verify=“none”, protocol=nil, options=nil
14:07:53: SiteSensor: “GET” “https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=.dji&apikey=”, headers={ }
14:07:53: SiteSensor: Eval #1: “temp=response[‘Global Quote’]”=(“table”){ __type=“null” }
14:07:53: SiteSensor: Eval #2: “temp[‘01. symbol’]”=(“table”){ __type=“null” }

Makes no sense at all. Something else is wrong. Can you repost the actual JSON response? It seems like we’re shooting at a moving target here.