[UNSUPPORTED] Enphase Envoy (local access)

That got it.

Not sure what you mean by entering dates is error prone. We need the other system data so I would think the date would be the easy part. I had to search for my panel and the inverter size. The date was easy. LOL I would suspect more people will be getting the newer system and they may run into this issue.

Oh and thanks for this in the first place. Love having the info at my fingertips.

The issue lies in data formats - there are a gazillion of them and it needs to be right in order to being able to properly parse things…

Gotcha. I just figured enter month day year and all good like I did in the DH code. But figures it’s not that easy.

Hey I learned something today. But can’t figure out how to post it all neat like yours looks. LOL

So I played around and added this:
input(title: “”, description: “Enter date as MMM DD, YYYY\n\n Ex: Oct 07, 2016”, type: “paragraph”, element: “paragraph”, displayDuringSetup: true)
input(“datedata”, “string”, title: “Date”,
defaultValue:“Oct 01, 2016”, required: true, displayDuringSetup: true)

and changed this:

state.installationDate = new Date().parse(“MMM dd, yyyy”, “Oct 12, 2016”).getTime()

To:

state.installationDate = new Date().parse(“MMM dd, yyyy”, datedata).getTime()

And now I can enter the date and it shows and calculates correctly. Whoo Hoo. I know it leaves room for someone to enter the date wrong but serves my purpose.

