MPP Solar PIP-1012-MSE interfacing example
April 2022This is a quick example of how to interface with an MPP Solar PIP-1012-MSE solar inverter. It will likely work with other MPP Solar models that share the same form factor, as well as rebranded units. These units typically look like the image below, with a USB and RJ45 connector on the right side of the unit. The RJ45 connector provides a serial interface using the same console cable as Cisco routers use. I believe that the USB connector provides a USB to serial interface, but it has some strange driver requirement.
The serial interface to these inverters is 2400bps, 8 data bits, no parity and 1 stop bit. Commands must be suffixed with a CRC16 checksum to be accepted. The QPIGS command is the most useful status command. Click here to download a copy of the serial interface reference.
Source
#!/usr/bin/python3
## which serial port the MPP Solar inverter is connected to
serial_port = '/dev/ttyS0'
###
import serial ## provided by 'pyserial' from pip
import crc16 ## provided by 'crc16' from pip
import sys ## inbuilt library
def send(ser, command) :
## convert the command to bytes
command_bytes = command.encode('utf-8')
## calculate the CRC16 checksum of the command
crc = crc16.crc16xmodem(command_bytes).to_bytes(2, 'big')
## add the CRC and a carrige-return to the command
command_send = command_bytes + crc + b'\r'
## send the command
print('Sending: ' + str(command_send))
ser.write(command_send)
## flush the serial buffer to make sure the command is sent
ser.flush()
## open the serial port as 2400-8-N-1
serial_connection = serial.Serial(serial_port, 2400, timeout = 1)
## send the command passed as the first command-line argument
send(serial_connection, sys.argv[1])
## get the response
response = serial_connection.readline()[:-1]
## get the response checksum
checksum_received = response[-2:]
## get the response data and convert it to a string
data = response[1:-2].decode('utf-8')
## calculate the response checksum
checksum_actual = crc16.crc16xmodem(response[:-2]).to_bytes(2, 'big')
## print the response if the checksum is ok
if checksum_received == checksum_actual:
print('Data: ' + str(data))
else:
print('ERROR: Checksum mismatch!')
Also available on Github