Enphase Envoy-S “Data Scraping”.

If you are interested in other Enphase information the following other pages may also be of interest:
What is inside the Enphase Envoy-S (teardown)
Reverse Engineering the Enphase Installer Toolkit
Enphase Envoy-S Open Ports!

I’ve recently had to interface with an EnPhase Envoy Solar PV system. The annoying thing is the lack of documentation.

The API for the “cloud service” exists and is well documented but the API for the local device itself doesn’t seem to exist.

There is one tiny one page document that seems to suggest you can get some data from the device. The information gleaned from their example API ” http://device.ip.address.here/api/v1/production ” is poor.

 "wattHoursToday": 6641,
 "wattHoursSevenDays": 6641,
 "wattHoursLifetime": 6669,
 "wattsNow": 90

First.. it gives far LESS information than you can just retrieve from the main web page for the device on the LAN. Secondly the wattsNow field doesn’t seem to match the information displayed on the main page of the device. The wattsHoursSevenDays is also slightly off. Third.. it doesn’t even update regularly. You can’t have a system that detects dips in production due to cloud cover etc.

However. I did find some other sensible sources for information – and information that updates at an even more regular rate than the devices main website!

When you visit the site on the device running firmware D4.2.27 it makes the following requests:
This URL contains a lot of references to other json files that I need to research. See further down in this post for the other URLs exposed.
This json file contains the Database size / utilisation, date and time on the device, connection status and settings and update status.
Contains most useful information.. Production and (if fitted) consumption data!

Also contains some very useful information. Detailed status about the state of each micro-inverter. So far I’ve seen the following states:

– “envoy.global.ok”
– “envoy.cond_flags.pcu_ctrl.commandedreset”
– “envoy.cond_flags.pcu_ctrl.dc-pwr-low”
– “envoy.cond_flags.obs_strs.discovering”
– “envoy.cond_flags.obs_strs.failure”
The full conversion table on what these status messages mean in english is at the end of this article.

The full output of the page is as follows:


And thanks to Stuart Graves:
Which produces a continual stream of data for each phase. It does require authentication. It might be useful to read Stuart’s comment here.

All of this means you can make your own system that (in my case) refreshes generation and consumption status up-to-the-second!

A couple of notes: The Consumption metering / data seems to give strange low or even minus values if you fetch the json file more than roughly once per second. (Possibly because it works on a counter and the math goes wrong?)
During nighttime the Production metering goes into a minus value, for example -7 Watts. This is in fact the correct reading. The Envoy-S javascript filters out minus values and ensures a 0 is displayed. Cheeky!
The panel count on the main production.json file is the count of associated panels and not the currently generating panels. I’ve used the inventory.json file to count the number of panels “producing”, I refresh this information every 3 minutes instead of every second.

solar status

solar panel status

My next steps are to investigate the JavaScript and see what other pages are accessible. I also need to see if I can reverse engineer, find out or ask the installer for the “Installer Login” password (UPDATE: This has been done, see here!).

I also wish there was public documentation. No google searches for the status strings or other data I’ve found in the JSON files have returned any results to do with Enphase / SolarPV.

The backbone/application.js file exposes the following sub-files on the devices web server.
– /admin/lib/admin_dcc_display.json
– /ivp/tpm/capability
– /datatab/event_dt.rb?start=0&length=153
– /info.xml
– /ivp/meters
– /installer/pcu_comm_check
– /api/v1/production/inverters
– /prov
– /ivp/peb/newscan
– /installer/profiles/index.json
– /installer/profiles/details.json
– /installer/profiles/inverters_status.json
– /installer/profiles/set_profile.json
– /admin/lib/admin_pmu_display.json
– /ivp/peb/reportsettings
– /ivp/tpm/select
– /ivp/tpm/tpmstatus
– /ivp/tpm/parameters
– /admin/lib/dba.json
– /admin/lib/security_display.json
– /admin/lib/date_time_display.json?tzlist=1&locale=en
– /admin/lib/network_display.json
– /api/v1/production/inverters
– /admin/lib/wireless_display.json?site_info=0

