diy solar

diy solar

An Enphase Ensemble Installation

Looks like Enphase has modified local access, requests like http://envoy.local/api/v1/production/inverters now returns a 301 (Moved) response, the new location is https://envoy.local/api/v1/production/inverters, that requires a token which sends you to https://entrez.enphaseenergy.com ... not sure yet if that requires a web lookup to resolve...I'll be annoyed if you lose access when the web is down.

Thread on it here: https://community.enphase.com/s/que...with-loss-of-local-api-connectivity-to-envoys.

Finally had some time to update my homegrown monitoring system. The server issues a JSON Web Token which is sent to the Envoy to be authorized which provides a cookie that is used to validate the request. Here's the first-pass replacement networking class (needs polishing, but shows the "successful" path), keep in mind it won't work when the internet is down as the token server is remote:

Java:
import java.io.FileInputStream;
import java.io.IOException;
import java.net.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
import java.net.http.HttpClient;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;

public class EnvoyNet {
    public EnvoyNet() {    }

    public static void main(String[] args) throws Exception {  // example test program
        Properties properties = new Properties();  // load local data from a propeties file
        properties.load(new FileInputStream("envoy.properties"));  // local file that hold Envoy ID, serial#, and enlighten login
        String envoyAddr = properties.getProperty("envoyIP", "envoy.local"); // e.g., 192.168.0.22
        String envoySerial = properties.getProperty("envoySerial"); // you can see this when you login locally with a browser
        String enlightenPassword = properties.getProperty("enlightenPassword");
        String enlightenLogin = properties.getProperty("enlightenLogin"); // usually your email address
 
        EnvoyNet.init(enlightenLogin, enlightenPassword, envoyAddr, envoySerial); // do this first once to initialize the class and get the cookie

        System.out.println(EnvoyNet.get("https://"+ envoyAddr + "/api/v1/production")); // repeat the "get" for the url of interest
    }

    static HttpClient client;

