Efergy Engage Elite Energy Monitor


(Anthony S.) #1

Hello Everyone,

I’m still new to this groovy\smartthings programming and i am trying to pull in my home energy use. I’ve tried searching for tutorials for beginners on this stuff, but i’m struggling to get my bearings.

The API url is "https://engage.efergy.com/mobile_proxy/getInstant?token=APITOKENHERE"
It returns this JSON:
{
age: 5,
last_reading_time: 1429546828000,
reading: 622
}

Could someone point me to a similar Device Type and Smart App i can mirror off of?


(Kris Schaller) #2

Hey @tonesto7,

Have you seen the developer docs for this yet? They’re a great resource. We’re planning on releasing some walk-throughs for more of these issues that are pain-points for beginners. :smile:

http://docs.smartthings.com/en/latest/smartapp-developers-guide/calling-web-services-in-smartapps.html


(Jim Anderson) #3

There’s also an example here of using httpGet to call a Weather Underground API.


(Andy Rawson) #4

Here is a fairly simple device type that does basically the same thing. https://github.com/AndyRawson/SmartThings/blob/master/SparkThings/sparkthings-devicetype.groovy

Something like this should work for you:

private checkStatus() {
    def readingClosure = { 
        response -> response.data.each { 
            item ->
                log.debug "age: $item.age"
                log.debug "last reading time: $item.last_reading_time"
                log.debug "reading: $item.reading"
        }
    }
    httpGet("https://engage.efergy.com/mobile_proxy/getInstant?token=${token}", readingClosure)
}

(Anthony S.) #5

Seriously everyone thanks for the prompt reply’s.

I really appreciate the code Andy i will try it out.
I will need a device type now correct?
Any suggestions there?


(Anthony S.) #6

Nevermind the last question… I viewed the code from the spark things device


(Anthony S.) #7

Here is my device type:

preferences {
    input "token", "text", title: "Access Token", required: true

}

metadata {
definition (name: “Efergy Engage Elite Energy Monitor”, namespace: “tonesto7”, author: “tonesto7”) {
capability "Energy Meter"
capability “Polling”
}

simulator {
// TODO: define status and reply messages here
}

tiles {
valueTile(“energy”, “device.energy”, decoration: “flat”) {
state “default”, label:’${currentValue} kWh’
}

    main (["energy"])
  }

}

// parse events into attributes
def parse(String description) {
log.debug “Parsing ‘${description}’”
}

// handle commands
def poll() {
log.debug "Executing ‘poll’"
getReading()
}

// Get the sensor reading
private getReading() {
def readingClosure = {
response -> response.data.each {
item ->
log.debug "age: $item.age"
log.debug "last reading time: $item.last_reading_time"
log.debug “reading: $item.reading”
}
}

httpGet("https://engage.efergy.com/mobile_proxy/getInstant?token=${token}", readingClosure)

}

Unfortunately its not returning any data. I can see the empty log entries for the Age, last_reading, and reading.
Thoughts?


(Andy Rawson) #8

See what you are getting back with this:

private getReading() {
    def readingClosure = { 
        response -> 
        log.debug "result: $response.data"
    }
httpGet("https://engage.efergy.com/mobile_proxy/getInstant?token=${token}", readingClosure)
}

Then we can go from there.


(Anthony S.) #9

That returned data

8:12:02 AM: debug result: {“age”:9,“last_reading_time”:1430309513000,“reading”:667}


(Andy Rawson) #10

Ok, then this should work.

private getReading() {
    def readingClosure = { 
        response -> 
            log.debug "result: $response.data"
            log.debug "age: $response.data.age"
            log.debug "last reading time: $response.data.last_reading_time"
            log.debug "reading: $response.data.reading"
    }
httpGet("https://engage.efergy.com/mobile_proxy/getInstant?token=${token}", readingClosure)
}

(Anthony S.) #11

Here is the output…

0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 8:21:51 AM: debug reading:
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 8:21:51 AM: debug last reading time:
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 8:21:51 AM: debug age:
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 8:21:51 AM: debug result: {“age”:8,“last_reading_time”:1430310103000,“reading”:620}
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 8:21:50 AM: debug Executing ‘poll’


(Andy Rawson) #12

