Enphase Envoy-s metered

Hello, question, does anyone have experience with Enpase Envoy-S Metered (Solar energie), you can also read the consumption? and more info of the divice?

Kind regards,
CANS

Did you ever figure this out? I have an Enpahse Envoy that I would very much like to read the consumption data from.

What do you get if you try the requests below in your browser or with curl (replace the IP appropriately)?

http://192.168.86.210/api/v1/production
http://192.168.86.210/production.json

When I attempt what you suggested, it asks me to login (which I am unable to do). I am however able to view all the envoy statistics at envoy.local/home

I am able to successfully change the envoy password using this interface, but I don’t know (or can’t remember) the username in order to login. What is the default password? I tried ‘admin’, ‘envoy’, ‘user’, with no success.

There’s some info at this link. This works for me, but yours might be a little different. The password is the last 6 digits of the serial number. Try this with the links I suggested and see if it works.

curl -s --anyauth --user envoy:083581 http://192.168.86.210/api/v1/production

Nice! Thanks for that link. I am able to visit http://192.168.1.21/production.json and see the information displayed there. I am still unable to login at http://192.168.1.21/production

Now, back to the original question: how do I get that data openhab?

Maybe that second link that didn’t work is a typo? Should be this:

http://192.168.86.210/api/v1/production

But that doesn’t answer your question. The best way in my mind to get this into OH is with Jython using the requests library. Alas, at this point that does not work as the library seems incompatible with the currently used version of Jython.

Second choice is to try this binding: [New Binding] Enphase Envoy Solar System gateway. I have used it and it does work, but I got warnings all the time in my log. You may or may not get them. @captndelta doesn’t seem to be active anymore, so there isn’t any support for this work that I’m aware of.

My third suggestion is to use a shell script and then parse the data in OH. The script below will post to 2 Items (type String) in json format. Run the script as often as you like from cron. Then when the Items change you can parse the json in OH to get the individual elements with a rule. Or convert the script to Python and parse it first, then push the data to the Items. That might be better than this script.

#!/bin/sh

envoyProd=`curl --anyauth -u envoy:083581 http://192.168.86.210/api/v1/production 2>/dev/null`
envoyInverters=`curl --anyauth -u envoy:083581 http://192.168.86.210/api/v1/production/inverters`

curl --header "Content-Type: text/plain" --request POST --data "$envoyProd" http://192.168.86.212:8080/rest/items/EnvoyProd 2>/dev/null
curl --header "Content-Type: text/plain" --request POST --data "$envoyInverters" http://192.168.86.212:8080/rest/items/EnvoyInverters

And my last suggestion which may not work for you is to use Jython without the authorization. This is what I am using today as I worked through the above techniques, but I do not need authorization for this particular request, but it seems like you do. Anyway, I post it here in case it does work for you.

"""
Envoy Jython Rule
"""

from core.rules import rule
from core.triggers import when
from core.actions import HTTP
import datetime
import json

@rule("Envoy Solar Update", description="Picks up Envoy Solar Inverter status", tags=[])
@when("Time cron 11 2/10 * * * ?")
def envoyCollectData(event):

    response = HTTP.sendHttpGetRequest("http://192.168.86.210/api/v1/production", 10000)
    #  envoyCollectData.log.info(response)
    if response is None:
        return None

    jsonResponse = json.loads(response)

    events.postUpdate("EnvoyPower", str(jsonResponse["wattsNow"]))
    events.postUpdate("EnvoyEnergyToday", str(jsonResponse["wattHoursToday"]))
    events.postUpdate("EnvoyEnergy7Days", str(jsonResponse["wattHoursSevenDays"]))
    events.postUpdate("EnvoyEnergyLifetime", str(jsonResponse["wattHoursLifetime"]))

Should you choose to use an external Python script, this might be a reasonable starting point. It’s doing something quite close to what you need. Change the http links, change the Items it is writing to, and change from basic auth to digest auth (see example here).

