Blog

The thoughts, opinions, happenings, and just plain ramblings of a seemingly boring person.

Logging Solar Inverter Output with a Raspberry Pi

We've had a 3kW solar array on top of our house ever since we built it about 6 years ago.

Solar panels on our roof. Look at that perfectly competent builder person!

It came to our attention recently that one of our 12 solar panels had shattered glass (seemingly for a while), something you can even see from the latest Google Maps satellite imagery.

dodgy solar panel
Detective work; just like on CSI.

Surprisingly, when we had some guys out to replace it, it is pretty much impossible to source another panel with a similar voltage and current that wouldn't drastically affect the rest of the array. So we ended up just removing the broken panel.

It came to mind that, other than random glances at the inverter's basic LCD display, I had no idea if our solar system is performing as it should. As our inverter (a Samil Solar River SR3K3TLA1) is an old and fairly basic model, it doesn't have fancy wireless/network logging or monitoring, and pretty much only records the total output for the current day (which is reset each day), and the lifetime total output of the inverter.

The only method of external monitoring is through a serial data connection over RS485 or RS232, i.e. the good old serial port that computers have largely ditched for well over a decade.

Sensing the opportunity for a project, I googled around for some monitoring mechanisms. The most popular was having a small computer hooked up to the inverter using a serial cable, and then uploading the data to the online PVOutput service for storage and analysis.

Our inverter (blue box) with the Raspberry Pi attached (the little white box).
Our inverter (the blue box) with the Raspberry Pi attached (the little white box).

I've been waiting to have a decent use case for doing something with a Raspberry Pi, and this seemed a perfect fit: something extremely low-powered that I could stick on the wall (our inverter is inside our garage). I ordered the Raspberry Pi starter kit (which includes the official case, power supply, and SD card in addition to the Raspberry Pi 3 Model B) from Core Electronics, and it was delivered a few days later. The last piece of the pie (ha ๐Ÿ˜‰ ) was a basic serial to USB cable.

For the script itself, I found a lot of references to a perl script from a forum called Solar Freaks, but the website seems to now be defunct. Luckily, some kind person had uploaded the script onto GitHub, so I promptly forked it and went to work.

I have to acknowledge this fantastic post for tips on how to use this script for a Samil inverter, as well as modifying it to run as a cron instead of a looping program. Most of the changes recommended there I have made in my own GitHub repository for the project.

You can find my fork on GitHub.

For a similar Samil inverter, the latest commit from my fork should work fine on a Raspberry Pi, although there are also config files included for some other manufacturers' inverters.

Here are the steps I needed to do to get it working:

  1. On your Raspberry Pi, install the required Perl modules (Perl should already be installed by default on Raspbian).
    1. Open the Perl CPAN module manager:
      sudo cpan
    2. Install the modules:
      install AppConfig Device::SerialPort HTTP::Request::Common LWP::UserAgent
    3. Exit CPAN to return to the bash terminal:
      exit
  2. Download the script from my GitHub repository and extract it to your Raspberry Pi home directory.
    The script assumes that it resides in /home/pi/inverter_monitor/ , but you can put it anywhere and change the paths in config.ini, inverter.pl, and runSolarStats.sh (there should only be a few mentions of the path).
  3. In pvoutput.pl, insert your own PVOuput user account details for your system ID, inverter serial number, and API key:
    my @PVOUTPUT = (
     {
      SERIAL_NUM    => "<REPLACE WITH YOUR INVERTER SERIAL NUMBER>",
      API_KEY       => "<REPLACE WITH YOUR PVOutput API KEY>",
      SYSTEM_ID     => "<REPLACE WITH YOUR PVOutput SYSTEM ID>",
     },
    );
  4. Run the script and see if it works:
    bash runSolarStats.sh
  5. Create a cron so that the script runs according to your desired schedule. I used the following which runs it every 5 minutes between 4am and 8pm:
    */5 4-19 * * * bash /home/pi/inverter_monitor/runSolarStats.sh

That should be it! You can see my system's live output data on PVOutput.org. Below is a graph of yesterday's output.

Let me know if this helps you, and feel free to fork my version of the script for your needs! ๐Ÿ™‚

