Andy Malakov software blog

Saturday, November 23, 2024

Commissioning new solar inverter into SunPower PVS5

I have SunPower solar panels on my roof and have been using their monitoring app to periodically check on my system. This summer, however, SunPower filed for bankruptcy, which prompted me to find an independent way to monitor historical production data. My solar setup also has SolarLog meter that operates independently and also used to have ability (3G Cellular) to reporting my solar production, but since 2022 (when cellular network providers phased out 3G), this feature has stopped working. With the 3G sunset, I lost access to historical production data via the SolarLog website. As a result, I decided to explore options for monitoring my production locally, while the SunPower interface is still operational (and I can validate my readings against theirs). I found an excellent guide by Dolf Starreveld on integrating the SunPower PVS6 module with Home Assistant. The guide details how to use a Raspberry Pi Zero W as a bridge between the PVS monitoring LAN and the home LAN. It also applies to the PVS5 SunPower solar supervisor unit, which features two network ports and integrates somewhat more easily than the newer PVS6, which rely on wireless connectivity.
What follows are my notes on how I successfully registered an additional inverter with the PVS5. I accessed the PVS5 management LAN using a Raspberry Pi Zero, but you should be able to follow these steps by connecting a laptop directly to the PVS5 LAN1 management interface as well. The management app should be accessible at http://172.27.153.1 or, if your laptop obtains an IP address via the PVS5 DHCP server, at http://www.sunpowerconsole.com.
DISCLAIMER: These steps are provided "as is" for informational and educational purposes only. I am not responsibile or liabe for any errors, damages, or issues that may arise from following these instructions. Use at your own risk. Always exercise caution when working with electricity.
If you need to update your PVS5 solar configuration (such as adding an inverter), you’ll need to run the "commission" setup process using the SunPower PVS5 Management App.

Step 1: Verify access to SunPower PVS Management App

If you are connected directly to the PVS management port, the SunPower PVS Management app should be accessible at https://172.27.153.1. If you are using a Raspberry Pi as a proxy, connect to the Raspberry Pi’s IP address within your local network. The interface should look like this:

Step 2: Tick the SunPower PVS Management app to work with your own server.

This app is built with Angular and interacts with the SunPower server at https://pvsmgmt.us.sunpower.com. However, as of November 2024, the server endpoints used by the app are no longer functional and return 503 errors. If you inspect the app’s network activity using Google Chrome Developer Tools, you’ll see that it makes the following calls to the main server:

  • https://pvsmgmt.us.sunpower.com/PvsMgmtAPI/api/v1/device/logFwCalls
  • https://pvsmgmt.us.sunpower.com/PvsMgmtAPI/api/v2/rma/candidates
  • https://pvsmgmt.us.sunpower.com/PvsMgmtAPI/api/v1/device/savePvsConfig
  • https://pvsmgmt.us.sunpower.com/PvsMgmtAPI/api/v1/commissioning/config
  • https://pvsmgmt.us.sunpower.com/PvsMgmtAPI/api/v1/module/types

Based on what I observed most of these calls are simply for logging purposes, except for the last one. That call is used to retrieve solar panel and inverter models from the SunPower database, based on the discovered inverter type and the user-provided panel wattage. For example, in my case, I have 335W panels and an AC_Module_Type_D microinverter. The server is expected to return a list of compatible panels with full model numbers, such as SPR-X21-335-BLK-C-AC, like this:

[
  {
    "Value": "SPR-X21-335-BLK-C-AC", # my panels
    "Type": "inverter-micro",
    "Key": 12345
  }
]

I am still unsure about the exact JSON payload the /module/types endpoint is supposed to return. It parses the AC/DC suffix of the panel model (provided in the Value result field) and verifies that the returned Type result field is "inverter-micro". The app also checks the Key result field and validates that it contains a number.

I made the following simple Python Flask program to simulate pvsmgmt.us.sunpower.com shown below.

from flask import Flask, jsonify, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app) 

###########################################
## Stub for https://pvsmgmt.us.sunpower.com
###########################################

# Specific handler for /PvsMgmtAPI/api/v1/module/types
@app.route('/PvsMgmtAPI/api/v1/module/types', methods=['GET', 'POST'])
def module_types():
    filter_param = request.args.get('filter') # unused
    model_type = request.args.get('model_type')
    
    if model_type == "AC_Module_Type_D":     # TODO: Replace with your inverter type
        return jsonify([{
            "Value": "SPR-X21-335-BLK-C-AC", # TODO: Replace with full number model of your battery
            "Type": "inverter-micro",
            "Key": 12345
        }]), 200
    else:
        return jsonify({}), 200

#@app.route('/PvsMgmtAPI/api/v1/device/logFwCalls', methods=['GET', 'POST'])
#@app.route('/PvsMgmtAPI/api/v2/rma/candidates', methods=['GET', 'POST'])
#@app.route('/PvsMgmtAPI/api/v1/device/savePvsConfig', methods=['GET', 'POST'])
#@app.route('/PvsMgmtAPI/api/v1/commissioning/config', methods=['GET', 'POST'])
# Generic handler for all other /PvsMgmtAPI endpoints
@app.route('/PvsMgmtAPI/', methods=['GET', 'POST'])
def handle_requests(subpath):
    return jsonify({}), 200  # Empty / 200=success

if __name__ == '__main__':
    app.run(debug=True)
I run this flask program on default port 5000, and also run STUNNEL to wrap this in SSL using self-signed certificates.
[sunpower]
accept = 443
connect = 5000
cert = sunpower-cert.pem
key = sunpower-key.pem
verify = 0
sslVersion = TLSv1.2
options = NO_SSLv2
options = NO_SSLv3

Step 3: STUNNEL

Last bit was local DNS hack in my Windows system32\drivers\etc\hosts file:
# Sunpower hack
127.0.0.1 pvsmgmt.us.sunpower.com

Now when a page in my browser wanted to access https://pvsmgmt.us.sunpower.com it would go to local STUNNEL process on port 443, and from there to my Flask app running on port 5000.

CHECK: Refresh the PVS Management App and check Developer/Network panel in Chrome: you should see no errors when app tries to access https://pvsmgmt.us.sunpower.com.

Step 4: Run commissioning steps in PVS Management App

It may be helpful to familiarize yourself with the app using the SunPower Manual. Go to page 44 to learn how to use the app. Some of the appendices also provide useful information about additional features that were added to the app later. You may also find this manual generally helpful—for instance, it explains how to determine whether production tracking is set up on the LINE or LOAD side of your system.

Interestingly, the app contains an easter egg: if you encounter a black screen warning about the app’s sunset, you can bypass it by entering the Konami Code (Up, Up, Down, Down, Left, Right, Left, Right, B, A). In my case, the screen appeared, but I was able to dismiss it using the "Close" button. It seems that a thoughtful member of the SunPower development team enabled this lock screen dismissal.

After commissioning is successful, the app attempts to forward you to pvsmgmt.us.sunpower.com. According to the manual, at this step, you can edit general information about your site (such as the owner name and address). In my case, this step had already been completed during the initial system setup and was entirely unnecessary. The new inverter was registered successfully regardless.

That was it. Good luck if you want to follow these steps. Let me know if you need more information.