Efergy Engage Elite Energy Monitor

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?

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

1 Like

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

2 Likes

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)
}
2 Likes

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?

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

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?

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.

That returned data

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

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)
}

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’

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)
}

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)
	}

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.

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.

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…

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”?

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

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

Thanks for your help. Its working great.

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.