GroveStreams SmartThings QuickStart

I’m hitting the “free tier” limits only in terms of # of streams (they allow 20, I think; I have two hubs in two separate places, and I exceed it). My invoice last month was about $0.50…

@btk How do i make my dashboard look like that? You are self-hosting? Do you just get a copy of the source and host it on your own machine? I could do that, that isn’t a problem.

What is the cost of that?

Before that though, I wanted to configure a few dashboards with my different temperatures, humidity etc, and see what type of information I’m getting before I put a lot of data up there that isn’t worth while.

What use cases do you get out of it? I would like to set up temp, humidity, I like that display for which switches you have on/off, and I have a few devices that I could track energy usage on.

How did you set that up? Is there a read a documentation for it?

It’s several open source packages running on one of my own servers. ElasticSearch for the backend, Graphite for the graphing, Grafana to make Graphite look decent, and Backstop to accept the input from the SmartApp and shove it into the Graphite instance. There’s no documentation for the entire suite, but each project has its own set of docs.

It’s not an arrangement that would make sense for most users, but they’re tools I already use for other things and am familiar with, so it was convenient for me.

@minollo @JasonBSteele Where is the code for the latest version of the SmartApp? Also, has anything added being able to report devices that are tracking energy yet? I only see, temperature, motion, presence, contact, accelerations, and switches.

I was thinking of adding it, if someone hasn’t done that yet.

Hi @thrash99er, At the bottom of the tutorial (linked to in the OP) there is the final version of the code I am using. It includes energy and power devices. This version does not include any queuing or buffering logic to attempt to prevent exceeding the free usage limits. The reason for this is that it is using an X-Forwarded-For header that is set to the deviceID. So as long as none of your devices exceeds more than one report every 10 seconds (averaged over a 2 minute period) you should be okay.

What a fantastic tool for graphing the data from ST. Excellent for the beginner who wants to look at the overall picture. Thanks to Jason for chasing it and Mike for allowing and his very detailed instructions. A heads up. I loaded every possible variable from ST. It took 12 hours to populate. Seems to be working great.

I went through the quick start with no problems. I used the code at the very bottom to support more device types. I’m seeing this in my logs on the IDE…

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎24‎:‎29‎ ‎PM: debug Logging to GroveStreams Front+Door, temperature = 72

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎24‎:‎29‎ ‎PM: debug Logging to GroveStreams Front+Door, battery = 88

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎22‎:‎00‎ ‎PM: debug Logging to GroveStreams Front+Door, battery = 100

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎21‎:‎59‎ ‎PM: debug Logging to GroveStreams Front+Door, temperature = 74

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎21‎:‎59‎ ‎PM: error groovyx.net.http.HttpResponseException: Unprocessable Entity @ line 134

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎21‎:‎59‎ ‎PM: debug Logging to GroveStreams Front+Door, battery = 100

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎20‎:‎33‎ ‎PM: debug Logging to GroveStreams Atmo+Outdoor, humidity = 75

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎20‎:‎33‎ ‎PM: debug Logging to GroveStreams Atmo+Indoor, temperature = 74.12

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎20‎:‎33‎ ‎PM: debug Logging to GroveStreams Atmo+Outdoor, temperature = 77.36

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎18‎:‎13‎ ‎PM: debug Logging to GroveStreams Drawer, battery = 75

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎18‎:‎13‎ ‎PM: error groovyx.net.http.HttpResponseException: Unprocessable Entity @ line 134

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎18‎:‎11‎ ‎PM: debug Logging to GroveStreams Drawer, battery = 75

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎18‎:‎11‎ ‎PM: debug Logging to GroveStreams Drawer, temperature = 70

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎17‎:‎13‎ ‎PM: debug Logging to GroveStreams Garage+Door+Movement, temperature = 70

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎17‎:‎13‎ ‎PM: debug Logging to GroveStreams Garage+Door+Movement, battery = 88

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎15‎:‎41‎ ‎PM: debug Logging to GroveStreams Drawer, battery = 88

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎15‎:‎41‎ ‎PM: debug Logging to GroveStreams Drawer, temperature = 72

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎14‎:‎43‎ ‎PM: debug Logging to GroveStreams Garage+Door+Movement, temperature = 73

c5f6d721-1d02-4ef6-ba25-56196e7778e2 ‎4‎:‎14‎:‎43‎ ‎PM: debug Logging to GroveStreams Garage+Door+Movement, battery = 100

Any chance we can get a new guide for the V2 of ST hub and new app?

I just got my first ST and really like the idea of temp monitoring with GroveStreams.

Thank you.

I’ve started receiving an error when transmitting data to GroveStreams. The interesting thing is that the transmission still works just fine - all my data is logging to GroveStreams.
But I’m receiving the following: error Error sending value: groovyx.net.http.ResponseParseException: OK

This occurs during the processQueue event, and causes the queue to never be truncated.
I didn’t realize it for a couple of weeks, so that Queue had grown Huge… I’m resetting the app every day or two now to clear it out.

Anyone else receiving this message?
I’ve tried a couple things to try and get more detailed error messaging, but my coding skills are lacking.

Here’s the code that I’m using:

def processQueue() {
def url = "https://grovestreams.com/api/feed?api_key=${channelKey}"
log.debug "processQueue"
if (state.queue != []) {
    log.debug "Events: ${state.queue}"

    try {
        httpPutJson([uri: url, body: state.queue ]) { 
            response -> 
                response.headers.each {
        		log.debug "${it.name} : ${it.value}"
    				}
            //log.debug "response data: ${response.data}"
            if (response.status != 200 ) {
                log.debug "GroveStreams logging failed, status = ${response.status}"
            } else {
                log.debug "GroveStreams accepted event(s)"
                state.queue = []
                state.queueCount = 0
            }
        }
    } catch(e) {
        def errorInfo = "Error sending value: ${e}"
        log.error errorInfo
    }
}

}

An update to the ST platform several weeks ago introduced an issue where httpPutJson is not able to handle responses which are successful (200, OK), but which return an empty payload - like what GroveStreams does.
It’s clearly an ST defect; I’ve let support know, and I’ve had a conversation with an engineer, who seemed to be quite reluctant to accept that a) this is a bug, and b) this is a regression; easier to assume that GroveStreams is doing something wrong, of course - which is not true in this case.

I haven’t had any update from support in the last 2-3 weeks; I would recommend reporting this issue, so that at least they see that it’s not just one annoying user bringing this up…

ok I’ll report it too. I only put some cheatcode in to empty the queue in either case. Before that it got up to thousands of items - probably made a stormcloud, can’t be good for infrastructure to store that bag of old data.

How were you able to determine the cause? I looked at the live log which only said “…Exception: OK” Which told me nothing of the cause.

The exception class gives it away (ResponseParseException). I tested the call outside ST with Postman, and verified that the response payload is indeed empty; I then tested a different web service returning a payload on PUT, and that made ST happy…

1 Like

I successfully set this up yesterday to monitor only two streams from my Aeon energy monitor: power and energy. It reports every 5 minutes. In less than 24 hours, I was blocked for exceeding the data limit. 5MB is the limit, so I’m surprised this was reached. Anyone else having issues?

Hmm… sounds surprising. I have almost the same setup (Aeon HEM, 5 minute updates), and I also log a number of contact sensors and temperatures as well. Never been blocked (or warned).

You might check your Grovestream data, verify the time interval and amount of data.

GroveStream support helped out, on Thanksgiving no less. The polling was set to 30 seconds on some dashboard elements, so it was the browser requests that took me over the data usage. They reset. I modified that setting, and all is good now.

I just set up this app and am also getting the ResponseParseException. Any updates on how to handle that?

It’s a false positive, you can ignore it.

However, if you’d like to not see it clogging up the logs, here is an update to the GroveStreams smartapp code. Replace the sendEvent() method with this one…

private sendValue(evt, Closure convert) {
	def compId = URLEncoder.encode(evt.displayName.trim())
	def streamId = evt.name
	def value = convert(evt.value)
	
	log.debug "Logging to GroveStreams ${compId}, ${streamId} = ${value}"
	
	def url = "https://grovestreams.com/api/feed?api_key=${apiKey}&compId=${compId}&${streamId}=${value}"
	
	//Make the actual device the origin of the message to avoid exceeding 12 calls within 2 minutes rule:
	//http://forum.grovestreams.com/topic/155/10-second-feed-put-limit-algorithm-change/
	def header = ["X-Forwarded-For": evt.deviceId]
	
	try {
		def putParams = [
			uri: url,
			header: header,
			body: []]
		
		httpPut(putParams) { response ->
			if (response.status != 200 ) {
				log.debug "GroveStreams logging failed, status = ${response.status}"
			}

		}
	} catch (groovyx.net.http.ResponseParseException e) {
		// ignore error 200, bogus exception
		if (e.statusCode != 200) {
			log.error "Grovestreams: ${e}"
		}
	} catch (Exception e) {
 		log.error "Grovestreams: ${e}"
	}
}
1 Like

Think i am getting an error?

72a6f713-174a-42b3-8263-6022cf1bb4d3 12:54:33 PM: debug Logging to GroveStreams Christmas+Tree, power = 33.8
72a6f713-174a-42b3-8263-6022cf1bb4d3 12:54:32 PM: error groovyx.net.http.ResponseParseException: OK @ line 134
72a6f713-174a-42b3-8263-6022cf1bb4d3 12:54:32 PM: debug Logging to GroveStreams Christmas+Tree, power = 29.5
72a6f713-174a-42b3-8263-6022cf1bb4d3 12:54:30 PM: error groovyx.net.http.ResponseParseException: OK @ line 134
72a6f713-174a-42b3-8263-6022cf1bb4d3 12:54:30 PM: debug Logging to GroveStreams Christmas+Tree, power = 30.8
72a6f713-174a-42b3-8263-6022cf1bb4d3 12:54:29 PM: error groovyx.net.http.ResponseParseException: OK @ line 134
72a6f713-174a-42b3-8263-6022cf1bb4d3 12:54:29 PM: debug Logging to GroveStreams Christmas+Tree, power = 29.3

As mentioned above in this same thread, that error is actually a defect in ST; a fairly “benign” defect (your call succeeds anyway), but still quite annoying…

thank you for the quick response