    private static SSLContext disableCertificateCheck() {
        javax.net.ssl.TrustManager x509 = new javax.net.ssl.X509ExtendedTrustManager() {
            public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws java.security.cert.CertificateException { }
            public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws java.security.cert.CertificateException { }
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;   }
            public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {}
            public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { }
            public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket)   throws CertificateException { }
            public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { }
        };
        SSLContext ctx = null;
        try {
            ctx = SSLContext.getInstance("SSL");
            ctx.init(null, new javax.net.ssl.TrustManager[] { x509 }, null);
        } catch (java.security.GeneralSecurityException ex) {
            System.out.println("Exception while disabling certificate checks: "+ex.getLocalizedMessage());
        }
        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
        return ctx;
    }

    public static void init(String enlightenLogin, String enlightenPassword, String envoyIP, String envoySerial) throws Exception {
        client = HttpClient.newBuilder()
                .sslContext(disableCertificateCheck())
                .cookieHandler(new CookieManager())
                .build();

        String urlParams = "username="+ enlightenLogin + "&password="+enlightenPassword;
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://entrez.enphaseenergy.com/login"))
                .headers("Content-Type", "application/x-www-form-urlencoded")
                .POST(BodyPublishers.ofString(urlParams))
                .build();

        HttpResponse<String> response = client.send(request, BodyHandlers.ofString());

        urlParams = "client=envoy&serialNum="+envoySerial;
        request = HttpRequest.newBuilder()
                .uri(URI.create("https://entrez.enphaseenergy.com/entrez_tokens"))
                .headers("Content-Type", "application/x-www-form-urlencoded")
                .POST(BodyPublishers.ofString(urlParams))
                .build();

        response = client.send(request, BodyHandlers.ofString());
        String body = response.body();
        // <textarea name="accessToken" id="JWTToken" cols="30" rows="10" >eyJr...rA</textarea>

        int i = body.indexOf("id=\"JWTToken\"");
        if (i < 0) throw new Exception("JWTToken not retrieved");
        i = body.indexOf('>', i) +1;
        int j = body.indexOf("</textarea>", i);
        String JwtToken = body.substring(i,j);

        request = HttpRequest.newBuilder()
                .uri(URI.create("https://"+envoyIP+"/auth/check_jwt"))
                .headers("Authorization", "Bearer "+JwtToken)
                .build();

        response = client.send(request, BodyHandlers.ofString());
    }

    public static String get(String url) {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .build();

        HttpResponse<String> response;
        try {
            response = client.send(request, BodyHandlers.ofString());
            return response.body();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Example output from main():
JSON:
{
  "wattHoursToday": 12468,
  "wattHoursSevenDays": 18100792,
  "wattHoursLifetime": 18113260,
  "wattsNow": 4683
}
 
Last edited:
Had an odd battery "burp" yesterday. According to the Enlighten app events, nothing happened... didn't go off-grid or see other events.

But, digging into the Envoy Events there are quite a few events around the burp, and it's across all the IQ8s. A couple of these events (e.g., black-start) I've never seen before. I don't see how the black-start can even be applicable. My self-written monitoring system shows the batteries were all were they should have been (60% SoC) at 10:00.
1642253247698.png

If I'm reading it correctly, the system islanded from around 10:15 to 10:45 even though it knew it was on-grid and the Enlighten doesn't seem to know about it (possible as the system was always on-grid).

Code:
            "Fri Jan 14, 2022 02:30 PM EST" "envoy"                  "ZigbeeModGone : Clear",
            "Fri Jan 14, 2022 02:30 PM EST"  "envoy"                  "ZigbeeModGone : Set",
            "Fri Jan 14, 2022 12:33 PM EST"  "Encharge Controller",  "EnsembleDevicePingReceived",
            "Fri Jan 14, 2022 12:18 PM EST"  "Encharge Controller",  "EnchargeSoCMaintenance : Set",
            "Fri Jan 14, 2022 11:30 AM EST"  "pcu channel 1",           "Grid Instability: Clear",
            "Fri Jan 14, 2022 10:49 AM EST"  "pcu ",                   "No Grid Profile: Clear",
            "Fri Jan 14, 2022 11:25 AM EST"  "pcu ",                   "No Grid Profile: Set",
            "Fri Jan 14, 2022 11:25 AM EST"  "pcu channel 1",           "Grid Instability: Set",
            "Fri Jan 14, 2022 11:28 AM EST"  "Encharge Controller",  "EnsembleDevicePingReceived",
            "Fri Jan 14, 2022 10:49 AM EST"  "pcu ",                   "No Grid Profile: Clear",
            "Fri Jan 14, 2022 10:49 AM EST"  "pcu channel 1",           "Grid Instability: Clear",
            "Fri Jan 14, 2022 10:48 AM EST"  "Encharge Controller",  "Device is excluded from the aggregate SOC: Clear",
            "Fri Jan 14, 2022 10:48 AM EST"  "envoy",                   "SOC below reserved level : Clear",
            "Fri Jan 14, 2022 10:47 AM EST"  "Encharge Controller",  "EnchargeOnGrid",
            "Fri Jan 14, 2022 10:47 AM EST"  "Encharge Micro",       "Vout over-voltage",
            "Fri Jan 14, 2022 10:47 AM EST"  "Encharge Micro",       "under-frequency",
            "Fri Jan 14, 2022 10:47 AM EST"  "Encharge Micro",           "Grid-Tied Black Start",
            "Fri Jan 14, 2022 10:47 AM EST"  "Encharge Micro",       "boot_reason_fw_expected_reset",
            "Fri Jan 14, 2022 10:47 AM EST"  "Encharge Micro",       "Power Generation turned off by command",
            "Fri Jan 14, 2022 10:47 AM EST"  "Encharge Micro",       "AC Frequency Out Of Range",
            "Fri Jan 14, 2022 10:47 AM EST"  "Encharge Micro",       "EnchargePCUStateIdle",
            "Fri Jan 14, 2022 10:47 AM EST"  "Encharge Micro",       "PLC Communication Established with E3",
            "Fri Jan 14, 2022 10:46 AM EST"  "Encharge Controller",  "EnchargeIQ8CommFailure : Set",
            "Fri Jan 14, 2022 10:46 AM EST"  "Encharge Micro",       "PLC Communication lost with E3",
            "Fri Jan 14, 2022 10:44 AM EST"  "pcu ",                   "No Grid Profile: Set",
            "Fri Jan 14, 2022 10:44 AM EST"  "pcu channel 1",           "Grid Instability: Set",
            "Fri Jan 14, 2022 10:17 AM EST"  "Encharge Controller",  "Device is excluded from the aggregate SOC: Set",
            "Fri Jan 14, 2022 10:17 AM EST"  "envoy",                   "SOC below reserved level : Set",
            "Fri Jan 14, 2022 10:17 AM EST"  "Encharge Micro",       "EnchargePCUStateThrottled",
            "Fri Jan 14, 2022 10:16 AM EST"  "Encharge Controller",  "EnchargeGridTied",
            "Fri Jan 14, 2022 10:16 AM EST"  "Encharge Micro",       "Multi Mode On-Grid",
            "Fri Jan 14, 2022 10:16 AM EST"  "Encharge Micro",       "EnchargePCUStateGridFault",
            "Fri Jan 14, 2022 10:16 AM EST"  "Encharge Micro",       "Grid-Tied",
            "Fri Jan 14, 2022 10:16 AM EST"  "Encharge Controller",  "EnchargeSoCMaintenance : Clear",
            "Fri Jan 14, 2022 10:15 AM EST"  "Encharge Controller",  "EnchargeIslanding",
            "Fri Jan 14, 2022 10:15 AM EST"  "Encharge Micro",       "Islanding"

I'll call Enphase support while they can still get the data and update this post if I learn anything useful.
 
Enphase diagnosed it to a loss of communication, which makes sense as the communication bars frequent drop into the orange:
Capture.jpg

He suggested taking the USB dongle out of the black case in the IQCombiner, but it didn't make much difference. Much to my surprise though, the box had two dongles, the expected green ZigBee dongle and a black one with no markings. I'll have to look into that.

Local API
Haven't tried it yet, but he also said that if you put the Enovy into AP mode (e.g., acts a wireless access point) then you can access it locally without the need for a remote token. So, I'll have to try that.

Non-Updated Micros
Since I was on a roll I ask him to look at why 17 of my microinverters hadn't been updating. He found an error status code indicating there was a "symbol" in an integer field. Supposedly fixed and should be updated in the next 24 hours. So, ?
 
Last edited:
Storm Guard
The NWS issued a storm warning here and Storm Guard correctly caught it and shifted to full backup.

Normally I leave the "charge batteries from grid" disabled and have been curious if Storm Guard would override it or not. Not to knock the NWS, but sometimes there is little warning so I was happy to see the status to the right.

Communications
I putzed around with the USB orientations for a while, seems leaving the green one on top of
the box they were in and the black on dangling gave the best results for me. Previously two had two bars (one of which was the one farthest away). Now only one has two bars, but its not the one farthest away. Also suspected one might be interfering with the other so tried it without, but the system seems to need both to work.
Grid charging, waiting for sunrise!1642334109541.png
The green one is an Xbee, I believe this is the spec sheet. It's programable, so I'm not sure I could just replace it with one that has an antenna.
Enphase recommends a range extender if you're over 50', I'm about 12' end to end, but the sequence is envoy-Enpower-Encharges.
Pretty sure the interference is the Enpower (I noticed the recommended layout is Enpower-Envoy-Encharges).

Wonder if I could put a ground reflector down to bounce the 2.4 GHz signal around the Enpower?
 
Made a DIY WindSurfer parabolic reflector for the USB, but the only place to put it without messing up the parabola was the top area which is directly inline with the Enpower's NFT and is the worst experimental location. The reflector isn't ideal either with the width of the circuit board antenna, but figured it couldn't hurt to try.

Sadly, no joy.
1642347039235.png
Now I'm wondering if I can run a type B USB cable extender through the existing conduit so the dongle is in the bottom of the Enpower cable area and a converter to plug the dongle into. Physically it's less than 2' (about 4' via cable), but in doing so the Enpower wouldn't between the dongle and the Encharges.
 
Saw this on the Enphase forums as a response from a mod (bold is my enphasis, not in the email):
  • In Q2 2022 we will be deploying the gateway software 7.x release to systems.
  • Gateway software 7.x provides the ability to home owners to do 2 levels of local monitoring
    1. In the absence of internet connectivity the app tries to reach the gateway directly via the local wifi router and displays a live streaming view of the current system status including power production and home consumption (and if applicable power export to grid)
    2. If the app is unable to connect to the gateway via the wifi router due to any reason the app provides direction to the homeowner to connect to the gateway’s wifi network directly and fetches the same live streaming view (described above) via the direct wifi connection
  • In the future we intend to extend these features to cover more information from the gateway
  • For advanced users who want to connect Enphase’s solution to home energy automation solutions – we do not plan to enhance the gateway software with MQTT clients in the near term however the APIs that have existed on the gateway continue to remain accessible with the caveat of requiring a security token (that currently has a 6 month expiry at maximum). We will be looking at expanding the expiry of the token based on the customer feedback received from the our users. We do not have a concrete timeline for this yet but the product team is in discussions with security architects and engineering on this feature now and we will have better visibility in a month or so.
 
Isn't software 7.x already out? unless they are referring to a global roll out.
I'm at "7.0.68", guess I need to wait until June when they release the "X" version ; -)
It sounds nice, but I'm not holding my breath as they don't seem to meet target dates very often and I'd like it wrapped up before June (at least before Hurricane season starts).

Need to get some "spare" time to figure out how to get a 6-month token, right now mine are 5 hours if I recollect correctly. With a 6-month token I could coast through most internet outages and not need it.
 
Last edited:
Have to love per-panel-data...
...top is a panel with some afternoon shade, bottom is a panel not in shade (only another couple of weeks before it should be shade free)

1642783043639.png
1642783082586.png
Wonder what it would look like with a maxim chip replacing the diode?
 
I'm at "7.0.69", guess I need to wait until June when they release the "X" version…..
I’m on 7.0.68 when I connect to Envoy, ITK prompts me to update to 7.0.69 but according to settings page, 7.0.69 is for systems with M series micro inverters.

1642787436612.jpeg
1642787363917.jpeg
 
Last edited:
... according to settings page, 7.0.69 is for systems with M series micro inverters.
Typo... Sorry about that... I so can't be trusted with numbers....
<software>D7.0.68</software>
 
No worries!, I have a ticket open for that issue. ITK is supposed “automatically” select the correct software to update to. And in my case, it’s prompting me to update to the wrong version.
 
No worries!, I have a ticket open for that issue.
Hmm, hoping that's for the ITK prompting for the wrong version rather than me with numbers :LOL:

And in my case, it’s prompting me to update to the wrong version.
Let us know what they say about that!
I still need to follow up on why those 17 microinverters of mine aren't updating.
 
There's a mention that the local API issue (i.e., need the internet to get a security token to access local devices, so local access is toast if the internet is down) will have a work-around by the end of January by putting the Envoy in the AP mode.

I wonder if it isn't time to put in an alternative monitoring system?


...Iotawatt seems to have gone under, their web site is still active, but it's no longer available on Amazon....

I went through this process with my system. Partly because the numbers I was getting from the envoy local API for battery charging/consumption didn't add to to what Enlighten said, or what separate CTs measured.

I'm running a pair of IotaWatts (according to their website they don't sell on Amazon, but their web store is still active so I don't think they've folded). I ran CTs from one of the IotaWatts into the Enpower and measure the current on the lines feeding each breaker in the Encharge, so I get a reading of grid consumption, solar production, battery consumption/charging, and overall house draw. I use the second Iotawatt (along with the leftover channels on the first) to monitor individual circuits in my main panel.

