Capture and Analyze Solar Power Generation Metrics with Python and InfluxDB

Over the past couple of months, I’ve been working on building out a solar energy harvesting and storage solution. This solution involves several components, including solar panels, a solar charge controller, and battery storage. All of these components work together to gather energy from the Sun, and efficiently charge the battery storage bank. Here’s what my current solar power generation setup looks like.

The charge controller that I am using is the EP Solar Tracer 3210an. Although it has a LCD screen, the charge controller doesn’t offer much in the way of controls. This package included the EP Solar MT50 meter. The MT50 connects to the charge controller using an ethernet cable with male RJ-45 connectors on each end. Once physically connected, the MT50 uses the modbus protocol to communicate with the Tracer. You can view PV (photovoltaic array) and battery metrics and configure the charge controller’s parameters from the MT50.

MT50 LCD display connected to EP Solar charge controller
The MT50 attached to an EP Solar charge controller

The MT50 provides an excellent interface to view the performance of your battery bank and solar array. However, what if you wanted to capture and retain this data for future analysis? What if you want to compare the performance of your solar array in December versus July? The MT50 doesn’t provide this type of data logging functionality.

Connect Your Computer to the Charge Controller

Instead of using the MT50 device to monitor and control the solar charge controller, you can connect a computer instead. By connecting your charge controller to your computer, you have direct control over the data that’s retrieved from the controller. In my scenario, I wanted to ingest the metrics from the charge controller into the open source InfluxDB time-series database. Once I ingest metrics into InfluxDB, I can then graph the performance of my PV array over time.

Running a high-power desktop computer or laptop to ingest the metrics from the charge controller is overkill. I have several Raspberry Pi 3 B+ devices, so I decided to use one of these. Under peak load, the Pi 3 B+ only consumes about 5 watts of power. This makes the Pi an excellent choice for this purpose.

Charts showing metrics from EP Solar charge controller and battery bank

The big question is: how do I connect my computer to my solar charge controller, and communicate with it via modbus? That is what we’re going to answer here.

Because the charge controller uses modbus (RS-485) to communicate, we need an interface to physically connect to the slave device. I purchased the DTECH USB-to-serial adapter for this purpose. This cable includes an adapter that has bare wire terminals on it. Although it’s more ugly than a nice connector, it makes it easy to wire up.

Buy or grab a spare CAT-5 cable, and cut off one end so that you have only one RJ-45 connector and a frayed end. Strip and connect the wires as seen in the list & photo below. Plug the other end into your charge controller. Because we’re only using two wires to communicate with the slave device, this is considered half-duplex mode. This configuration has worked well for me, but it may be possible to wire it up for full-duplex as well.

  • Blue/White – transmit (Tx)
  • Green/White – receive (Rx)
  • Brown/White – ground (Gnd)

Now that you have physically connected your computer to the charge controller, you can start communicating with the controller.

Retrieve Metrics from the Charge Controller with Python

Although you can theoretically use any programming language to communicate with the charge controller, I decided to use Python. There are several well-supported modules for Python that support modbus, including the one I’m using now called minimalmodbus. Additionally, there’s a well-supported Python module for InfluxDB, which makes it easy to write metrics into InfluxDB Cloud.

You’ll want to consult the documentation for your charge controller to determine which registers to read metrics from. Here’s the documentation for the EP Solar Tracer series charge controllers.

Many of the modbus registers on the charge controller return 16-bit values, however certain ones have two separate 16-bit registers. In the latter case, the two 16-bit registers must be merged together to calculate the result. For example, the photovoltaic (PV, solar panel array) power (in watts) has a “high” and “low” register. Similarly, the battery power is exposed as two 16-bit registers. Other registers, such as PV & battery voltage, and PV & battery current (amps) are represented as single 16-bit values.

I’ve posted the full code that I’m currently using over on GitHub. However, for the sake of this article, I will post a simple example here.

First, install the modules that you’ll need.

pip3 install influxdb-client minimalmodbus

Then create a new Python script with the following code. For example, let’s call the script solar-metrics.py.

import minimalmodbus

ins = minimalmodbus.Instrument('/dev/ttyUSB0', 1, debug=False)

# Set up the connection parameters
ins.serial.baudrate = 115200
ins.serial.bytesize = 8
ins.serial.stopbits = 1
ins.serial.parity = serial.PARITY_NONE
ins.serial.timeout = 1

ins.mode = minimalmodbus.MODE_RTU
ins.clear_buffers_before_each_transaction = True

# Define the registers (from the PDF documentation)
PV_VOLTAGE = 0x3100
PV_CURRENT = 0x3101

# Read and print the registers
pv_voltage = ins.read_register(PV_VOLTAGE, 2, 4, False) 
pv_current = ins.read_register(PV_CURRENT, 2, 4, False) 
print(pv_voltage)
print(pv_current)

Once you’ve created the script, just invoke it from the terminal.

python3 solar-metrics.py

The above code will get your Raspberry Pi connected to the charge controller via modbus, and print out a couple of key metrics (solar panel voltage and current).

Ingest Metrics into InfluxDB

Now you’ve got your basic Python script working, to communicate with the solar charge controller via modbus. However, what if you want to ingest this data into InfluxDB cloud?

First, sign up for InfluxDB’s SaaS service, or deploy a Docker container running the open source version on your local network. Then, use the following code to ingest metrics into InfluxDB.

# Set up connection parameters
influx_uri = 'https://us-central1-1.gcp.cloud2.influxdata.com'
influx_token = 'SET THIS TO YOUR OWN TOKEN'
org = 'SET THIS TO YOUR INFLUXDB ORG'
bucket = 'SET THIS TO YOUR INFLUXDB BUCKET'

# Import InfluxDB into Python script
from influxdb_client import InfluxDBClient
from influxdb_client.client.write_api import SYNCHRONOUS

# Create a writer API client
influx = InfluxDBClient(influx_uri, influx_token)
writer = influx.write_api(write_options=SYNCHRONOUS)

# Construct the metrics as strings and write them to the API
data = 'array1 pv_voltage={0}'.format(pv_voltage)
writer.write(bucket, org, data)
data = 'array1 pv_current={0}'.format(pv_current)
writer.write(bucket, org, data)

Your organization name will be the e-mail address that you signed up for InfluxDB cloud with, and you can create “buckets” to store metrics using whatever name you’d like. There’s a section in the InfluxDB management console that allows you to generate authentication tokens that can write to a specific metrics bucket. Make sure you substitute all the appropriate values into your Python script.

Conclusion

As you can see, with a little coding work, and a compatible solar charge controller, you can capture useful data from your solar power generation system. InfluxDB is easy to deploy, easy to ingest metrics into, and makes it easy to build graphs and dashboards. You can bookmark these dashboards and easily reference them any time you want to analyze the data from your solar power system!

Here’s what the completed solution looks like.

Ingest metrics from solar charge controller to InfluxDB via Python & Raspberry Pi

Please feel free to follow me on Twitter or check out my YouTube channel. Also, leave a comment and let me know what you think of this project!