This is a monster blog. Therefore I have sliced it up on a new page.
When the solar panels were installed in 2010, the inverter was a Aunilec Aunisol3000 which did not have an interface that allows to read out information about the electric power production. This was a bit of a disappointment for me as I had to read the production from the power meter and enter the values by hand into my database.
The Aunisol proved to be a difficult choice, at least for the electric power grid in France and it broke in summer 2011. The supplier of the Aunisol3000 unit had to replace it under guarantee, not only at my home but at many other customers as well. So the supplier decided to install a Schneider Electric SunEzy 2800 system in my home. It comes with a RS232 interface, so it was immediately clear for me that I had to connect to this device. There is a software supplied called SunEzy Control running under Windows, but is was no option for me to install a PC that would be running 24 hours a day doing nothing else but listening to the inverter.
So when I got my first Raspberry Pi, it was clear I had to connect this device to my inverter. The tasks are:
- Setup a Raspberry Pi to operate “headless” over SSH
- enable the serial port
- Prepare the required hardware, a 3.3V TTL to RS232 converter and a USB-RS232 cable
- Find out the communication protocol, connect the Raspberry Pi to the inverter and set up a generic communication
- Develop a Python script that reads parameters from the inverter frequently and stores them in a data base.
- Develop a HTML interface to display the data graphically.
- Backup the data on a network drive
- Add more functionality, like a fan
Step 1: Set up the Raspberry Pi to work without Monitor and Keyboard
A very good article about how to configure a Raspberry Pi to work without monitor and keyboard can be found here. However, here is my own story about it:
After the Raspberry Pi had arrived, I went through the usual learning curve of a complete beginner – flashing a SD card with Raspbian, searching frantically a spare HDMI cable to connect it to my TV, not having a USB keyboard at hand (oops!) and last but not least having neither much idea about the Raspberry Pi hardware nor about Linux. The USB keyboard problem I could solve relatively quickly thanks to my self-made UART-to-RS232 adaptor (see step 2) connected to a RS232-to-USB cable. Raspbian by default starts up a terminal on the UART and one can connect to it from a PC with a terminal program. So no USB keyboard and no TV is required.
Step 2: Enable the Serial Port
By default the serial port is configured to start up a console input/output. To be able to use the serial port to connect and talk to other devices , the serial port console login needs to be disabled. This used to be a procedure more or less straight forward. With the introduction of the Raspberry Pi 3 this has become somewhat confusing however.
On older models, including the Raspberry Pi Zero, There are two files that need to be edited. The following procedure is appropriate for Raspbian Wheezy OS.
The first one is
This file has the command to enable the login prompt and this needs to be disabled. Edit the file and move to the end of the file. You will see a line similar to
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
Disable it by adding a # character to the beginning (marked red below0. Save the file.
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
The second file to be edited is /boot/cmdline.txt
The contents of the file look like this
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
Remove all references to ttyAMA0 (marked in red above). The file will now look like this
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
Save the file and reboot,
sudo shutdown -r now
Using Raspbian Jessie, the Uart needs to be activated. Edit this file:
at the end of the file, add the following line:
disable the console login on /dev/ttyAMA0:
sudo systemctl stop serial-getty@ttyAMA0.servicesudo systemctl disable serial-getty@ttyAMA0.service
Reboot, done. Again, the Pi 3 is more complicated, see here.
Step 3: Prepare Hardware to connect the Raspberry Pi to the PV Inverter
The inverter has a RS232 port that needs to be connected to the Raspberry Pi. There are basically two possibilities:
- use a USB-RS232 cable, the simplest solution.
- use the Raspberry Pi UART and a Converter from 3.3V UART to RS232. Those converters can be purchased at very low cost, as low as 1 EUR per piece. They measure 9.4 x 15.9mm, rumor says they are so small they can be accommodated in a DSUB9 Plug. I haven’t tried it though.
Step 4: Test the SunEzy Communication Protocol
After some time of searching on the internet for wisdom how to pull data from the SunEzy 2800, I came across this Python module: https://pv.codeplex.com/. It describes the communication protocol in detail. Looking into the Python sources, one can immediately see that this is professionally written software. For me as a Python beginner it was clear I would use this module, study it and hopefully learn a lot from it. But first I have to verify that the communication protocol works with my Sunezy 2800.
As I had to wait for Raspberry Pi to arrive, I first connected the SunEzy to my PC using a USB-RS232 cable and verified that the Sunezy Control Software worked. It took some time though, this piece of software is thought to connect to and manage multiple inverters.
The first test without this software was to query the serial number from the Sunezy inverter. Sounds simple. Send some bytes to the inverter, and read some bytes back – for this purpose there are terminal programs available, like TeraTerm. This sequence – expressed as hexadecimal numbers is to be sent to the inverter:
aa aa 01 00 00 00 00 04 00 01 59
Unfortunately, when I open a terminal in TeraTerm, I can send only characters that are available on the keyboard. But already the first character to send is hexadecimal ‘aa’ (representation of the ASCII character number 170, or binary 10101010). The normal Alphabet is represented by ASCII codes between 32 and 127. Some language specific characters can be represented by values between 128 and 255, but not all values can be generated easily with the keyboard. Worse, values below 32 are control characters, for example LF (line feed, ASCII code 10) or CR (carriage return, ASCII code 13).
The solution to this is: use a Hex Editor like Pspad, save the hex string to a to a file, start TeraTerm, and send data from this file.
Playing with this method wasn’t satisfying because I had to connect the inverter with my PC with a 3m cable in that very small boxroom where the heating is.
Step 5 : Python test script
sudo pip install pyserial
sudo apt-get install pyserial
The package contains setup.py and additionally a test script, but the actual python module is identical to the original.
Step 6: Concept and Implementation of a data logging system with Python
At the beginning my experience with python was not very solid. So I didn’t trust my own scripts to run stable. When I start a script that is supposed to run all day, but it crashes at some time because of a bug, I would loose a lot of data until I realize the script doesn’t run anymore. Therefore I implemented a scheme where the script would collect data over 5 minutes and then terminate. If it crashes, I would loose data of a 5 minutes period only. A cron job can start the same script every 5 minutes.
a python script is started by a cron job every 5 minutes. The script will collect data from the inverter 10 times every 30 seconds, so its total run time is 4 minutes 30 seconds. At the end of the script the collected data are processed, and average, min and max values are stored. I store energy production, grid voltage, grid frequency, PV solar panels voltage and Raspberry Pi temperature in a data base.
The crontab entry looks like this:
*/5 means every 5 minutes
5-22 means between 5:00 am and 10:00 pm
* * * means every day / every month / every day of week
>/dev/null means all output (stdout) is diverted into the trash bin
2>&1 means error messages are diverted to stdout so go into the trash bin
implementation of the data logging system
data are stored in csv format in text files, i.e parameters are plain text, separated by commata.The set of data recorded each 5-minute period is stored in a file. This file has the format [week-of-year]_[year].csv.
As its name suggests, a new file will be generated for each week.
Step 7: Fresh Air – Fan Control
A fan controlled by a PWM signal depending on temperature. I implemented 8 ‘on’ stages of fan speed but the routine can be set up to use 1 on-stage only (on /off) as well.
The speed of a fan can be controlled by turning it on for some time and turning it off for another period of time. On average there will be a certain rpm (rounds per minute) rate depending on the relation between the on and the off times (the “duty cycle”). The frequency is of secondary importance. I have implemented the PWM signal with 50 Hz which works great with the fan that I am using. There is certainly a upper limit to it as the fan would not start to turn at all with a 50Hz / 10% PWM signal. It certainly would work at approximately 10% if we let it work for 2 seconds and turn it of for 18 seconds (i.e. a frequency of 0.05 Hz). I haven’t tested the PWM signal for such low frequencies however.
The actual software driver of the fan is a python script using the hardware PWM of the Raspberry Pi (GPIO 18). For this purpose I use the Python library wiringpi . The script sets up the PWM mode (2), adjusts range (1200) and clock (320) so that we get a 50Hz output frequency and then writes the duty cycle value according to a command line option, a number between 0 and 100. A value of 10 represents a duty cycle of 10%, that is a 2ms on-pulse followed by 18ms off time. A value of 60 would represent a 12ms on pulse followed by 8ms off time. The good news about the hardware PWM is that the pulsed signal continues on the PWM pin after the script has finished, and no software in the background has to take care that increases CPU load. The resulting script looks simple, although it took me quite some time to get there. The documentation of wiringpi is really bad.
On the hardware side, we have to consider the fact that a fan consumes between 50 to 100mA at a voltage at 5V or even 12V. The Raspberry Pi’s GPIO pins cannot deliver more than 2mA at 3.3V, as everybody knows (hopefully). A NPN transistor as current amplifier will do the switching. My fan operates at 5V, supplied by the Raspberry Pi’s power supply.