I also didn't like the sometimes 5 minute delay between a grid outage and a notification from Enlighten. So I got a little ESP-based device (M5Stack ATOM Lite) and wired it up to one of the load control relays in the Enpower. Now I get instant notifications when there's a grid outage, fully local, and can automate off of that with my Home Assistant setup.
 
...So I got a little ESP-based device (M5Stack ATOM Lite) and wired it up to one of the load control relays in the Enpower. Now I get instant notifications when there's a grid outage, fully local, and can automate off of that with my Home Assistant setup.
Sweet! Can you start a thread on the forums and talk about it? I bet I'm not the only one that would like to hear more!
There's a mention that the local API issue (i.e., need the internet to get a security token to access local devices, so local access is toast if the internet is down) will have a work-around by the end of January by putting the Envoy in the AP mode.
Heard it's out in beta! But rather than an Envoy update it seems to be a new cell phone app... will let you know more as I hear it.
 
Saw a thread on the Enphase forums where they're trying to put an inverter on the generator input, so far nothing that we haven't already talked about. Seems like a few are interested in doing it.
 
Release notes from Enphase on the 7.0.86 Envoy upgrade.
Tech Brief on using the new token (I'll have to look into it more, I skimmed it and saw at the bottom it would give a 6 month token).
 
...Tech Brief on using the new token (I'll have to look into it more, I skimmed it and saw at the bottom it would give a 6 month token).
For an uncommissioned token, it only gave me a 5-hour expiration. Not sure what goes in the "system" field for a commissioned token, although I bet the envoy field is the envoy serial number. Tried a few values like the site-id, but none worked. I'll try some other stuff and update this post if I can get anything to work.
1643990498253.png
 
Back
Top