Full status messages system strings to plain english:

        cond_flags: {
            acb_ctrl: {
                bmuhardwareerror: "BMU Hardware Error",
                bmuimageerror: "BMU Image Error",
                bmumaxcurrentwarning: "BMU Max Current Warning",
                bmusenseerror: "BMU Sense Error",
                cellmaxtemperror: "Cell Max Temperature Error",
                cellmaxtempwarning: "Cell Max Temperature Warning",
                cellmaxvoltageerror: "Cell Max Voltage Error",
                cellmaxvoltagewarning: "Cell Max Voltage Warning",
                cellmintemperror: "Cell Min Temperature Error",
                cellmintempwarning: "Cell Min Temperature Warning",
                cellminvoltageerror: "Cell Min Voltage Error",
                cellminvoltagewarning: "Cell Min Voltage Warning",
                cibcanerror: "CIB CAN Error",
                cibimageerror: "CIB Image Error",
                cibspierror: "CIB SPI Error"
            obs_strs: {
                discovering: "Discovering",
                failure: "Failure to report",
                flasherror: "Flash Error",
                notmonitored: "Not Monitored",
                ok: "Normal",
                plmerror: "PLM Error",
                secmodeenterfailure: "Secure mode enter failure",
                secmodeexitfailure: "Secure mode exit failure",
                sleeping: "Sleeping"
            pcu_chan: {
                acMonitorError: "AC Monitor Error",
                acfrequencyhigh: "AC Frequency High",
                acfrequencylow: "AC Frequency Low",
                acfrequencyoor: "AC Frequency Out Of Range",
                acvoltage_avg_hi: "AC Voltage Average High",
                acvoltagehigh: "AC Voltage High",
                acvoltagelow: "AC Voltage Low",
                acvoltageoor: "AC Voltage Out Of Range",
                acvoltageoosp1: "AC Voltage Out Of Range - Phase 1",
                acvoltageoosp2: "AC Voltage Out Of Range - Phase 2",
                acvoltageoosp3: "AC Voltage Out Of Range - Phase 3",
                agfpowerlimiting: "AGF Power Limiting",
                dcresistancelow: "DC Resistance Low",
                dcresistancelowpoweroff: "DC Resistance Low - Power Off",
                dcvoltagetoohigh: "DC Voltage Too High",
                dcvoltagetoolow: "DC Voltage Too Low",
                dfdt: "AC Frequency Changing too Fast",
                gfitripped: "GFI Tripped",
                gridgone: "Grid Gone",
                gridinstability: "Grid Instability",
                gridoffsethi: "Grid Offset Hi",
                gridoffsetlow: "Grid Offset Low",
                hardwareError: "Hardware Error",
                hardwareWarning: "Hardware Warning",
                highskiprate: "High Skip Rate",
                invalidinterval: "Invalid Interval",
                pwrgenoffbycmd: "Power generation off by command",
                skippedcycles: "Skipped Cycles",
                vreferror: "Voltage Ref Error"
            pcu_ctrl: {
                alertactive: "Alert Active",
                altpwrgenmode: "Alternate Power Generation Mode",
                altvfsettings: "Alternate Voltage and Frequency Settings",
                badflashimage: "Bad Flash Image",
                bricked: "No Grid Profile",
                commandedreset: "Commanded Reset",
                criticaltemperature: "Critical Temperature",
                "dc-pwr-low": "DC Power Too Low",
                iuplinkproblem: "IUP Link Problem",
                manutestmode: "In Manu Test Mode",
                nsync: "Grid Perturbation Unsynchronized",
                overtemperature: "Over Temperature",
                poweronreset: "Power On Reset",
                pwrgenoffbycmd: "Power generation off by command",
                runningonac: "Running on AC",
                tpmtest: "Transient Grid Profile",
                unexpectedreset: "Unexpected Reset",
                watchdogreset: "Watchdog Reset"
            rgm_chan: {
                check_meter: "Meter Error",
                power_quality: "Poor Power Quality"

Some more info about errors can be found on page 45 of the manual.
CommandedReset Recommended Action: No action is required; it will automatically resume normal operation momentarily. Description: The microinverter was reset, either following a successful software download or by user command.

DcPowerTooLow Recommended Action: This condition should correct itself. No action is required. Description: This condition may occur at sunrise or sunset, while the modules are covered with snow, or during extreme weather. This event indicates that sunlight levels are too low for effective production. Once sunlight levels increase, the microinverter resumes power production and this event message will clear.

DcVoltageTooLow Recommended Action: This is usually a normal condition during hours of low light and at dawn and dusk. No action is required. Description: The microinverter reports that DC input voltage from the PV module is too low. If this condition does not clear during hours of full day

PowerOnReset Description: The microinverter has powered on after having DC disconnected.

This entry was posted in Uncategorized. Bookmark the permalink.

165 Responses to Enphase Envoy-S “Data Scraping”.

  1. Pingback: Enphase Envoy-S Open Ports! | thecomputerperson

  2. RRM says:

    Bought the envoy-s 3 weeks ago and having the same difficulties in reading the local data.
    Found several scripts for running man-in-the-middle option or scripts for OpenHAB, but haven’t found the information you wrote.
    Unfortunately I have not that much information in the production.json, as you demonstrate.
    I bookmark this link and follow your progress.

  3. Thank you for commenting. What firmware version is your Envoy-s running ?
    Does it show that you have micro-inverters connected and “producing” on the envoy-s web interface?

  4. RRM says:

    @license Backbone-Envoy 4.2.43 (2016-05-20)

  5. RRM says:

    Although the Enphase site clearly demonstrates the exact number of producing inverters, the only output I get from production.json is:

  6. Is that all you see in the production.json? In my case there is a “type”:”eim”, section and also a “consumption” section.
    You should also see if /inventory.json contains anything interesting too.

    I’ve not yet managed to work out how to get individual inverter generation statistics.

    This evening my Envoy-S seems to have crashed or hung! This will be interesting to try and work out how to solve. It is responding to pings but the web interface is not returning any data.

    Update: In the end I just had to turn off the power to the Envoy-S and turn it back on again.

    Do you have an Envoy or an Envoy-S? The one I have is running firmware “D4.2.27 (b13066)” with a “Software Build Date” of “Jun 03, 2016 1:17 AM” which is strange. Your comment seems to show you have a _newer_ firmware but with a build date after the build date of my older firmware which doesn’t make much sense.
    Also the request to the javascript file that my firmware makes references 04.02.43.. even more weird.

  7. RRM says:

    It’s an Envoy-S (EU version). The inventory page contains output which is more or less identical. Unfortunately the production.json not.

  8. Not sure what to suggest :(

  9. Paul says:

    Thanks for the head start.

    I have > D4.4.x

    when prompted for username:password are envoy:nnnnnn where nnnnnn=last 6 digits of serial number

    This works for wifi and diagnostics from home but not other screens :(


    /production.json?details=2 etc (might be interval records?)

    to do

    The installer toolkit can see all inverter details without a password – but how? Time to sniff some traffic.

  10. Thanks for the info. I’ve yet to try the installer toolkit and prod the buttons on the Envoy. Will it work while the Envoy is on the normal network? (My one is hard wired / ethernet).

  11. Paul says:

    Yes and shows live inverter level data. It can connect to the envoy wirelrss ap but also works if device is on the same subnet. The app queries the presence of the envoy and it responds with its serial number which appears in the app. Touch this and your in.

    You can see this arp traffic using wireshark but not http from app ??? May be limitation of windows on promiscuous mode can see http access from browser np..

  12. I will give it a go and post an update. It will be at least a few weeks before I get a chance though. Too many things to do and not enough time.

  13. Paul says:

    also try


    Authentication of installer app process

    app uses api key (based on info? eg S/N) and pings. This was different to the web API key!
    there is some traffic back and forth inc some binary
    /api/collected?apikey= XXXXXXXXXXX&currentTime=xxxxxxx

    /prov returns unauthorised
    /prov again gets a response. It contains authorisation below

    GET /prov HTTP/1.1
    Accept: application/json
    Authorization: Digest username=”installer”, realm=”enphaseenergy.com”, nonce=”xxxxxxxxxxxxxxxx”, uri=”http://192.168.0.x/prov”, response=”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”, qop=auth, nc=00000001, cnonce=”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”
    Host: 192.168.0.x
    Connection: Keep-Alive
    Accept-Encoding: gzip
    User-Agent: okhttp/2.7.

    hmmmmm……. digest access auth

  14. The information you are seeking about the energy each inverter is generating appears to be returned at this URL:


    It requires authentication. In my case I was able to replay an authentication request that I had sniffed 13 hours earlier! So if you can sniff a successful authentication header from the installer toolkit request _to that specific page_ you may just be able to replay the authentication line from the header for eternity!

            "serialNumber": "REDACTED1",
            "lastReportDate": 1472215582,
            "lastReportWatts": 221,
            "maxReportWatts": 244
        }, {
            "serialNumber": "REDACTED2",
            "lastReportDate": 1472215588,
            "lastReportWatts": 226,
            "maxReportWatts ": 248

    While playing about I did manage to get /home.json to spit out:

        "alerts": [{
            "msg_key": "lwui.home.warnings.cross_domain_traffic"


  15. RRM says:

    Unfortunately the amazon link of Paul isn’t working at the moment.
    I also tried to get access through the installer toolkit, but with the lack of passwords, it wasn’t successful.

    /api/v1/production/inverters requires name and password. I get exact the same data of my 20 inverters by filling in envoy and the last 6 numbers of the serial number.

  16. I’ve fixed paul’s link – it was missing the https on the http:// bit.
    Installer toolkit just let me right on on my system without the need to authenticate. Yet if I visit the same URLs on the browser it requires authentication.
    As Paul noted, the app generates the authentication details somehow.
    If you can sniff the details it seems the final authentication http header can be reused for eternity. It seems the envoy doesn’t check for expiry of the nonce.

    Sadly whatever details are generated are specific to your unit so I can’t share my http request with you and have you authenticate against your Envoy with it :(

  17. Paul says:

    Ypu shouldnt need user .. pass with the installer toolkit.

    It finds the envoy on the local lan or you can use the envoy ap lan.

    The s/n will appear when its found. Just tap on this.

  18. The Installer Toolkit application is a Xamarin (Mono) .net cross platform app. This means, when extracted, you get a load of (as far as I’m aware) windows compatible .dll files.
    The authentication is likely handled by “assemblies\Enphase.InstallerToolkit.dll”.

    Next step – I’ve got to learn how to reverse engineer .net dll files :< This might be beyond my abilities.

  19. Pingback: Reverse Engineering the Enphase Installer Toolkit | thecomputerperson

  20. RRM says:

    Succeeded in getting access through the installer kit.
    Tried to sniff the procedure with wireshark, which produced some files with http 1.1 or application/json information in it.
    Tried to search for keys/passwords, but my lack of knowledge of wireshark makes it a slow process. I’ll keep on trying with your suggestions.

  21. Dave says:

    Anyone know how to pass the username/password to the envoy-s api via http post? I’m looking to grab the panel level info, and I can do so via:
    ( is the wifi IP of my envoy-s)

    But it needs a username of ‘envoy’ and password of the last 6 digits of the serial number, which it pops up and requests. I’ve tried:
    (where 123456 is the last 6 digits of my envoy-s)
    which returns:
    “status”: 404,
    “error”: “”,
    “info”: “Resource /api/v1/production/inverters&user=envoy&password=123456 not found”,
    “moreInfo”: “”

    I’ve also tried the same thing but instead of & I used ?, and it popped up with the password prompt as if I wasn’t using them.

    Anyone figured this one out yet?

  22. What code are you using to scrape the data? Normally you just pass it extra parameters such as..


    (Very rough example, not working code!).

  23. Dave says:

    I was using a post–just pasting into the web page.
    I believe that using a format similar to an ftp site works. For instance:

    I need to test it on a separate computer.

    Once I have that working, I’ll figure out what language I want to learn to do this…right now I know perl, but I think I should probably learn python.

    Thanks for the reply…good to know there is a way to do it, and that I’m not barking up a dead tree!

  24. I’d approach it the other way around. Mash out the code and get it to authenticate and dump the resulting page.

    I’ve not got any experience in Perl but as far as I can see LWP takes authentication options:

     use LWP 5.64;
      my $browser = LWP::UserAgent->new;
        'usernamehere' => 'passwordhere'
    my $response = $browser->get($url);

    Perl looks pretty horrible from the code I’ve just seen, I expect Python is a far better bet :)

  25. wharwood says:

    I’ve been working to programmatically authenticate the inverter production page via Matlab. The built in authentication options don’t work and the method suggested above of using http://user:pass@xxx doesn’t work either.

  26. Do you have an Envoy or Envoy-S? My Envoy-S doesn’t need authentication for /inventory.json or /production.json so I can’t test against my own system and help you with code :(

  27. wharwood says:

    I have an Envoy-S. I too don’t need authentication for /production but the real data I want is in /production/inverters. That is password protected.

  28. Ah yes, that one is password protected but I’ve not yet figured out how to calculate the password from the envoy serial number. The older Envoy firmware was “installer” and the last 6 digits of the serial number (as far as I remember) but the newer firmware or Envoy-S seems to have a dynamically generated password.
    For more information on my password generation probing see:

  29. wharwood says:

    I must have an older unit then because user: envoy pass: XXXXXX (last 6 of serial) works for me.

  30. Doesn’t work for me :( I am on Software Version D4.2.27 (b13066)

  31. Dave says:

    I was able to get to this page by using the ‘envoy’ username and last 6 digits of the serial number. Try:
    (where you substitute the last 6 of your serial and your IP number)

    The only odd thing is that it pops up with a prompt that you have to click yes to, not sure how that’ll work out programatically.

    I haven’t had time to look into this, since I posted last.

  32. That one works for me with the envoy/XXXXXX details!

        "serialNumber": "REMOVED",
        "lastReportDate": 1475688141,
        "lastReportWatts": 0,
        "maxReportWatts": 259
  33. wharwood says:

    Matlab returns 401 on Dave’s link for me. Glad you that login info worked for you. I’m running software version R4.2.33 (b68db1)

  34. I can download Matlab and test here. I’ve never used it before – what are the lines of code you have that make the request ?

  35. wharwood says:

    It all revolves around the built in function “webread”. Documentation is here: https://www.mathworks.com/help/matlab/ref/webread.html Truthfully, Matlab is probably not the best language for this. It’s just the one they taught me in school. It’s also expensive.

  36. Dave says:

    My system has build D4.2.27 (b13066), for reference

  37. wharwood says:

    It interesting that we have what appears to be very different firmware builds. I have the Envoy-S Metered (ENV-S-AM1-120). I would guess you both do not have the metered version.

  38. I have a consumption and production clamp meter that came with the Envoy-S and the data read out shows on the Envoy page.

  39. It looks like matlab is just sending “Basic” authentication in a single request and not triggering a Digest authentication (First a non-authenticated request needs to be made in which the envoy provides a salt / nonce which matlab [or other software] then hashes the authentication details with to produce a unique authentication string before making the second authenticated request with this string).

    The following might help but I can’t actually see any code in that example about authentication even though it claims it tackles Digest auth.

    Wireshark is a great tool – Install it and use the filter “host” where is the IP of your envoy. Make a request / run your matlab script and you can then right click on a request and go to Follow –> TCP Stream to see if matlab sent a Basic or Digest authentication line.

  40. wharwood says:

    Just had a breakthrough. First, I took my own advice and got away from Matlab. I grabbed Visual Studio and started writing a console app in C#. The following code grabs the json file:

    var envoy = new WebClient { Credentials = new NetworkCredential(user, pw) };
    var response = envoy.DownloadString(url);

  41. jam says:

    It was only a matter of time before someone blogged about this stuff! I currently have OpenHAB polling my envoy-s production.json and logging production and consumption data, and also activating heating etc based on available power! :) The APIs they provide are USELESS….!

    I’ve also had my envoy-s metered crash twice now since I began polling it every few seconds or so. It required a hard reset. I have no evidence of course that it wouldn’t have crashed anyway, but it is annoying. Has anyone else noticed this, or has anyone had their envoy-s crash when not polling it? (you get an email from enlighten saying it is not reporting)

  42. I’ve certainly had it crash twice. Both times I thought it was due to my polling and it seemed to crash in an extended amount of time when I changed the polling to 2 seconds instead of 1 second etc.. but I don’t recall changing my polling code since and I’ve not had it crash (yet).
    If you poll the Envoy consumption data more than once per second you get totally screwed up values (minus values and the 7 day consumption total starts counting down!).

  43. Having said that – it crashed again today. Lots of other random services still respond but port 80 doesn’t ever load and the Envoy stops reporting to the cloud service. Boring. Wish I could reboot it remotely :<

  44. Jam: I’ve been testing. I thought maybe the crash was triggered by either.
    1) Requests being sent too quickly to the Envoy
    2) A hard-limit on the number of requests that the envoy can handle before it runs out of ram, temp filesystem space or something
    3) Race condition

    The number of requests I seemed to send before it crashed was around 604,800 however.. I’ve been soak testing it with a script that has been hammering the Envoy with over 100 requests per minute and I’ve reached well over 800,000 requests and it still hasn’t crashed.
    There goes my theory.

    Which files are you fetching every second? I was testing with /production.json
    I wish I had SSH or some other debug access to the device to either restart it remotely or, even better, figure out what is causing the lock up.

  45. jam says:

    Hi tcp, I really appreciate you hammering your system in the name of science!

    I am only fetching /production.json, once every 10 seconds on a little wifi display I built to have in the kitchen, and once every 30s on OpenHAB.

    I really think getting the installer password used by the installer app could possibly open up some options for getting further access to the box.

    I’m surprised they don’t have some kind of watchdog running on it to restart the service – it does stop it uploading to enlighten, and does stop logging data when it “crashes” so it’s kind of important….

  46. emdeex says:

    Some good info here, thanks. I’m using Splunk to fetch and display the data from my Envoy-S … there’s a short forum post here: https://answers.splunk.com/answers/390296/how-to-get-splunk-to-fetch-json-data-from-enphase.html#comment-451860

  47. Over the last week my Envoy updated itself from “Software Version D4.2.27 (b13066)” to “Software Version D4.4.89 (5e7c1d)”.
    I now find that the web interface (html and everything) takes many minutes to load up and the json files take a similar amount of time. Sometimes it takes 1.4 minutes, sometimes it takes 3.5 minutes, sometimes it takes 5 minutes to just return one of the json pages.

    The web interface now mentions batteries which I believe have recently been launched as an Enphase product in several countries.

    Anyone else had this firmware? Anyone else having page load delay problems?

  48. jam says:

    Same firmware has upgraded itself here – no delay problem. Also haven’t had any crashes for ages!

  49. Thanks.. I will monitor and see what is going on. Seems to be ok for a bit and then goes weird, possibly when I request inventory.json and production.json in very quick succession.

  50. Right. Not sure what has changed in the firmware / envoy back end but I’ve figured out what is going on. My code is quite aggressive: It checks for /production.json every second _but_ has a 1 second no response timeout. This is normally ok but..

    Also, every 3 minutes, I check for /inventory.json. It seems that sometimes /inventory.json is taking more than 1 second to respond with data (sometimes takes 600ms, sometimes takes up to 6 seconds) and is “blocking” so other requests get queued / delayed.

    My code then, at the next second, requests /production.json but as /inventory.json is still processing – it times out, then requests it again a second later.
    It seems that prior requests get queued still even though the TCP connection has been ended [RST, ACK (forcefully ended)] with the timeout. This ends up running away and the envoy appears to have locked up. If you stop _all_ requests and leave it for about 10-20 minutes, it recovers.

    You can reproduce this problem by loading up one of the .json files in your browser and constantly spamming the Refresh -> Stop -> Refresh -> Stop button (without waiting for the page to load each time). After about 20 or so goes at that you should see that your final request and ones shortly after take quite a long time to be responded to by the envoy.

    Something has changed with the way the envoy handles requests or how quickly it can respond to requests.. compounded by my aggressive code.
    I guess I now need to code, my side, failure detection and make my code “back off” so that the envoy can recover or fulfil all pending requests (double the delay until the next request, then double it again if it fails a second, third, fourth (etc.) time).

    I hope that the new firmware, with this quirk, does at least fix the total lockups that required a power cycle to recover from :D

  51. No crash or lockup since the firmware update!
    Yay. I no longer have to power cycle the envoy weekly.

  52. Ken Clifton says:

    Thanks for your work on this! I wish that I had an Envoy-S. My two older Envoys don’t have many of the items mentioned. In case you are interested, I created a Python script to archive the event log on the older Envoy version — it may work with your Envoy-S… Short link: https://goo.gl/kWHcBJ

  53. Cam says:

    I can get a fair bit of data following you instructions including panel production, but what program did you use to make your own system and refresh the data?

  54. I’m using asp classic and built in logic to cache the response for X seconds before making another request.
    This means I can have multiple displays or systems (automatic space heater that uses up spare energy instead of exporting) polling my ASP page multiple times per second! but my ASP only “bothers” the Envoy-S every 3 seconds and returns that cached result until it expires.
    See my previous comments (above) about how the Envoy really doesn’t cope well with lots of requests in quick succession.

    ASP Classic was my choice because I knew I could develop something rapidly. Anything else would also work fine, PHP, Perl, Python or even a simple bash script using wget and grep.

  55. Cam says:

    Thanks for the quick response. Any chance you would be able to share the script/programming you wrote for your own system which I could then adapt. I’m not great with writing my own. Also I would probably only request every 10 seconds so I don’t upset my envoy.
    Thanks again.

  56. Difficult to share without knowing what it is going to be used for. My code spits out javascript which probably won’t be suitable for whatever you want to use it for. And my code is ASP classic which requires an IIS / Windows server.

  57. Cam says:

    No worries. I’ll work on it from another angle.

  58. Dave says:

    Ken’s python script does not work with the current envoy-s firmware. It gets both an unauthorized error, and it looks like the envoy login doesn’t allow access to the event log, at least at that location, even with the envoy:last6ofsn login.

  59. Ken Clifton says:

    Thanks for checking that Dave. You can try downloading the event log directly to see if the location is correct — it is at — http://%5Benvoy ip address]//datatab/event_dt.rb

    I wish that I had an Envoy-S to test with. Does anyone know if the Envoy-S will work with the older M190, M215 and M250 series inverters?
    The fact that it exposes the production information makes it very attractive to me…

  60. Compatible Micro-inverters.. a convenient table is here:
    Looks like the M215 and M250, yes.. M190 isn’t even mentioned.

    On the Envoy-S you need to issue the event log request with start= and length= variables for it to return information. For example /datatab/event_dt.rb?start=0&length=153

    I’m still stuck on the reverse engineering of the password hashing function :( Shame.

    Off-topic: I can find at least 688 Envoys just “open on the internet”.. I do hope they’ve been designed securely! Otherwise another potential IoT disaster.

  61. Ken Clifton says:

    Yes, the whole IoT thing is a disaster waiting to happen. My two Envoy(s) are behind multiple firewalls.
    Since I don’t have the “S” model, I can’t do any testing. My Python script is fully commented so you can see where the request to the event_dt.rb has a whole bunch of parameters being passed. I do understand about the start and length on your “S” version.
    I wish you luck with the password hashing. It is a shame they don’t expose the data with a password known to the user.

  62. Ken Clifton says:

    BTW, to get the parameters I did the to get the network monitor in Firefox, then copied the exact request made by the Eventlog page on the Envoy. I noted in the script the parameters that I have changed with effect — some it seems to ignore.

  63. Ken Clifton says:

    The keys were stripped out: control and shift and q

  64. Matthew says:

    Guys if I want to pass my user id envoy and password – last six digits of the Envoy-s to read the individual inverter / panel data – does anyone know the format of how I need to pass these parameters? My code has issues passing these credentials.

    If I key the local device URL into Chrome and enter envoy and 012345 when it prompts for user id and password it accepts this and shows all the relevant details:

    “serialNumber”: “121440006251”,
    “lastReportDate”: 1484971459,
    “devType”: 1,
    “lastReportWatts”: 172,
    “maxReportWatts”: 255
    “serialNumber”: “121440009849”,
    “lastReportDate”: 1484971423,
    “devType”: 1,
    “lastReportWatts”: 220,
    “maxReportWatts”: 251


    My html file is executing the following JSON code

    $.getJSON(“http://envoy:012345@”, function(data) { …}

    BTW – is the code for the screen on the first page shareable? Love to see how youo did what you have!

    Many thanks,


  65. It looks like getJSON might be jquery? If so it seems that jQuery can’t do Digest authentication and will likely just be sending Basic authentication headers.

    This looks like an addon for jquery that might help:
    (I’m no expert in jquery so the above might be wrong or out of date).

    Ref – the code from the first screen shot.. it is in ASP Classic which pretty much nobody uses (or should be using) so probably not worth sharing.

  66. Dave says:


    This guy hangs out with people who attempt to factor RSA keys. It appears that early Envoys all use the same SSH RSA hostkey from Debian – and it isn’t prime!

  67. Interesting article you link to – doesn’t seem to be the specific one about the keys used but does have some interesting stuff in it.
    Seems that they are looking at a tsv file of some energy generated (doesn’t say source or what other info the file contains) but have deduced that there isn’t much energy being produced vs. the energy to manufacture solar generation kit.

    A bit amazed by their findings / calculation. The stuff on my roof is certainly more than covering my daily energy usage and I’m exporting more than I use. I’m not sure on the energy cost to produce the equipment in the first place but I can’t believe the guys claim that they are not economical. “To recap : “solar power” costs more in energy alone to merely produce the hardware (we’re not counting the minerals, just the energy to assemble all the stuff together) than it will ever output over its lifetime.”
    “For every Watt of energy an installed solar panel ever produces, it will have consumed about three Watts of energy. You are actually saving two Watts by not putting one in. ”

    I really don’t believe that but I’ve yet to investigate their calculations in depth.

  68. Dave says:

    Yeah if they are correct with their calculations then whoever installed that solar array did a poor job. My array is covering my energy use as well, although admittedly it will still take quite awhile to pay off. I’m using my excess electricity to mine cryptocurrencies which helps.

    The more interesting finding to me is the link to the SSH RSA key. I figured out how to extract and convert the key on my Enovy-S and it is not the same as what these guys claim to have found. So it appears this is a problem with old Envoys, not new ones.

  69. Jason says:

    Hi jam… you said earlier:

    I currently have OpenHAB polling my envoy-s production.json and logging production and consumption data, and also activating heating etc based on available power! :)

    Can you expand on this please? Their doco is confusing me — I don’t see anywhere where it can take input data and graph (or do something) with it?

  70. jam says:

    That’s right, you won’t find anything specific in the docs about it. But all the information is actually there – you want to poll your envoy, not use the enphase binding.

    So I just use the http binding to poll the envoy-s and parse the json returned. You parse out the solar production and consumption values into an openhab “Number” variable. Then just switch on the rrd4j “persistence” for those Number variables.

    Then generate a chart from the rrd4j. Or action what you will based on the current power produced using the rules engine.


  71. Jason says:

    Ta for the info. Yeah, I don’t trust the Enphase cloud API… I have suspicions that they’re munging data.

    I’m putting together some Python, using SQLAlchemy to pull all data from the Envoy, storing it locally… and will probably end up graphing it using plot.ly and Flask as the frontend.

    I’m stoked as well, because production/inverters is working for me with creds as suggested above ;) so that’ll be interesting to see which panels do what, at which times of day.

  72. Ken Clifton says:

    Thanks for all the good work here! I upgraded one of my Envoy(s) to the “s” model. That has allowed me to develop some Python for it. I created a repository for the Inventory script on GitHub today. A post with that link and a screenshot can be seen at: http://www.kenclifton.com/wordpress/2017/06/envoy-s-local-solar-inverter-inventory-and-status/

    As well as running on standard Python version 3, it also works in the Pythonista App on iOS.

  73. Matthew says:

    I have found the following code gets a lot further when I execute $.getJSON(“”, function(data) {

    Now that it seems to pass authentication I am encountering network error

    SCRIPT7002: XMLHttpRequest: Network Error 0x2efd, Could not complete the operation due to error 00002efd.

    I found this on both firefox and edge – on Chrome I recieve

    ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘’ is therefore not allowed access. The response had HTTP status code 401.

  74. Access-Control-Allow-Origin is going to scupper you there. The envoy must be replying with that in the HTTP headers which then tells the browser to not allow inclusion of that data into your json / javascript.
    The only way around it is to get the envoy not to provide that header.

    If I were having this problem I’d build a simple php or aspx script to fetch the /inverters data and then spit it out again without the Access-Control-Allow-Origin header!.. or maybe make a scheduled task or crontab to wget the data into a file and then host that file on your own web server.

  75. Matthew says:

    Well I made a lot more progress by changing @.getJSON to $.getScript – it invokes the request user name and password and when supplied it does return success – and I can see the data returned to it in debug mode, the only issue I have is I log all the variable to console.log and somehow the data variable itself comes back as undefined. This may be becuase $.getScript is a ayschronous call – and by the time I log the headers, call success etc the data itself hasn’t yet been returned. So it seems a less challenging problem to tackle. In debug mode I can see a Get call is issued – all the headers and Params look correct and the Call stack shows 31 individual inverters data.

    My logic is:


    table td.box {
    width: 250px;
    border-left: 1px solid #000000;
    border-right: 1px solid #000000;
    table td.box div {
    background-color: #0000FF;

    Solar Test

    $(function() {
    var url = “”;

    $.getScript ( url, function( data, textStatus, jqxhr ) {

    console.log( textStatus );
    console.log( jqxhr.status );
    console.log( data );
    console.log(“Load was performed”);

    var table = $(“Serial NumberLast Report DateStatusLastMax”).addClass(“table table-striped”);
    var totalLastReportWatts = 0;
    var totalMaxReportWatts = 0;

    $.each( data, function(index, item) {
    console.log( index );
    totalLastReportWatts += item.lastReportWatts;
    totalMaxReportWatts += item.maxReportWatts;

    var percent = ((item.lastReportWatts / item.maxReportWatts) * 100);
    var row = $(“”).html(“” + item.serialNumber + “” + new Date(item.lastReportDate) + ” ” + item.lastReportWatts + “” + item.maxReportWatts+ “”);

    var totalsRow = $(“”).html(“” + totalLastReportWatts + “” + totalMaxReportWatts + “”);

    Any idea how to get the data to be actually linked to the data field so I can parse it correctly?

  76. Matthew says:

    I also tried re-structuring my code to execute the GetScript first – which toggles the Enphase Envoy-s unit to ask for authentication via a pop up window in the browser running the html file. Once these details are passed the call progresses – but with the returned data being classed as undefined and failing the string parsing.

    But I then added a second GetJSON call immediately after the GetScript call to see if the Authentication details created for the Get Script call where inherited by the subsequent GetJSON call – unfortunately they are not and a CORS error is recorded, buts its a 401 error – failed authentication.

    In firefox Debugger – it appears the GetScript call is a JS call type – which fails with a 401 – but the credentials when entered into the pop up Window that appears then immediately causes the Envoy to return the correct data with a 200 status code.

    When the GetJSON call is launched it is a JS XHR request and it doesn’t trigger the credentials logic the GetScript call does, so it doesn’t get the required authentication token / credentials and it simply fails with a 401 status.

    * * * * * *

    I wonder if there is any way to have the GetJSON call trigger the Envoy to ask / launch the credentials pop up window the GetScript did – so it too could pass authentication?

  77. Matthew says:

    Hey Jam, if you have got it all working could you please share your code somewhere!

  78. jam says:

    Hey there,

    Well, I don’t like reinventing the wheel so as I said I used OpenHAB, and the http binding included.

    So in the openhab.cfg I set the http binding timeout to 3000ms:
    ############################### HTTP Binding ##########################################
    # timeout in milliseconds for the http requests (optional, defaults to 5000)

    Then in the OpenHAB “Items” configuration file I make 3 items, one to hold the entire json from the envoy+s, and then one for production and one for consumption:

    String Enphase_JSON “JSON data from Enphase Envoy-S” {http=”<[*))]"}
    Number Power_Consumption (Solar2)
    Number Solar_Production (Solar2)

    Then I make a rule in the OpenHAB “rules” config file to parse the JSON when it is updated in the Enphase_JSON String item, writing the results to the Power_Consumption and Solar_Production items:

    rule “Init”
    Item Enphase_JSON changed
    var String data = Enphase_JSON.state.toString
    var Number production_value = transform(“JSONPATH”,”$.production[?(@.type==eim)][0].wNow”, data)
    var Number consumption_value = transform(“JSONPATH”,”$.consumption[?(@.type==eim)][0].wNow”, data)
    postUpdate(Solar_Production, production_value as String)
    postUpdate(Power_Consumption, consumption_value as String)

    and _that’s it_. You can then turn on persistence for the two Items to store the production and consumption values over time, graph them, write other rules to switch other openHAB items on and off based on the values, like power switches, etc etc etc… It just works.

    The downside is you have to learn OpenHAB, which might be worth it anyway IMHO! :)

  79. Matthew says:

    Thanks Jam – something new to learn! So are you parsing per panel / micro power – and if so did you use OpenHAB – to pass the Authenctication paramaters envoy + last 6 digits of the envoy to in your case

    Many thanks – given me something new to research!

  80. jam says:

    Nah, I didn’t bother with the per panel data. I didn’t need it for my automation needs, although it would be interesting to graph my split array separately (9 panels NE, 9 panels NW). In reality though it actually doesn’t vary that much!!

    I’m anyway lucky enough to have access to enlighten manager to scratch the per panel itch, and besides if you’re too OCD, per panel data can drive you nuts. 1W difference here, 2W there.. it doesn’t really matter to be honest.

  81. I did python script which scrapes the envoy.local APi’s and combines from different json responses one json (the data I wanted) I use this to store to my db and show it on my magic mirror. Codes are free to use in case it helps somebody: https://github.com/teemuhirsikangas/magicaespeculo/blob/master/scripts/send_envoy.py

  82. Bart Klumpers says:

    I have an Envoy-S and a couple of Enphase Batteries. I am retrieving the data every 2 seconds to display in an C# program and that works fine. However, the battery data reported by the Envoy-S changes only once every 5 minutes; any suggestions how I can get better LIVE data? Some documentation suggested that the batteries need internet connectivity, but sofar I have not been able to find which (WI-FI) IP address it uses, hoping that I could listen in on the conversation. I am not convinced the battery uses the internet.

  83. Matthew says:

    Someone informed me that the Envoy-s uses digest authentication – which isn’t avaliable in json directly – but you can code a AJAX call for digest authentication – which succeeds in triggering the same authentication logic that a browser encounters when requesting the inverter data. So I am a big step closer – in debug mode I can see the authentication passed and correct data returned – but the returned data isn’t being linked into the call – so I can’t parse it – not sure where it is going!

    The AJAX auth code is simply:

    $(‘#importButton’).click( function() {

    var commCareFormURL = $(‘#url’).val();
    var commCarePassword = $(‘#password’).val();
    var commCareUserID = $(‘#user’).val();

    type: “GET”,
    withCredentials: true
    dataType: “jsonp”,
    crossDomain: true,
    url: commCareFormURL,
    async: false,
    headers: {
    ‘Authorization’: “Basic ” + btoa(commCareUserID + “:” + commCarePassword)
    success: function (jsonData) {
    console.log(“AJAX Get Succeeded”);
    var table = $(“Serial NumberLast Report DateStatusLastMax”).addClass(“table table-striped”);
    var totalLastReportWatts = 0;
    var totalMaxReportWatts = 0;
    $.each( jsonData, function(index, item) {
    console.log( index );
    totalLastReportWatts += item.lastReportWatts;
    totalMaxReportWatts += item.maxReportWatts;

    var percent = ((item.lastReportWatts / item.maxReportWatts) * 100);
    var row = $(“”).html(“” + item.serialNumber + “” + new Date(item.lastReportDate) + ” ” + item.lastReportWatts + “” + item.maxReportWatts+ “”);
    var totalsRow = $(“”).html(“” + totalLastReportWatts + “” + totalMaxReportWatts + “”);
    error: function (request, textStatus, errorThrown) {
    console.log(“AJAX Get failed”);


    Trouble is although the authentication is launched – neither the success: nor the fail path seems to be triggered!

  84. danps says:

    hi clever people!
    i’m not a coder, so have no idea the feasibility of what i’m about to ask.
    not sure if you’ve seen it, but Mozilla are heading down the path of creating a standards-based approach to iot, or “web-of-things” as they’re calling it. the just released the first version of an open extensible gateway – https://iot.mozilla.org/
    I’ve been having a bit of a play, and was thinking it would be nice to include info from my enphase gateway there as a “thing”
    As the webthings API is published (https://iot.mozilla.org/wot/) looks very much like it’s based on JSON, as is the “production.json” file on the enphase gateway, how hard would it be to massage the data from enphase into an “adapter” for the mozilla gateway?
    Again, i have no idea the complexity of what i’m asking to apologies if it’s a crazy question!

  85. Many thanks: /production.json is the business!



  86. Pingback: What is inside the Enphase Envoy-S (teardown) | thecomputerperson

  87. Hi Damon and everyone else.
    You might find this page of interest.. I managed to dismantle and photograph the insides of the Envoy-S Metered:


  88. \o/

    Mmmm, electronic-y guts with magic smoke still in, mmmm!



  89. BTW, I just read a comment elsewhere that Enphase originally intended to bring out a battery version with 2 inverters so twice the charge/discharge power. Presumably at the cost of some battery life, but that could be worthwhile, especially given a mix of types in the system to balance the wear.

    Do you know any more about that?



  90. Not a clue. I’ve not researched battery storage and I’ve only ever seen an Enphase Micro PV system twinned with a Tesla battery system.

  91. Matthew says:

    Damon – that is correct – but it never launched. The great news from their investors tech conference in the IQ8 a 440W inverter will be in both their batteries Encharge and roof inverters. Better still the inverter is grid agnostic (islands from a fault gird – google Enphase Ensemble) and the battery is now a 3.3 kWh modular unit with 3 x IQ8 inverters giving a usable 1.3 kW sustained output. The unit will also be sold as a 3 x 3 = 10 kWh unit with a 3.8 kW sustained output. Launch is in H1 2019 – but I read they are targeting Africa and India first. – Matthew

  92. Matthew says:

    Ah – tried it on my mobile – works fine thank you!

  93. Bingo.. the app does need to be run on a mobile (or possibly “Bluestacks” android emulator for windows) as it contains the Enphase ARM based file that won’t run on Windows / “x86” computers.

  94. Matthew says:

    I am back on my quest to try an get an Excel sheet to poll the Enphase Envoy-s on my network using a web IP access call to the old (classic=1) Production page. So I am punching out to – but even in my browser trying to select the Production page invokes a user id / password challenge that I can’t get past – even with the installer id.

    When querying the local envoy – using the classic=1 flag to get the old interface on your web browser – does anyone know the password to access the Production page?

  95. Just use the json? ?
    And what installer password are you trying to use? On newer Envoy-s’s it isn’t likely to be the last digits of the serial number. It is a unique hashed value that you would need to generate using the app on this page:

  96. Matthew says:

    Trouble is – Excel hates trying to ingest json and it used to work beautifully from Excel when it pointed you to an already coded html file. That is the so annoying factor. The page is already there but some moron password protected i and refuses to give out the password!

  97. Matthew says:

    Interestingly today – Enphase Australia tried to recreate this behaviour on their test rig and it didn’t ask for authentication. I asked and two people on the Australian Enphase User group quickly tested it and confirmed the issue occurs for them. Do folk in America and overseas see the same behaviour I wonder? Wonder if this is how the anomaly slipped through – maybe it doesn’t occur in Enphases test rigs?

  98. Matthew says:

    Wow that is impressive! I only have Excel2013 – which acts very differently when you try and get production.json – asks if you want to open the file – then says unsupported file type and dies. Yours I see opens Power Query – that video was great. I may see about getting an upgrade to office 365 (which we use at work). If it can import .json and format it easily I could side step a lot of problems. Is the query tool you used in that video native to Excel office 365 – on another add in one must buy? Many thanks!

  99. Native. Office 2016 would also do (if you would rather buy than rent / subscribe).

  100. Matthew says:

    So I just downloaded Power Query and used it in Excel 2013 – and it worked very similar to your demo. Many thanks mate! Two questions for you: Can you run timed queries – i.e. say every five minute run this query using PowerQuery or do you sue Data -> Connections and set refresh to say 5 minutes? Secondly can you use this to get api/v1/production/inverters data – when I try to pass user id envoy and password last six digits of my envoy – it fails – I presume it is doing simple authentication and the envoy-s may wish digest authentication? Best regards

  101. Looks like it is in the connection properties.
    I’m no expert in excel :) Just googled for that one.

  102. Matthew says:

    So this is starting to give me in Excel what I – the only data morsel I wish to read if possible is total daily grid consumption.

    I can’t seem to find where or if the local Envoy-s hold this? So far now I can easily read in 1 minute intervals – current production, consumption, net power (import/export), Total watts produced today, Daily total Consumption (Grid import + Solar self consumption).

    I really want in real time grid daily consumption. So I either need this filed or need to know Total Solar Produced daily- less total export daily = Total daily self consumed to figure out total daily grid import, or read directly total daily grid consumed. Anyone know if this is provided anywhere? Thanks

  103. Matthew says:

    So Enphase told me to access the original view classic=1 of the new envoy-s the credentials are enphase and a password that looks like a Windows install key. Trying to find out if that is a generic key I can share with all or only the key to my device. Works well – also works for the api/v1/production/inverters.

    Anyone know how in Excel 2013 with Power Query I execute a Web call and tell it the web access setting to use – I can’t figure out how to bring up the page that asks what time of web call and what the user id and password is!

  104. Matthew says:

    I still haven’t found out two things.

    The first – how or if the envoy-s stores net export or net grid import – there is a data element for it – but at least on my machine it is always zerol! Using production.json noting watt hours in net consumption is always zero:

    type “eim”
    activeCount 1
    measurementType “net-consumption”
    readingTime 1537632361
    wNow 785.029
    whLifetime 16673757.994
    varhLeadLifetime 17297867.514
    varhLagLifetime 182755.155
    vahLifetime 40903738.501
    rmsCurrent 5.712
    rmsVoltage 243.594
    reactPwr -1066.64
    apprntPwr 1391.662
    pwrFactor 0.57
    whToday 0
    whLastSevenDays 0
    vahToday 0
    varhLeadToday 0
    varhLagToday 0

    The second is to determine if it is possible for PowerQuery to pass authorisation credentials to the production/inverters URL. I have tried specifying an advanced call to the URL and adding header Authorisation with data “Basic ZW5waGFzZTpmZTlmMzQzNzU0YmQxZjRkYTU4NGQzNmMwNmI5YTU4Mg==” with is the base64 coded “enphase;password” that works for me from enphase. But the call says anonymous has to be supported.

  105. Matthew says:

    So I tried a new approach with a lot more more success. I created a Execl file with two worksheets. In the first worksheet I wrote a normal Data -> web query that polls the website, successfully passes the credentials – grabs the inverter JSON results and simply writes it to a local file called inverters.json. Then in another worksheet write a power builder query to read this inverters.json file and extract the inverter data – scheduled to run every minute. This worked well!

    The only challenge I have now is storing the first procedure call and setting its properties to run every minute. Excel doesn’t seem to want to store this call if Excel isn’t trying to do something with the results. Any suggestion guys?

  106. @Matthew: thanks for the heads-up re IQ8 / Ensemble!



  107. Stuart Graves says:

    I’ve installed an Envoy-S and a 3 phase system and was interested in high resolution logging (ie: every few seconds) of meter data – particularly AC voltage and current.

    Unfortunately the JSON file at http://envoy/production.json just shows the sum total of all 3 phases as the “rmsVoltage” (so, in my case, about 750 V). Same deal with current. Not useful at all.

    However, using the installer toolkit app – or the password protected web pages on the Envoy (discussed in “Reverse Engineering the Enphase Installer Toolkit”), it is possible to see all these values, updated every second.

    So I did some packet sniffing and found another JSON file:




    This is just for the production meter and the first phase (“ph-a”). It continues on for each phase and for each meter.

    Unlike http://envoy/production.json, this requires installer authentication. But since it is a continuous data stream, I guess it’s probably a lot less taxing on the little Envoy than a new HTTP request every second.

    More importantly, it has the info I wanted. Plus reactive power and frequency.

    I can access it from the Linux command line with: “curl –anyauth –user installer:******** http://envoy/stream/meter“.

    Password is the installer password unique to the envoy, thanks to your awesome app at https://www.dropbox.com/s/csmm9izuu5nyllj/AndroidXam.AndroidXam.signed.apk?dl=0.

    Note that the first curly bracket is missing from the “data” key, so you need to add that bracket and the quotation marks before the JSON can be parsed.

    Hope this helps someone.

  108. Hi Stuart,

    Fantastic find with the hxxp://x.x.x.x/stream/meter URL! I will add that to the page. I don’t have 3 phase so didn’t even consider that it might be a problem for some people.

  109. Pete says:

    Using the wealth of information here I’ve put together a small python script that scrapes data from my envoy and makes it available to prometheus (a time-series database) and grafana (a service for plotting data).

    Everything runs in docker and it’s pretty trivial to set up once you have calculated your installer password.

    Everything can be found here: https://github.com/petercable/solar-observatory

  110. Michael says:

    Hi Stuart, totally out of my depth so far. 2 days into this.

    I have my installer password, and it works for http://envoy/installer/setup/home#overview etc, but if I try http://envoy/stream/meter it comes up with http://envoy/error and page not found.

    There’s some basic information displayed on the page (serial number etc) and a simple menu. Anything “advanced” I click on asks for authorisation, but username installer and password don’t work. http://envoy/home?locale=en&classic=1 shows if I hit the home, but neither username installer or envoy and the respective passwords work to go furher

    If I change to classic=0 (or remove &classic altogether, I get in further.

    I have:-

    Software Version D4.5.79 (08d137)
    Software Build Date 29 Mar, 2017 1:38 AM

    3 Phase system, 6 x batteries, sadly my solar was installed before and I’ve got a single Fronius inverter.

  111. Gjalt says:

    This is how to access the inverters page in Python 3. Replace 123456 with the last six digits of the serial nr.

    from requests.auth import HTTPDigestAuth
    url = “http://envoy:123456@”
    response = requests.get(url, auth=HTTPDigestAuth(‘envoy’, ‘123456’))
    print (response.json())

  112. CATS says:

    Thanks for the password generator , do you have any program for data logging / charting directly from the envoy-s available that could be used on a Linux distro ?

  113. paulbendall says:

    Thank you to everyone that has commented and the excellent work done by the author. Shame we have to go to this length of reverse engineering / scraping when Enphase are collecting “our” data.

    I’m using the API call “http://envoy/api/v1/production/inverters” to interogate the individual power production of the inverters. I’ve noticed they only update every 15 minutes, is this what others are observing?



  114. Thanks all! – very useful I now have my system now scraping the /stream/meter data.
    I have 3 phase power, so it’s great to see that each phase is doing. I’m hoping this may allow me to identify particular loads, i.e. the dishwasher, dryer, pool pump etc…

    It took me a while to be able to read the /stream/meter data, I ended up authenticating to /installer/setup/home first. Then calling /stream/meter (using the same HTTP session).

    Regrading the JSON data format this is consistent with a stream of Server Sent Events (SSE). I used the following python library to deal with this:
    So no modifying of the payload required.

    @Paul – yes my inverter data only updates around every 15 minutes also.

  115. paulbendall says:

    @Hamish – how did you maintain session information between calls? Did you use curl from the CLI or Python? The curl example given further up by @Stuart (“curl –anyauth –user installer:******** http://envoy/stream/meter“) doesn’t seem to work for me, I just get a null response

  116. CATS says:

    I have found http://envoy/api/v1/production/inverters can be set to refresh every 5 min ( toolkit needed network-settings standard mode ) and http://envoy/stream/meter is live my gripe is I had no way to remove dead inverters from showing in the output , so I had to alter scraper to disregard dead inverters https://github.com/MasterCATZ/solar-observatory the other is using wifi connection it lags the envoy and network pretty badly

  117. paulbendall says:

    @Cats thanks for the pointer with regard to changing the 15 min interval to 5 min. I had to set mine to Low Bandwidth and then back to Standard for it to start sending every five minutes rather than 15 minutes. Still having no joy with streaming. Is it possible to observe the stream via curl or web browser?

  118. David McPaul says:

    I would like to add my thanks to the writer of this site. I used the information you gathered to write my own tool for displaying data. https://github.com/dlmcpaul/EnphaseCollector

    It can output to an influxdb or pvoutput web site for easy visualisation or just use the internal web page to display current overview.

  119. Janrex says:

    re: whToday being zero in “net-consumption” within production.json. if you’re after a “today” net consumption calculation for home automation, make a reading at midnight against whLifetime and store the value. read it again when needed and subtract the current whLifetime against the midnight whLifetime read.

  120. Ray says:

    Could anybody help me writing a python script that can trigger a command when produced power is > 5000w?

    I have both my heater and poolpump connected to a raspberry allready and would like to activate then when more then 5000w is generated

    Email: geennut@hotmail.com

  121. bart klumpers says:

    Quite a different yet related query – any information about the commands Enlighten must be issuing to the Envoy-S? For instance, when I change in Enlighten when I want to charge my batteries from the grid? Maybe my monitor program could then tell the Envoy-S to start charging whenever it is worthwhile. Enlighten only allows for charging between midnight and 6 am, where maybe I want to start charging at 15:00, and perhaps the direct approach will allow that. My power provider charges me spot prices plus a fixed component varying between peak and off-peak times, and my monitor program could decide when it is time to start charging, depending on time of day, current charge in the battery, and current power price. The spot price component sometimes drops down to almost zero – a great time to charge, but has also been very high, even (exception) at $10/kWh – better not charge then!

  122. Thank you so much, it’s perfect for http://local_ip_through_vpn/production.json and the six CT information !

  123. Adam says:

    Does anyone know where the firmware update URLs are ? I haven’t been able to gather that information yet , nor have I seen it mentioned ..

  124. Hey @Paul – yes I used python to manage the session
    Here’s a code snippet (untested):

    import requests
    import logging
    import sseclient
    from requests.auth import HTTPDigestAuth

    logger = logging.getLogger(‘pythonStore’)
    logger.info(‘Logging in…’)
    session = requests.session()
    url = ENVOY_URL+’/installer/setup/home’
    resp = session.get(url, auth=HTTPDigestAuth(ENVOY_INSTALLER_USER, ENVOY_INSTALLER_PASS))
    if resp.status_code != 200:
    logger.error(‘Login failed. Error code [%i]’ % resp.status_code)
    url = ENVOY_URL+’/stream/meter’
    logger.info(‘Getting data from [%s]…’ % url)
    resp = session.get(url, auth=HTTPDigestAuth(ENVOY_INSTALLER_USER, ENVOY_INSTALLER_PASS), stream=True, timeout=(10, 300))
    if resp.status_code == 200:
    sclient = sseclient.SSEClient(resp)
    logger.info(‘Start processing meter data…’)
    for event in sclient.events():
    logger.info(‘End processing meter data…’)
    logger.error(‘Failed to process meter data. Error code [%i]’ % resp.status_code)

  125. MasterCATZ says:

    anyone else getting blocked from accessing http://envoy.fritz.box/api/v1/production/inverters 30 minutes after logging into the system via Toolbox ?

  126. Rob T. says:

    First, thank you (and everyone else here) for sharing all of this info, very helpful to me with an Envoy IQ.

    Does anyone know what’s in the Envoy’s database and how to access it? I see the reports of the database space utilization. But what’s in there? I can only guess that it is some metric storage.

    After about a month and a half of operation, my Envoy IQ’s db is only 1/2 full.

    The event log seems to max out at 500 entries, which is only about 1-2 days worth with 26 panels/microinverters.

    Last question, are there any other sites where people are discussing the Envoy and local access?

  127. Rob T. says:

    My Envoy-IQ status page says that the metering isn’t setup. Despite that, I still seem to be getting production data. My envoy couldn’t be located near the panels, so I’m not set up to monitor consumption. I need to find some other solution to handle that which will work with 2 x 200 amp panels.

    So if the metering isn’t setup, what’s producing the production data that is being reported?

    If the metering was setup correct, what else would I be seeing?

    Anyone try to configure metering on your own?

    If I try the “Wizard” via the Envoy’s built in web app after logging in as installer, it seems to hang and never complete.

    Thanks for any insights

  128. doc says:

    Thanks to the great info provided here I was able to put together a Python based realtime(ish) monitoring dashboard for my PV system. Everything works great, however there is one missing bit of information that I haven’t been able to find.

    I need to know how much has been imported from the grid (not ‘consumption’) at any given time of the day (or even total grid imports per day). MyEnlighten seems to know this figure because it reports it in the consumption part of the UI: Approximately xxxx kWh imported from grid.

    Does anyone know how this info can be obtained? I’d like to keep track of daily electricity costs/credits. Thanks.

  129. doc says:

    A further complication revolving around knowing the actual grid import figure, is knowing how much energy was actually exported (for FIT calc).

    MyEnlighten reports Net_Energy_Exported as a simple calculation: Energy_Produced minus Energy_Consumed. But this isn’t right because when the sun goes down, consumption keeps increasing, while Energy_Exported keeps decreasing!

    The total amount of energy exported to the grid for the day should not vary after the sun sets (just like total production does not vary).

    This is all tied to the same issue of conflating solar self-consumption with actual consumption through grid imports, into a single ‘consumption’ value.

    The only way I can think of getting accurate grid import/export data is by monitoring power generation/consumption over a 24 hr period in 1 second intervals (so that I can work out energy values).

    I’m starting to do this now, but I’m not sure how accurate the energy values are as the Envoy hub does not respond to get requests with military regularity. So there will likely be some drift over 24 hrs…

    The other problem is that sometimes Envoy stops responding to requests for minutes or not at all and I have to restart my app, but then the running totals are lost (as are gaps in time). Argh!

  130. David McPaul says:

    The envoy is not powerfull enough to respond to requests of that frequency. I find 1m intervals to be accurate enough and have not had any issues with the envoy stopping.

  131. doc says:

    I’ve been able to poll at 1sec intervals for well over 12hrs at a time without issue. But eventually, it does fail with this message:

    “A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond”

    I have to wonder that if it works fine for such long periods of time (at high frequency), when it fails that it might perhaps have something to do with Enphase querying the server remotely or trawling through the internal DB, or something, which makes it unresponsive to my GET requests…or the Envoy doing some housekeeping itself.

    The trouble with reducing the polling rate to 1min is that there is a reduction in accuracy when tracking total energy for grid-in and grid-out purposes.

  132. I’ve found that the failed requests still seem to get processed by the envoy so the more it’s failing and the more you try the longer it I’ll fail for.
    With my one I time out after about 10 seconds and then detect that and “back off” for 60 or 120 seconds to give the envoy time to recover and then resume normal 1 second polling again.

  133. doc says:

    >the more it’s failing and the more you try the longer it I’ll fail for.

    Yes, that’s what I’ve found. Once it fails, it rarely comes back (sometimes it does), until I stop the app and then restart after a short while.

    I’ve tried a few different things, which seem to work (so far). I scrape for ‘production.json’ and ‘production/inverters’ – the former at 1sec intervals, the latter at 20sec (as it doesn’t get updated as often).

    Now I’ve switched to 3sec & (still) 20sec intervals, but I’ve also added different user-agents in the header requests. I also back off for 20sec on failure.

    So far, this has worked well and I can live with 3s vs 1s polling intervals. Also, I’m just using a ‘dumb’ delay, but might try using the backoff_factor construction.

  134. Pierre Nakashian says:

    Doc, I’ve figured how to calculate Import From Grid for about a couple days now, I have it working in Home Assistant scripting language and it’s within 1kw from my Utility provider’s smartmeter readings, after many trials and errors.

    you only need to poll http://envoy.local/production.json
    it is basically the following rules

    if consumption[1][“wNow”]>0

    consumption[1][“wNow”] – ( production[0][“wNow”] – production[1][“wNow”] )

    if (consumption[1][“wNow”] <=0 then the formula becomes

    0 – ( production[0]["wNow"] – production[1]["wNow"] )

    if the result of the above formula's is <0
    then the realtime Import Power is 0

    I take the result of the above convert to WH. Since I sample envoy about every 2 minutes, I multiply each calculation by about (120/3600)
    then I take cumulative sum throughout the whole day. When I compare this summation result its slightly larger than myenlighten.com but slightly less than 1kw from the utility website smartmeter readings smartmetertexas.com

    I do have a few more cleanup rules, I don't know 100% if they are making any difference.
    I do set the readings (wNow) to zero if Powerfactor=0 ,

    for production readings I also set (wNow) to zero if powerfactor<=0 or wNow<0
    I have 2 additional rules I have to check if they are needed.

    I'm still working on the Export rules, just have a few more days to try a few things but I almost have that one figured out as well, for export i'm about 1kw higher than the utility providers smartmeter readings.

    My problem now is trying to figure out how to store End of day results from Home Assistant, into a new table or a new History Chart .

  135. doc says:

    >Doc, I’ve figured how to calculate Import From Grid…
    >you only need to poll http://envoy.local/production.json

    Hi Pierre, yes, that’s where I get my data from too. I poll the inverters only to get individual panel production values which I display in a bar graph.

    For the energy calcs, I’m doing something similar to you, but using production[1][‘wNow’], not production[0][‘wNow’]. I don’t really understand the relevance of production[0][‘wNow’] – it has a different timestamp compared with all the other timestamps, so it just seems to be an earlier version of production[1][‘wNow’]…

    My calculation is as follows:

    # Get elapsed time from last read
    timestamp = time.time()
    tdelta = timestamp – tsPrevTime
    tsPrevTime = timestamp

    if consumption[1][‘wNow’] >= 0 :
    # Importing from grid
    wGridIn = consumption[1][‘wNow’]
    whGridIn += (wGridIn * tdelta / 3600)
    # Exporting to grid
    wGridOut = -consumption[1][‘wNow’]
    whGridOut += (wGridOut * tdelta / 3600)

    This works pretty well.

    > …then I take cumulative sum throughout the whole day.
    > When I compare this summation result its slightly larger
    > than myenlighten.com but slightly less than 1kw from the
    > utility website smartmeter readings

    I suspect the reason why you’re off is due to the long-ish sampling rate of 2 mins – a lot of fluctuations can occur over 2 mins which you won’t catch.

    Also, don’t assume that because you poll every 2 mins, that you will get a result every 2 min from Envoy. I poll every 3 sec but keep a time delta between polls to use in the energy calculation (it fluctuates a fair bit).

    What I have now works okay, but it does have some drawbacks. I have to start the app before sunrise because then I know that the whToday consumption data is definitely from grid usage. Then as the app runs throughout the day, it keeps accumulating the energy import/export as shown above.

    The biggest problem is that after many hours of running, the app sometimes locks up and I have to restart. But restarting after sunrise means that I can’t determine real grid in/out figures. I have to figure out why it locks up (it doesn’t appear to be the GET requests…maybe an issue with Python – dunno yet).

  136. Pierre Nakashian says:

    Hi Doc,
    thanks for the info, I’ll have to try to convert my readings to energy first before using them in the formula. Maybe that’s the source of my issue.

    here’s what I know of the differences between production[0][‘wNow’], and production[1][‘wNow’].

    when I read production[0][‘wNow’] convert to energy and perform cumulative sum, It gives me the Total Energy my panels produces, yesterdays cumulative sum value matches exactly myenlightens.com Total production to the 2 decimal location they display. Unfortunately envoy updates this data only every 15 minutes. production[1][wNow] is more realtime,
    but converting to Energy and performing cumulative sum does not add up to Total production, and its also much less than Exported Energy to grid. Cumulative sum of p1.wNow yesterday was about 24.65KW same as p1.whToday
    but my export to Grid was 47.65KW and my total production was 67.76KW
    (export to grid is almost 67.76 – 24.65= 43.11 just 4kw discrepancy.

    It looks like the solar panels only consider exporting to grid when Total Energy production is above production[1][“wNow”] threshold, provided this power difference can be used to compensate all of your power consumption, and still have enough power left to export to the grid. if we reduced all our consumption to 0 export energy is roughly
    production[0][“wNow”] – production[1][“wNow”] , but to get exact Export Energy you need the negative values from consumption[1][“wNow”] as well to add to the exported energy.

    the difference of the 2 production values are roughly best case Exportable Energy, don’t know why or where does the production[1][“wNow”] energy goes to. could it be Waste energy to convert DC to AC? don’t know why the negative values in consumption[1][wNow]
    are needed to get exact Exported Energy.

    my export to Grid formula is below, except in Export to grid calculation
    you need to include the negative values in consumption[1][“wNow”] .
    I’ll have to try converting the readings to energy 1st then using
    the formula below, see if calculation is better.

    ( production[0][“wNow”] – production[1][“wNow”] ) – consumption[1][“wNow”]

    I tried to increase the frequency of measurements today, it caused envoy wifi to be lost for about 15 minutes, homeassistant then was throwing errors, luckily it can survive envoy blackouts or occasional envoy latency in responses. I may have to rewrite this in Java to control envoy request more carefully.

    could your app unresponsiveness be related to envoy becoming unresponsive after too many repeated request? In java Depending on how nested packages you’re using are, when an exception occurs in java and many repeatedly it could consume memory faster than Garbage collection can reclaim the memory, then java will crash with out of heap memory. Not too familiar with python though.

  137. Pierre Nakashian says:

    Hi David,
    pretty nice, like seeing code project from work. I have to brush up on my annotations/lombok/spring/lambda I don’t write as much java, I’m more of a database guy that writes java on the side. I got far enough to get it running in eclipse. I added a few more gauges for exportToGrid and ImportFromGrid that my utility provider seems to be tracking separately. Still trying to figure out how to add trend charts for exportToGrid and importFromGrid.

    I did notice the production values are from production[1].wNow instead of production[0].wNow, makes me wonder if envoy for different configuration is giving total production only on production[0].wNow for some people like me, and production[1].wNow for others.

    my Envoy up until August 7 was actually mis-configured it was reporting I was using 2x from grid, Solar installer sent someone and found it was set wrong, they changed it.
    I’m curious if you go the following URL below if your meter modes are Single or Three phase?

    This url http://envoy/installer/setup/home#meters/detail/production says my production meter mode is Single-Phase(L-L), same with the consumption meter mode.

    I also have to change the Dockerfile slightly to get openjdk for arm32, I’ll be running the docker in a raspberry pi.

    Thanks for sharing the code with all of us.

  138. David McPaul says:

    Unfortunately I do not have access to the installer pages.

    I can get the meter information from http://envoy/ivp/meters and that gives me this json

    “eid”: 704643328,
    “state”: “enabled”,
    “measurementType”: “production”,
    “phaseMode”: “three”,
    “phaseCount”: 1,
    “meteringStatus”: “normal”,
    “statusFlags”: []
    “eid”: 704643584,
    “state”: “enabled”,
    “measurementType”: “net-consumption”,
    “phaseMode”: “three”,
    “phaseCount”: 1,
    “meteringStatus”: “normal”,
    “statusFlags”: []

    suggesting I am three phase with one phase configured? Which sounds wrong to me as I don’t think my house is using three phase.

    I don’t so much read from production[0] or production[1]. I look for the “eim” type with a measuremenType of “production” and for consumption I look for a measuremenType of “total-consumption”

    production[0] is generally a simple structure marked as “inverters” and it’s wNow value seems ot be a rounded figure.

    But different versions of enphase affect the returned json being scanned.

    My code handles D4.2.27 & D4.5.79

    What version do you have?

    I would like to collect responses from other versions as well to try and learn more. It could be three phase needs to be handled differently.

  139. doc says:

    >my export to Grid was 47.65KW… and my total production was 67.76KW
    >(export to grid is almost 67.76 – 24.65= 43.11 just 4kw discrepancy.

    That’s almost a ten percent difference, which isn’t insignificant…

    I was able to get my polling working for well over 24hrs now. I think my issue was to do with threading, as I had two threads polling for different data at differently scheduled intervals. I’ve simplified it down to a single thread and it’s been working reliably.

    So, I was able to compare my calculated grid values against my smartmeter and MyEnlighten. Unfortunately, my meter only displays energy in/out to one decimal place, but even so, I was able to determine that my calcs were accurate to within 0.4%, which I think is pretty good.

    >could your app unresponsiveness be related to envoy becoming
    >unresponsive after too many repeated request?

    I think I’ve overcome that problem, as mentioned above, by rethinking my use of threads. The current setup works without issue with 3sec polling of ‘production.json’ and 20sec polling of ‘production/inverters’ (during daylight hours only). So polling frequency wasn’t really the problem as such.

  140. Pierre Nakashian says:

    Hi David,
    my software information using the url http://envoy.local/info.xml in the device section it shows it is R4.10.35

    the meters url you gave it shows I have a very different configuration than yours, split mode with 2 phases for production/consumption and in the consumption section mine is total-consumption yours is net-consumption.

    “eid”: 704643328,
    “state”: “enabled”,
    “measurementType”: “production”,
    “phaseMode”: “split”,
    “phaseCount”: 2,
    “meteringStatus”: “normal”,
    “statusFlags”: []
    “eid”: 704643584,
    “state”: “enabled”,
    “measurementType”: “total-consumption”,
    “phaseMode”: “split”,
    “phaseCount”: 2,
    “meteringStatus”: “normal”,
    “statusFlags”: []

    when my panels are at full power like below The production value under type “eim” by itself is useless. the java code method
    Optional inv = system.getProduction().getInverter();
    in place of
    Optional eim = system.getProduction().getProductionEim();

    does resolve the issue for getting total production. no issue with consumption section of the java code with my envoy software version, i think consumption[0].wNow under mine and your envoy software are reporting similar data, probably in mine consumption[1].wNow will be different. my consumption[1].wNow becomes negative when I’m exporting to the grid, when my panels are not producing any energy consumption[1].wNow is identical to consumption[0].wNow, when my panels are generating some energy but not enough to export my consumption[1].wNow is a smaller positive value.

    “production”: [
    “type”: “inverters”,
    “activeCount”: 41,
    “readingTime”: 1570378963,
    “wNow”: 9405,
    “whLifetime”: 22689789
    “type”: “eim”,
    “activeCount”: 1,
    “measurementType”: “production”,
    “readingTime”: 1570378983,
    “wNow”: 3545.69,
    “whLifetime”: 13784731.903,
    “varhLeadLifetime”: 134.344,
    “varhLagLifetime”: 5598841.857,
    “vahLifetime”: 17567742.118,
    “rmsCurrent”: 28.839,
    “rmsVoltage”: 249.05,
    “reactPwr”: 334.577,
    “apprntPwr”: 3591.212,
    “pwrFactor”: 0.99,
    “whToday”: 7474.903,
    “whLastSevenDays”: 165138.903,
    “vahToday”: 10206.118,
    “varhLeadToday”: 0.344,
    “varhLagToday”: 3535.857

  141. Otto says:

    You can also use: http://envoy.local/ivp/meters/readings to get the individual phases.

  142. David McPaul says:

    Interesting, I might switch to the Inverter wNow values then. On my system they track the same except the inverter value was just a little higher and looked to be rounded.

    Would you be able to send me some outputs like the ones listed here https://github.com/dlmcpaul/EnphaseCollector/tree/master/src/test/resources/stubs/D4.5.79

  143. Pierre Nakashian says:

    Hi David,
    just a caution on production[0][“wNow”] of type “inverters” on my envoy setup I have no choice but to use it to get total production that matches myentune.com. In the morning after panels start to generate power and start ramping up, production[0] type “inverter” is only updated every 15 minutes, this includes readingTime, wNow, whLifetime. the wNow value also has no decimal values. The value I get is very close to the sum of all the inverters lastReportWatts from the url below, (lastReportWatts also has no decimal values), the sum of WH calculated values I get is identical to myentune.com.

    Even this URLS http://envoy.local/ivp/meters/readings readings for production is not my total production.

    Some of you maybe luckier to get production[1] type “eim” and get total production with greater precision than me, but I can’t be sure of that. Only way to be certain is cumulative sum of production in WH and compare against myentune.com or your provider website if they give you access.

    I ran curl and generated .json files for the url you have in your .json files. I’ve uploaded my files to dropbox here’s the link.


    I’m still not sure if I have Envoy-S or IQ-Envoy, i managed to get the installer password following reverse-engineering-the-enphase-installer-toolkit, but near my unit there is a sticker it says IQ-Envoy. I’ve sent an email to the installer to find out which one they installed.
    info.xml does give a part number 800-00555-r03, I googled it, no hit which Envoy it is.

  144. pauljloz says:

    If you want to access data rapidly, consider using http://%s/stream/meter ? This doesn’t tax the envoy.

  145. pauljloz says:

    See Stuart Graves post November 27, 2018 at 21:04 for more details of the stream.
    The code below is loosely based on one of the examples that followed Stuarts post, and sums kW for the first 2 phases (ph-a + ph-b) from an envoy-s.
    You can use the Python code below in IDLE to stream live data to the console window.
    Production data appear to be “live” and change between each value streamed (about every second).
    I am using this for demand management.

    import os
    import time
    import json
    import ijson
    import requests
    import threading
    from requests.auth import HTTPDigestAuth

    #envoy-s host IP
    host = ‘#######’
    password = ‘#######’

    user = ‘installer’
    auth = HTTPDigestAuth(user, password)
    marker = b’data: ‘

    def scrape_stream():
    while True:
    url = ‘http://%s/stream/meter’ % host
    stream = requests.get(url, auth=auth, stream=True, timeout=5)
    for line in stream.iter_lines():
    if line.startswith(marker):
    data = json.loads(line.replace(marker, b”))

    print(f”{data[‘total-consumption’][‘ph-a’][‘v’] :5.0f}v {data[‘total-consumption’][‘ph-b’][‘v’] :5.0f}v {data[‘total-consumption’][‘ph-a’][‘i’] :5.1f}a {data[‘total-consumption’][‘ph-b’][‘i’] :5.1f}a POWER prod: {prod:6.0f}W cons: {cons:6.0f}W net: {net:6.0f}”)

    except requests.exceptions.RequestException as e:
    print(‘Exception fetching stream data: %s’ % e)

    def main():
    stream_thread = threading.Thread(target=scrape_stream)

    if __name__ == ‘__main__’:

  146. Pierre Nakashian says:

    with my envoy setup the data from http://%s/stream/meter does not give me not total production

    here’s production.json production[0].wNow=4161 W
    production[1].wNow=1070 W

    data from http://%s/stream/meter within 5 seconds of production.json readings
    is closer to production[1].wNow

    from ph-a ph-b of p (true power) 547.661+546.063=1093.724 W

    “production”: [
    “type”: “inverters”,
    “activeCount”: 41,
    “readingTime”: 1570641497,
    “wNow”: 4161,
    “whLifetime”: 22894013
    “type”: “eim”,
    “activeCount”: 1,
    “measurementType”: “production”,
    “readingTime”: 1570641915,
    “wNow”: 1070.227,
    “whLifetime”: 13859282.806,
    “varhLeadLifetime”: 134.344,
    “varhLagLifetime”: 5621436.782,
    “vahLifetime”: 17657166.059,
    “rmsCurrent”: 9.226,
    “rmsVoltage”: 246.715,
    “reactPwr”: 310.49,
    “apprntPwr”: 1136.716,
    “pwrFactor”: 0.94,
    “whToday”: 4464.806,
    “whLastSevenDays”: 170624.806,
    “vahToday”: 7532.059,
    “varhLeadToday”: 0.344,
    “varhLagToday”: 3826.782

    — /stream/meter —
    data: {“production”:{“ph-a”:{“p”:547.661,”q”:155.899,”s”:580.791,”v”:123.724,”i”:4.703,”pf”:0.94,”f”:60.0},”ph-b”:{“p”:546.063,”q”:154.276,”s”:579.582,”v”:122.936,”i”:4.722,”pf”:0.94,”f”:60.0},”ph-c”:{“p”:0.0,”q”:0.0,”s”:0.0,”v”:0.0,”i”:0.0,”pf”:0.0,”f”:0.0}},”net-consumption”:{“ph-a”:{“p”:-355.692,”q”:24.248,”s”:261.905,”v”:123.769,”i”:2.116,”pf”:-1.0,”f”:60.0},”ph-b”:{“p”:36.513,”q”:31.768,”s”:87.554,”v”:122.965,”i”:0.712,”pf”:0.42,”f”:60.0},”ph-c”:{“p”:0.0,”q”:0.0,”s”:0.0,”v”:0.0,”i”:0.0,”pf”:0.0,”f”:0.0}},”total-consumption”:{“ph-a”:{“p”:191.969,”q”:-131.65,”s”:320.666,”v”:123.814,”i”:2.587,”pf”:0.59,”f”:60.0},”ph-b”:{“p”:582.576,”q”:-122.507,”s”:668.322,”v”:122.994,”i”:5.434,”pf”:0.86,”f”:60.0},”ph-c”:{“p”:0.0,”q”:0.0,”s”:0.0,”v”:0.0,”i”:0.0,”pf”:0.0,”f”:0.0}}}

  147. rcterzi says:

    With the data that’s available that’s now available via the envoy – is there any reason to pay for Enlighten Manager?

  148. doc says:

    Probably not if you do the data scraping yourself. I only use Manager from time to time now, mainly for viewing system Events (such as dropouts due to out of range line voltage and/or frequency or other notable events).

  149. These discussions are very interesting,but I just wanted to point out that for anyone wanting a device to continuously and accurately monitor surplus production and divert it to heat water, you can’t do better than to purchase the Solar iBoost+. Simply clip a sensor on a wire in your meter box and it relays information to a box you can locate near your immersion heater. Even better, the device has a second output so that when water is hot, you can divert elsewhere – mine goes to a panel heater. Device then keeps checking periodically for water cooling due to circulation or use and flips back to water heating when required. I have also reduced the thermostat on my gas water heating circuit and maxxed it on the immersion thermostat. For about 7 months this year, I used no gas at all. Everything solar.

  150. Bob says:

    I’d like to have envoy type monitoring primarily to be sure none of my inverters have failed but don’t really want to buy an envoy. Has anyone been able to communicate directly with the inverters?

  151. Mickey A says:

    Long story shorter…Love reading this thread. I am ultimately working on an Excel sheet to pull historical data from Enphase API but after finding this thread, I am interested pulling realtime Envoy data to post on my Excel sheet for current production and consumption data. However, for the life of me, I can seem to make the math work. And here is what I am doing to compare what I am getting from production.json withe my envoy.local/home page. I am trying to take my production and consumption numbers at the same point and time as running production.json and attempting to match up. Never matching…I am assuming that the local home page is grabbing every minute so I am waiting to pull(json) right when it changes. Am I missing something in my retrieving of production and consumption via JSON? My json values are always lower than the local home page. Makes wonder how accurate I can get if I missing something. Can someone explain what I am seeing/experiencing? Or maybe a better way?

  152. Thomas says:

    I’m having trouble getting the installer password. I tried to run the .apk on a couple devices, and an emulator but none were working. Enphase support was also entirely unhelpful in this matter. Can someone who has gotten it working provide the device and OS information?

  153. What happens when you try to use / install the app?

  154. Capt. Smek says:

    Anyone knows how to determine the mapping of inverters to array (as graphically represented in the enphase web site or app)? I have 2 arrays and I’d like to be able to know how to group each individual inverter to sum production for each array as they are connected to different houses.

  155. Olivier says:

    Hi thecomputerperson,
    Just wondering if you can give me some hints on how to go about getting very basic info (which can be found from /production.json) and display it on a re-purposed iPhone. I want it to be super minimalist, so ideally a HTML file directly on the iPhone. But I do have a Raspberry Pi2 at my disposal I could setup to be a server. Any hints what would be the best approach? I’m not really confident in writing java script. But I guess I could learn if push comes to shove. Just want a basic dashboard in my kitchen, with near real time consumption, production, and net value.

  156. Hamish McNeish says:

    Hi @Capt. Smek – I asked my installer and they were able to provide a picture of the layout and the matching serial numbers for each panel. Then I was able to replicate the Envoy display.

  157. Hamish McNeish says:

    Hi @Oliver, some options to consider:

    – I guess the Envoy mobile app doesn;t meet your needs?, I have Android but I assume there is an Apple version

    – Look for existing integrations to home automation systems like Home Assistant
    (Hopefully someone else has done the hard work :)

    – On the Pi2 run a Cron job calling CURL to preiodically download the JSON data, then host an html page with javascript to render it

    – On the Pi2 run a Python web app, for example Python using Flask to serve up the data, then render with javascript and html

    – On the Pi2 run an app (like the Python examples) to query and store the data to InfluxDb, then use Grafana to viualise it

    I do the last one using containers for Grafana, InfluxDB, and my python app. Grafana is great and pretty easy to use, and handles rendering on a mobile.

    I expect various people have done the options above, and there is code and links in these comments that may help.

    I plan to put my solution on GitHub with the container detail so it can just be installed, I’ll see how I go this weekend.

  158. Hamish McNeish says:

    Hi all, I’ve added my container setup that reads from the Envoy and writes to InfluxDb here: https://github.com/jinxo13/EnvoyReader

  159. Steve Muckle says:

    Thanks for this post! I’m building a raspberry pi powered LED light strip power meter to visualize the our current solar production and total power consumption. I was going to use the enlighten API (I thought it was great that was documented as well as it was) but then figured there must be some way to grab that data off the local device. I found the webpage for the device but wondered how I could access it programatically… production.json!

  160. Peter Galbavy says:

    I was playing with my Envoy-M (pill shaped) now that I have my installer password – thanks for that – and any of the /ivp/ urls redirected to port 9094. Authenticating with that and going to the root of the site gives me a directory listing with interesting pages, including


    which leads to full documention!

  161. Good to know! Any chance you can pastebin, or similar, a copy?

Comment on this topic

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s