Thanks very much for your help! I was able to install the Envoy binding you mentioned. I added the binding, PaperUI discovered the Enovy and all the inverters as things with very little effort on my end. I can read the channels for each Inverter (Production Now, Production Max, etc), but I the Envoy channels (of which ‘Consumption Now’ I am most interested in) all return “-NaN” (aka “not a number”). Any idea why that may be?

After a second attempt, I am now able to access the envoy production data at: http://192.168.1.21/api/v1/production

and consumption at:
http://192.168.1.21/api/v1/consumption.

I took a quick look at your Python script and it looks like it would be useable to read this data every 15 minutes, and save it to an OpenHab item. Is that how it is supposed to work? I’m too tired to try tonight, but definitely tomorrow.

Many thanks, and I really look forward to getting this working properly!

I don’t think it would be too hard to debug/update the code in the binding, but it is using an old build process, so I just didn’t see the benefit of going through updating it when a small Python script can do just as well.

Are you sure those 2 URL’s need a password? If they don’t, then you can use the http binding or the sendHttpGetRequest action and the json transformation to get what you need. That’s all there now, no script needed. On my system the api/v1/production does not need a password.

If they do need a password, then the small Python script run periodically which saves to an openHAB Item just as you describe will work well.

It turns out I do not need a password for either of the following links:

http://192.168.86.210/api/v1/production
http://192.168.86.210/api/v1/consumption

I assume this is the same situation you have? That being the case, you would recommend using the “sendHttpGetRequest” action and the json transformation?

I have never used either of those before… any tips?

Thanks again for your help and I am excited to get this going!

If you are adventurous, try the Jython route. Then you can use the script I posted above. See this thread on installation. I’ve given the Jython code for production and you can easily add consumption. I like the Python/Jython over rules DSL, but that’s my preference.

The absolute easiest way to do this is to install the json path transformation and the http binding.

Then you can put something like this in your services/http.cfg file:

# Enphase Envoy
http:envoy.url=http://192.168.86.210/api/v1/production
# refresh every 10 minutes
http:envoy.updateInterval=600000

Then have items such as these:

Number EnvoyPower             "Solar Power [%.2f W]" { http="<[envoy:600000:JSONPATH($.wattsNow)]" }
Number EnvoyEnergyToday       "Solar Energy Today [%.2f Wh]" { http="<[envoy:600000:JSONPATH($.wattHoursToday)]" }
Number EnvoyEnergy7Days       "Solar Energy 7 Days [%.2f Wh]" { http="<[envoy:600000:JSONPATH($.wattHoursSevenDays)]" }
Number EnvoyEnergyLifetime    "Solar Energy Lifetime [%.2f Wh]" { http="<[envoy:600000:JSONPATH($.wattHoursLifetime)]" }

Just add more for consumption.

Alas, the http binding is v1, so it will go obsolete with OH3 when we get there. So yes, a better long term choice is the sendHttpGetRequest as you mention. It’s the same concept. Set up a rule that runs periodically, sends out the request, and parses the result. I can see if I can find anything like this in my rules if you wish. You take the result and apply the json transformation to get the values you want similar to this:

var float solarPower= Float::parseFloat(transform("JSONPATH", "$.wattsNow", responseData))

the above pops it into a variable, but I think you could just as well get this directly to an Item.

This is my first rule (yay), so I had to work my way up the learning curve to get it to work. I DID get the sendHttpGetRequest to work. It returns a string, which I am then able to parse into a Number and display it on the log.

The remaining part of my issue is how to get this value to an Item so I can display it on my sitemap. I read the ‘Rules’ guide, but it mainly talks about updated the states of items (turning a light ON/OFF), but that is not quite what I am after here… Any pointers.

Thanks again for your help!

Use the postUpdate method. Let’s say the Item you want to update is Power. Then you can do this in your rule:

Power.postUpdate(receivedValue)

“receivedValue” is the Number you have from the sendHttpGetRequest.