To use in-line code you surround it between single back ticks (`in-line code`).
To show long pieces of code, you put it between two lines that contain three single back ticks each (```):

```
multi-line code snippet
```

Yes - your fix works (and only uses the settings value if it can’t find it from the device itself - it still requires the user to manually enter the date even if it wouldn’t be required though…

Also,

state.installationDate = new Date().parse("MMM dd, yyyy", datedata).getTime()

should be

state.installationDate = new Date().parse("MMM dd, yyyy", settings.datedata).getTime()

(adding the settings.)

Thanks,

I changed it so I believe the date isn’t required(changed required to false and removed the default value)

 input(title: "", description: "If you have a newer Envoy, Enter date as MMM DD, YYYY\n\n Ex: Oct 07, 2016", type: "paragraph", element: "paragraph", displayDuringSetup: true)
    input("datedata", "string", title: "Date",
        required: false, displayDuringSetup: true)

Hey that worked. :grin:

Also going to post it to Github. I fixed the color issue on tiles using Android.(not sure how it effects IOS). Feel free to merge it if works OK and you want to.

Now only issue left for is the graph disappearing on a refresh. I have to completely close/force close the ST app for the graph to show up again. But I seem to recall this is an platform/android issue.

Thanks again for helping me out.


After a refresh

Date of install correct and calculating lifetime correct after manual input in settings.

I think I mess up the Github posting, sorry still learning,. It looks like it may have posted my changes 3 times in the same file and I can’t figure out how to delete it. UGH Let me know if I fixed enough to be usable.

The problem with that fix is that it will lose the number formatting on iOS which makes the efficiency display not as useful.

A long time ago I asked for an additional optional parameter for tile definitions that would allow specifying the number format - I am not sure that ever will happen though :cry:

It should come back after a while - at least it does on iOS.

Whilst we’re on the topic of the newer Envoy-S, as it turns out you can get the system install date from:

http://[local IP of Envoy]/inventory.json

As an example, you can find the inventory.json from my Envoy-S Metered unit here:

https://dl.dropboxusercontent.com/u/2449289/inventory.json

More details surrounding this API can be found on the below page (this is an excellent little resource):

This could be leveraged to create a more permanent fix for those of us who have the later Envoy-S.

1 Like

So, for those with the newer square Envoy-S Metered, the below code will automatically retrieve your installation date and set it appropriately.

Firstly, update your pullData() method as per below:

def pullData() {
	state.lastRequestType = (state.api == "HTML" || !state.installationDate ? "HTML" : "JSON API")
	log.debug "${device.displayName} - requesting latest data from Envoy via ${state.lastRequestType}…"
	updateDNI()
	sendHubCommand(new physicalgraph.device.HubAction([
		method: "GET",
		path: state.lastRequestType == "HTML" ? "/production?locale=en" : "/api/v1/production",
		headers: [HOST:getHostAddress()]
	]))

	if(state.installationDate == -1) {
        log.debug "${device.displayName} - attempt to determine installation date via inventory.json on newer Envoy-S"
        updateDNI()
        sendHubCommand(new physicalgraph.device.HubAction([
            method: "GET",
            path: "/inventory.json",
            headers: [HOST:getHostAddress()]
        ]))
    }
}

Once you’ve done this, you’ll then want to add the below snippet at your new line 430:

    else if ((state.installationDate == -1) && (msg.json != null) && (msg.json.devices != null)) {
		def installationDate = new Date((msg.json.devices[0].installed[0] as long) * 1000)
        state.installationDate = installationDate.getTime()
        log.debug "${device.displayName} - system has been live since ${installationDate.format("MMM dd, yyyy")}"
        sendEvent(name: 'installationDate', value: "System live since " + new Date(state.installationDate).format("MMM dd, yyyy"), displayed: false)
        return null
    }

Once done, the hub will now retrieve the inventory.json and use the contents to determine the installation date (based off the installation date of the first device in the json file):

Can someone else with a newer Envoy please confirm this works as expected on their system too?

It worked for me. It does show an error in IDE referring the new line starting with Else if. But it pulled the date just fine.

error java.lang.NullPointerException: Cannot invoke method getAt() on null object @ line 430
1 Like

Thanks for testing this … I’ll publish a complete version of the device handler after work today as I suspect I’ve already resolved this issue.

I’ll keep you posted :slight_smile:

1 Like

Here you go, this version should not only correctly retrieve the installation date on a newer Envoy-S, but also retrieve updates from the unit without causing a NullPointerExemption.

Let me know if you have any issues!

Great job! However, wouldn’t it be better to get the JSON for the installation date upon failure to retrieve it from the HTML source rather than in pullData()? With the current setup, everyone will get a failed request (either the HTML or the inventory JSON).

I’ll try to incorporate that into my version (yours seems to be based on an earlier version of the DTH) but I don’t have access to a newer Envoy for testing…

You’re absolutely correct - that would be a much better place to attempt the inventory.json method of determining the installation date.

I actually have a further round of changes which allow for two instances of the device handler to be deployed to support consumption monitoring too.

This allows SmartThings users the ability to create logic surrounding the net position on power. ie. only turn on X when there’s Y net power (production minus consumed). Or perhaps, do not turn on device Z when consumption is over ABC.

The user experience is similar to that below:

Perhaps we could incorporate both round of changes and test simultaneously?

Sounds like a plan - I’m a little busy at the moment so bear with me…

When you find a moment, you’ll find that the latest version of the DTH (based upon the 1.4 release) on my Dropbox account. The key challenge I found when attempting to get the consumption handler up and running was the unique network ID conflict in SmartThings - SmartThings prevents two devices from holding the same network ID. To get around this, each Envoy device handler (production and consumption) now only sets the network ID prior to making a call to the device, then immediately sets the network ID to a random string to avoid a conflict with the opposing handler.

The DTH I’ve been running for a few days now without issues includes the following changes:

  • Lines 34-35: Added production/consumption mode selector to the preferences screen.
  • Lines 299-311: Updated the startPoll() method to prevent the production and consumption devices from clashing when accessing the same network device within SmartThings (they alternate on odd/even minutes).
  • Lines 320-335: Added removeDNI() method.
  • Lines 352-370: Updated pullData() method to dynamically generate the URI/path based on what mode the DTH is running under.
  • Lines 428-429: Added call to removeDNI() to be run 5 seconds after parse() has been called to remove/reset the device network ID.
  • Lines 467-473: Added else statement to catch the response for the inventory.json call for setting system installation dates on newer Envoy-S Metered devices.

I’m reasonably sure that’s all of the changes I’ve made… as per the below screenshots, it seems to be working quite well.

Hey @ahndee

For the last week or so this is all i get in the graph

Thoughts?
Rick

Yikes!! All is fine here with graphing on android for me. Does your Enlighten page look fine?

Yes, that all looks fine

Android as well

Rick