11 thoughts on “Logging Solar Inverter Output with a Raspberry Pi

  1. Hi Lucas,
    Thanks so much for your informative post!
    At Christmas 2017 I have a very similar epiphany and have sourced code to connect my Australian Orion 2.5 kW (aka Phenotexic) inverter to the Raspberry Pi via the RS 232 port/USB.
    Have had great success.. to a point.
    I am now running your run SolarStats shell and that is creating nice current logs and cumulative data tables at 5 minutely intervals.

    My problems are now uploading to the PV output.org site. How do you run the live feed to the site ( I have configured the pvoutput.pl with my API and id number.) When I run this in the terminal it seems to indicate I had an unauthorised number near the serial number ( line 88) or there abouts.
    I then added the pvoutput file to the run stats to see if I could drive 5 minutely uploads. The "current" file in my log indicates that it has run the file...but my outputs in pv output look odd.

    Do you have any other comment son how you achieved the pvoutput link?
    I have also been trying to get the rrdtool to work and have struggled with that as well.

    I will keep trying, but i just thought I would see if you had any other advice or recollections on how you made this work.
    Cheers - and thanks again.

    Chris

  2. No worries, Chris! Glad you found it useful!

    Line 88 of pvoutput.pl is checking the serial number of the inverter, which you need to specify on line 59. Are you sure you have provided the inverter serial number correctly on line 59? (you will also need to specify your PVoutput API key and System ID on lines 60 and 61 respectively).

    The inverter serial number is mainly if you are running multiple inverters, but even if you are running one inverter, the script still needs you to provide it.

    I hope this helps!

  3. Thanks, Andrew! I haven't had any experience with an ESP8266, but if it can run a Linux-like OS, it should be able to use my version of the script as long as Perl can run on it.

    You could try modifying the script that you link: as long as you can match the specific values that the inverter outputs via the serial cable to a value that PVoutput uses, it _should_ be possible.

    But that probably sounds a lot easier than what might be required (it almost always is... ๐Ÿ™‚ )

  4. No worries! BTW, have you tried comms over RS485 on the Samil? Iโ€™m struggling to get anything from that interface for some reason. I wonder if it has to be โ€˜enabledโ€™ in some way?

  5. Iโ€™ve managed to get some output over RS485. I had been struggling for a few days, using a USB TTL serial adaptor and a TTL to RS485 module. Basically going from 2 wire to 4 wire on the Samil. I finally realised I had to tie both +ve and -ve wires on the 4 wire to allow 2 wire comms.

    Now to try and adapt the fellas code to suit the Samil and Iโ€™ll have a ESP8266 solution with MQTT to integrate with my smart home build!

  6. Nice work!

    If it helps, below is a log from my script if it helps you match up the output data to the values you want (inverter serial number is redacted). You can see at the bottom that the script only sends a few data points to PVoutput.

    Starting up at 04/08/2018 09:40:01 running on linux ...
    Initialise Serial Port... port = /dev/ttyUSB0
    Send -> req init inverter: 55aa000000000004000103
    Send -> req serial: 55aa0000000000000000ff
    Recv < - 55aa0000000000800a5333333131365234353203c7 
    Send -> confirm serial: 55aa0000000000010b5333333131365234353201034a  
    Recv < - 55aa00010000008101060188 
    Send -> req version: 55aa000000010103000104
    Recv < - 55aa000100000183403120203330303056312e3030536f6c6172526976657220332e334b5753414d494c504f57455220202020202053333331313652343532000000000000333630301036 
    CAPACITY : 3000
    FIRMWARE : V1.00
    MANUF    : SAMILPOWER
    MODEL    : SolarRiver 3.3KW
    OTHER    : 3600
    SERIAL   : XXXXXXXXXXXX
    Send -> req param format: 55aa000000010101000158
    Recv < - 55aa00010000018101000183 
    * Parameter Format:
    dataToFollow = hex(01) = 1
     9 = 00
    Send -> req params: 55aa00000001010400015b
    Recv < - 55aa00010000018401000186 
    * Parameters:
    Send -> req data format: 55aa000000010100000101
    Recv < - 55aa00010000018014000104090a0c111213161718313233343536373803d8 
    * Data Format:
    dataToFollow = hex(14) = 20
     9 = 00 = TEMP     =  0 = Internal Temperature
    10 = 01 = VPV1     =  1 = Panel 1 Voltage
    11 = 04 = IPV1     =  2 = Panel 1 DC Current
    12 = 09 = ETOTALH  =  3 = Accumulated Energy (high bit)
    13 = 0a = HTOTALL  =  4 = Working Hours (low bit)
    14 = 0c = MODE     =  5 = Operating Mode
    15 = 11 = ETODAY   =  6 = Accumulated Energy Today
    16 = 12 = HTOTALH  =  7 = Working Hours (high bit)
    17 = 13 = ERR_GV   =  8 = Error message: GV fault value?
    18 = 16 = ERR_GF   =  9 = Error message: GF fault value?
    19 = 17 = ERR_GZ   = 10 = Error message: GZ fault value?
    20 = 18 = ERR_TEMP = 11 = Error message: Tmp fault value?
    21 = 31 = IAC      = 12 = Grid Current
    22 = 32 = VAC      = 13 = Grid Voltage
    23 = 33 = FAC      = 14 = Grid Frequency
    24 = 34 = PAC      = 15 = Output Power
    25 = 35 = ERR_PV1  = 16 = Error message: PV1 fault value?
    26 = 36 = ETOTALL  = 17 = Accumulated Energy (low bit)
    27 = 37 = ERR_GFC1 = 18 = Error message: GFC1 fault value?
    28 = 38 = ERR_MODE = 19 = Error mode?
    Send -> req data as at 04/08/2018 09:40:08 : 55aa000000010102000103
    Recv < - 55aa000100000182280159099e003300006ebc010300e200000000000000000000003709aa139205400004348c000000000787 
    * Data:
    TEMP    :     34.5 deg C = Internal Temperature 
    VPV1    :    246.2 V     = Panel 1 Voltage 
    IPV1    :      5.1 A     = Panel 1 DC Current 
    ETOTALH :        0 kWh   = Accumulated Energy (high bit) 
    HTOTALL :    28348 hrs   = Working Hours (low bit) 
    MODE    :      259       = Operating Mode 
    ETODAY  :     2.26 kWh   = Accumulated Energy Today 
    HTOTALH :        0 hrs   = Working Hours (high bit) 
    ERR_GV  :        0       = Error message: GV fault value? 
    ERR_GF  :        0       = Error message: GF fault value? 
    ERR_GZ  :        0       = Error message: GZ fault value? 
    ERR_TEMP:        0       = Error message: Tmp fault value? 
    IAC     :      5.5 A     = Grid Current 
    VAC     :    247.4 V     = Grid Voltage 
    FAC     :     50.1 Hz    = Grid Frequency 
    PAC     :     1344 W     = Output Power 
    ERR_PV1 :        4       = Error message: PV1 fault value? 
    ETOTALL :   1345.2 kWh   = Accumulated Energy (low bit) 
    ERR_GFC1:        0       = Error message: GFC1 fault value? 
    ERR_MODE:        0       = Error mode? 
    Logging to: /home/pi/inverter_monitor/logs/inverter_XXXXXXXX_20180804.csv
    PVOUTPUT as at 04/08/2018 09:40:09 ...
      ran: /usr/bin/perl /home/pi/inverter_monitor/pvoutput.pl 2260 1344 20180804 09:40 XXXXXXXXXX 246.2 34.5
    Sending to PVOUTPUT [ d => 20180804, t => 09:40, v1 => 2260, v2 => 1344 ]
    
  7. Hmm interesting, so only time, date, etoday and pac values by the look of it, much less than I thought!

    Thanks Lucas, will see how I go with this code. ๐Ÿ™‚

  8. Hi Lucas,
    Thanks for your site, an interesting article. I'm trying to do similar, using your instructions as guidance. I an absolute newbie wrt raspberry pi and linux.
    I have a query.
    I have followed your page and have a pi zero w attached to the inverter. However, when running the bash command the following error results:
    runSolarStats.sh: line 1: /home/pi/inverter_monitor/logs/current.txt: No such file or directory
    Can you point me in the right direction to this little problem?
    Thanks in advance.
    Rob

  9. Hi Robert!

    Hmmm, you might need to manually create the directory it is trying to write the logs to (/home/pi/inverter_monitor/logs/). Try creating that directory and running it again.

Leave a comment

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