PHP Solarpanel monitoring via Rasperry PI

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.

 

 

 

 

 

5 thoughts on “PHP Solarpanel monitoring via Rasperry PI”

  1. Hi,

    I saw your Raspi and XS3200 monitoring solution!

    I have 2 XS3200 connected to eachother by the RS485 connection, and connected to an old PC with the Mastervolt software. But this uses tooo much power to run all day long.

    I’m not a master in writing software….
    Do you have the possibility to adapt the software to read out 2 XS3200’s?
    And maybe send me a copy of the image from the memory card?

    Kind Regards,

    Thomas

  2. HI,

    My software is part of a bigger platform to monitor all devices (smartmeter, plugwise, youless e.t.c.) so it is not easy to take out the part that you need.

    However, in theory it should be possible to read out both converters at the same time. They both will have their own unique ID..

    A raspberry will do fine and will have enough power to process this data.
    Kind regards,

    Cris

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.