Ok, testing with https://engage.efergy.com/mobile_proxy/getInstant shows that they return it as Content-Type: text/html instead of Content-Type: application/json so it looks like if we modify the content type in the httpGet we should get proper JSON back.

private getReading() {
    def readingClosure = { 
        response -> 
            log.debug "result: $response.data"
            log.debug "age: $response.data.age"
            log.debug "last reading time: $response.data.last_reading_time"
            log.debug "reading: $response.data.reading"

def params = [
    	uri: "https://engage.efergy.com",
    	path: "/mobile_proxy/getInstant?token=${token}",
        contentType: 'application/json'
    ]

httpGet(params, readingClosure)
}

(Anthony S.) #13

I made the changes you suggested and this is the output.

0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 12:27:34 PM: debug reading: null
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 12:27:34 PM: debug last reading time: null
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 12:27:34 PM: debug age: null
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 12:27:34 PM: debug result: [status:error, description:bad token]
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 12:27:34 PM: debug Executing ‘poll’

How would I config the polling frequency?
Here is the full code:

preferences {
        input "token", "text", title: "Access Token", required: true
	}

	metadata {
	definition (name: "Efergy Engage Elite Energy Monitor", namespace: "tonesto7", author: "tonesto7") {
		capability "Energy Meter"
        capability "Polling"
	}

	simulator {
		// TODO: define status and reply messages here
	}
	
	tiles {
    	valueTile("energy", "device.energy", decoration: "flat") {
			state "default", label:'${currentValue} kWh'
		}
		
        main (["energy"])
		}
 	}

	// parse events into attributes
	def parse(String description) {
		log.debug "Parsing '${description}'"
	}

	// handle commands
	def poll() {
		log.debug "Executing 'poll'"
    	getReading()
	}


	// Get the sensor reading
	private getReading() {
    def readingClosure = { 
        response -> 
            log.debug "result: $response.data"
            log.debug "age: $response.data.age"
            log.debug "last reading time: $response.data.last_reading_time"
            log.debug "reading: $response.data.reading"
			}
	def params = [
    	uri: "https://engage.efergy.com",
    		path: "/mobile_proxy/getInstant?token=${token}",
        	contentType: 'application/json'
    		]

	httpGet(params, readingClosure)
	}

(Andy Rawson) #14

Looks like the token is bad now but it is returning as JSON with the square brackets. [status:error, description:bad token]

I use Pollster to handle polling frequency changes. I haven’t looked into any other ways.


(Anthony S.) #15

I am very appreciative of the time you’ve given to help through this so thanks…

The token still works if I use it with previous function you sent. So something is missing with the new code.
I will use the pollster since I am using it for something else till i get better with the code to integrate it.


(Andy Rawson) #16

Hmm, it looks like the query part may need to be broken out when the path is split from the uri.

private getReading() {
    def readingClosure = { 
        response -> 
            log.debug "result: $response.data"
            log.debug "age: $response.data.age"
            log.debug "last reading time: $response.data.last_reading_time"
            log.debug "reading: $response.data.reading"

def params = [
    	uri: "https://engage.efergy.com",
    	path: "/mobile_proxy/getInstant",
        query: ["token": token],
        contentType: 'application/json'
    ]

httpGet(params, readingClosure)
}

Almost there…


(Anthony S.) #17

Amazing! that was it…

0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 2:18:01 PM: debug reading: 680
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 2:18:01 PM: debug last reading time: 1430417879000
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 2:18:01 PM: debug age: 2
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 2:18:01 PM: debug result: [last_reading_time:1430417879000, reading:680, age:2]
0d00b71d-9f55-4eec-ba0a-4d12ed5d8722 2:18:00 PM: debug Executing 'poll'

So what variable would I reference for the tiles label to show the “reading”?


(Andy Rawson) #18

You would probably want to use something like this right after the log.debug lines

sendEvent(name: "energy", value: response.data.reading)

(Anthony S.) #19

Thanks for your help. Its working great.


(Anthony S.) #20

I figured this out :slight_smile:

I have been able to modify the date output from epoch UTC to a actual date.

last reading time: 1430946840000
Last Updated: Wed May 06 21:14:00 UTC 2015

How can i apply the timezone offset “EST” to this?

log.debug "Last Updated: ${new Date(response.data.last_reading_time as long)}"

I’m really struggling with this language! I have been researching but it’s so weird compared to C# which i am very fluent.