Mastervolt with Raspberry PIAs promised some time ago here is the post explaining how I use my Raspberry PI to monitor my SolarPanel Output. I use PHP for this mather.

When I bought my solar panels back in november 2012, I knew that i wanted a Raspberry to communicate with the Solar inverter and read out the values to store them in a database. My preferred language to use was PHP. I will show you how I did this.

First a summary of the equipment I used :

The Mastervolt is equiped with an RS-485 interface. It offers data transmission speeds of 35 Mbit/s up to 10 m and 100 kbit/s at 1200 m. The RS-485 to RS-232 converter makes it easier to talk to the Mastervolt. I choose to use a RS-232 to USB converter and not to use the integrated RS232 port.

I used an RS-232 converter based on the PL-2303 chipset as you can use this without any drivers on the Raspberry PI. Just plug and play.

Bus 001 Device 004: ID 0557:2008 ATEN International Co., Ltd UC-232A Serial Port [pl2303]

Furthermore I used Apache + PHP for the webserver. Performance is not really an issue as I am the only “user” of this system. You might want to look for a lighter variant as Nginx, or Lighttpd.

MySQL data is stored on my Synology NAS, but you can choose to store the data on the SD Card too. The reason I did this is for 1) performance 2) Space 3) Limit R/W actions of the SD card.

I used the phpSerial class to communicate with the RS-232 Port (which is named /dev/ttyUSB0 on my PI)

Now it’s time to get to know the Mastervolt a bit better. You can only do this at daylight. The inverter switches completely off when the sun sets. This also stops all means of communicating with the device 🙂

In order to send commands to the Mastervolt you have to know it’s ID. This is important. You can have multiple Mastervolts connected to each other by RS-485 so the right ID will make sure only that mastervolt will reply.

The codes you can find in the program Masterlog (made for monitoring the Mastervolt from a Windows PC) and a Free Serial Port Monitor. I used the information reversed engineered and gathered by this belgium forum (it’s in Dutch)

I will only post sniplets of the code as it will be to big to post it all as the code is fine-tuned to my home environment. Hopefully it will help and inspire you to use parts of it to do it yourself.

First we need to initialize the comport

#Create Comport
$serial = new phpSerial;
$serial->deviceSet("/dev/ttyUSB0");
$serial->confBaudRate(9600);
$serial->confParity("odd");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->deviceOpen();

Then we can send a special code to the inverter that will reveal it’s ID.

//Send General message to retrieve ID
$serial->sendMessage("x00x00xFFxFFxC1x00x00x00xBF");
$read = $serial->readPort();

if (strlen($read) >9) {
    $hexresult = substr(strtohex($read),18);
    $output = str_split(strtoupper($hexresult), 2);
    $converterID = hexdec($output[3].$output[2]);
    echo "YOUR ID : ".$converterID." (Or hex :".$output[3].$output[2].")";
} else { echo "Inverter offline.."; }

The result looks like : YOUR ID : 688 (Or hex :02B0)  .. but you might have another number of course. This number is used to send further commands to your Mastervolt. I stored it in a variable.

$converterID = "688";

In order to receive some realtime information you have to send a series of HEX codes to your inverter containing the inverter ID, the command you want to be executed and a checksum bit to give the Mastervolt a possibility to check if the data was received correctly.

Mastervolt uses a little endian system, so it reads bits from right-to-left. So we convert our $convererID into 2 parts which i call the id_lowbit and id_highbit.

    $id_lowbit = substr(sprintf ("%04x",$converterID),0,2);
    $id_highbit = substr(sprintf ("%04x",$converterID),2,2);

Now lets form our command to send to the inverter.

$bit[0] = $id_highbit;
$bit[1] = $id_lowbit;
$bit[2] = "FF";
$bit[3] = "FF";
$bit[4] = "B6";
$bit[5] = "00";
$bit[6] = "00";
$bit[7] = "00";

Bit [0] and [1] are the inverterID. Bit [2] and [3] are always #FF , bit [4] is the actually command (in this case, show us realtime values) , bit [5],[6],[7] are always #00 and bit [8] (not shown here) is our checksum which will be added at the end before the command is submitted. Here I will show you the function I used to calculate the checksum.

function calculate_checksum($value) {

$checksum = 0;
$binary_string = pack("H*" , $value);
for ($i=0; $i<strlen($binary_string); $i++){
    $checksum+= ord($binary_string[$i]);
}

//Calculate Least significant bit for checksum value
$leastSigBit = substr(decbin($checksum),-8);
$checksum = dechex(bindec($leastSigBit));
return $checksum;
}

$x=0;
$tosend ="";

while ($x <=7) {

    $tosend .= strtolower($bit[$x]);
    $x++;

}

$tosend = $tosend.calculate_checksum($tosend);

$serial->sendMessage(hextostr($tosend));
$read = $serial->readPort();

Now the command is send to the receiver, expect some results. I have no clue how to turn of the ECHO command so I strip the first 9 bits from the respond. Quick and Dirty 🙂

        $dayprod = $serial->readPort();
        $hexresult = substr(strtohex($dayprod),18);
        $dayprod = str_split(strtoupper($hexresult), 2);

        /* Read current values */
    #Since i have no clue yet how to turn of the echo i strip the own command (first 9 bits from the respond)
    $hexresult = substr(strtohex($read),18);
        $output = str_split(strtoupper($hexresult), 2);

    $solar_voltage = hexdec($output[9].$output[8]);
    $solar_ampere = hexdec($output[11].$output[10])/100;
    $solar_power = round(($solar_voltage * $solar_ampere),2);
    $net_Frequency = hexdec($output[13].$output[12]) / 100;
    $net_ampere = hexdec($output[16]) / 100;
    $net_power = hexdec($output[19].$output[18]);
    $net_voltage = hexdec($output[14]);
    $temp = hexdec($output[23]);
    $efficiency = round ((($net_power / ($solar_power)) * 100),2);

    echo "
 Solar Input Voltage            :".$solar_voltage." Vdc";
    echo "
 Solar Input Current            :".$solar_ampere." Amp";
    echo "
 Solar Power output             :".$solar_power." watt";
    echo "
 Grid Frequency                 :".$net_Frequency." Hz";
    echo "
 Grid Current Reading           :".$net_ampere." Amp";
    echo "
 Feed the Grid Power            :".$net_power." watt";
    echo "
 Grid Voltage Reading           :".$net_voltage." Vac";
    echo "
 Inverter Temperature           :".$temp." ℃";
    echo "
 DC/AC Conversion Efficiency    :".$efficiency." %";

 

Well, in big lines this is how I do it. I actually do 2 queries to the Mastervolt , to give the total production for that day too. You can do that with this command :

        /* Read Day production */
        $bit[0] = $id_highbit;
        $bit[1] = $id_lowbit;
        $bit[2] = "FF";
        $bit[3] = "FF";
        $bit[4] = "9A";
        $bit[5] = "00"; #days back / 00 = current
        $bit[6] = "00";
        $bit[7] = "00";

The final result looks something like (It’s January, winter and cloudy so the results are a bit low currently) :

solarrealtime

And of course this can be stored in a database, from where you can make nice graphics like this :

daygraph

Ofcourse I participate in the online community too. Here are my stats (also send from the Raspberry PI) to PVOUTPUT. The temperature is the outside temperature, which I grab from the KNMI site since I don’t have my own weather station to read-out from (yet!)

Oh, a little tip.. Since Apache might not have access to /dev/ttyUSB0 directly you can try to CHMOD it  to make accessible for all users.