pvout_growatt.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 08 11:33:47 2014

@author: Lennart Kuhlmeier.

With help for modbus read examples from:
https://gist.github.com/Elwell/6418662

Follow production data here:
http://www.pvoutput.org/list.jsp?id=21951&sid=19826

R01: Minor bug fixes.
Mainly in the readout values.
Curl call to PVoutput updated so it now includes the power generation correctly (c1 = 0 instead of 1)
Information on the weather situation included in addoutput upload.
"""
import subprocess
from time import strftime
import time
from pyowm import OWM
from pymodbus.client.sync import ModbusSerialClient as ModbusClient

# READ VALUES FROM MODBUS SERIAL DEVICE (GROWATT INVERTER)
# choose the serial client
client = ModbusClient(method='rtu', port='/dev/ttyUSB0', baudrate=9600, stopbits=1, parity='N', bytesize=8, timeout=1)
client.connect()
rr = client.read_input_registers(1,44) #For debugging
print rr.registers

# The basic stuff is read not all is used but just added for later use
rr = client.read_input_registers(2,1) #Watts delivered by panels (DC side)
value=rr.registers
pv_watts=float(value[0])/10
rr = client.read_input_registers(3,1) # Volts on DC side
value=rr.registers
pv_volts=float(value[0])/10
rr = client.read_input_registers(4,1) # Amps on DC side??? Not sure.
value=rr.registers
pv_amps=float(value[0])/10
rr = client.read_input_registers(12,1) #watts delivered by inverter to net
value=rr.registers
out_watts=float(value[0])/10
rr = client.read_input_registers(13,1) # frequenzy of AC
value=rr.registers
ac_hz=float(value[0])/100
rr = client.read_input_registers(14,1) # volts on AC side delivered by inverter
value=rr.registers
ac_volts=float(value[0])/10
rr = client.read_input_registers(27,1) # Total energy production today
value=rr.registers
Wh_today=float(value[0])*100
rr = client.read_input_registers(29,1) # Total energy production in inervter storage
value=rr.registers
Wh_total=float(value[0])*100
# close the client
client.close()

# Retrieve current weather information (Requires the installation of pyowm. $ sudo apt-get install pyowm)
owm = OWM('your-API-key') # a Python wrapper around the OpenWeatherMap API
# See: http://openweathermap.org/appid
obs = owm.weather_at_coords(8.24736,56.08592) # input your own longitude,latitude
w = obs.get_weather()
w_stat= w.get_detailed_status()
t_date = format(strftime('%Y%m%d'))
t_time = format(strftime('%H:%M'))
w_stat= w.get_detailed_status()
temp = w.get_temperature(unit='celsius')
current_temp = temp['temp']
cloud_p = w.get_clouds()
my_com = ("Cloud coverage: %s percent" %cloud_p)
e_con=0 # Consumed kWh will be added later - Next raspberry pi project :o)
p_con=0  # Consumed kW will be added later - Next raspberry pi project :o)
com_str= ('%s with a cloud coverage of %s percent' % (w_stat,cloud_p))

# Upload the data read from Growatt inverter to pvoutput.org
# see for http://www.pvoutput.org/help.html detajls
# Curl is required for this action. Refer to: http://curl.haxx.se/
SYSTEMID="Your-system-ID"
APIKEY="Your-API-key"
#Live update data. To be sent every 5 min
cmd=('curl -d "d=%s" -d "t=%s" -d "v1=%s" -d "v2=%s" -d "v5=%s" -d "v6=%s" -d "c1=0" -H \
"X-Pvoutput-Apikey: %s" -H \
"X-Pvoutput-SystemId: %s" \
http://pvoutput.org/service/r2/addstatus.jsp'\
%(t_date, t_time,Wh_today, out_watts, current_temp, pv_volts,\
APIKEY,SYSTEMID))
ret = subprocess.call(cmd,shell=True)

time.sleep(30)

# End of day report update also performed each 5 min.
# This will overwrite daily report as a current status until the inverter shuts down at the end of the day
cmd=('curl -d "data=%s,%s,,,,,,,%s,,,,," -H \
"X-Pvoutput-Apikey: %s" -H \
"X-Pvoutput-SystemId: %s" http://pvoutput.org/service/r2/addoutput.jsp' \
%(t_date,Wh_today,com_str,\
APIKEY,SYSTEMID))
ret = subprocess.call(cmd,shell=True)

print 'pv_watts %s' %pv_watts
print 'pv_volts %s' %pv_volts
print 'pv_amps %s' %pv_amps
print 'out_watts %s' %out_watts
print 'ac_hz %s' %ac_hz
print 'ac_volts %s' %ac_volts
print 'Wh_today %s' %Wh_today
print 'Wh_total %s' %Wh_total

For testing the Modbus serial connection to the inverter:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 08 11:03:41 2014

@author: lku
"""
# import the server implementation
from pymodbus.client.sync import ModbusSerialClient as ModbusClient

# READ VALUES FROM MODBUS SERIAL DEVICE (GROWATT INVERTER)
# choose the serial client
client = ModbusClient(method='rtu', port='/dev/ttyUSB0', baudrate=9600, stopbits=1, parity='N', bytesize=8, timeout=1)
client.connect()
rr = client.read_input_registers(1,44)
#Try out this also:
#rr = client.read_input_registers(1,44,unit=1)
print rr.registers

# close the client
client.close()

7 thoughts on “pvout_growatt.py”

  1. It seems that the code is truncated at line 88 !!

    Can you provide the whole code either on the website or via a download?

    V/r
    Niels

  2. Btw.
    I get an error during execution:
    File “pvout_growatt.py”, line 83
    ^
    SyntaxError : EOL while scanning string literal

    1. There.
      I see that the python code in the post for some reason has an extra line in the cmd(stuff goes here). It should be:

      cmd=(‘curl -d “d=%s” -d “t=%s” -d “v1=%s” -d “v2=%s” -d “v5=%s” -d “v6=%s” -d “c1=0” -H \
      “X-Pvoutput-Apikey: %s” -H \
      “X-Pvoutput-SystemId: %s” \
      http://pvoutput.org/service/r2/addstatus.jsp‘\
      %(t_date, t_time,Wh_today, out_watts, current_temp, pv_volts,\
      APIKEY,SYSTEMID))

      and

      cmd=(‘curl -d “data=%s,%s,,,,,,,%s,,,,,” -H \
      “X-Pvoutput-Apikey: %s” -H \
      “X-Pvoutput-SystemId: %s” http://pvoutput.org/service/r2/addoutput.jsp‘ \
      %(t_date,Wh_today,com_str,\
      APIKEY,SYSTEMID))

      I.e. without any between the lines.

      1. Great… Thanks – that worked.
        Now I get this response
        ‘…line 36, in
        value=rr.registers
        AttributeError: ‘NoneType’ object has no attribute ‘registers’

        I think that my RS485 USB (FTDI) is not in contact with my Growatt TL-3000. I do get a good response from the USB485 connection on USB0 (dmesg | grep tty).

        I’m using these two interfaces:
        a. http://www.ebconnections.com/index.php/fr/cables-usb-rs485/cable-usb-rs485-fils-1-8m-chipset-ftdi-detail.html
        b. http://www.aliexpress.com/item/USB-2-0-to-TTL-RS485-Serial-Converter-Adapter-FTDI-FT232RL-SN75176-double-function-double-protection/583268610.html

        I’ve connected the inverter Pin 1 (-) to A and Pin 2(+) to B.
        I’ve also tried the opposite = same result 😐

        1. Yes. that was the same response I got with a faulty connection.
          dmesg | grep tty displays the system’s serial support, but I think the actual connection can still be faulty. There is really not much else to do than to hook it up to a PC and see if you can connect to you Pi using the serial port with e.g. Putty. When you can write in the command line of the Pi and see the message on you PC screen you know it works.

          You are sure that your inverter is Modbus? Mine is firmware 1.8 but I have been in contact with a guy who had 1.7 and he claimed that this is standard serial and got some perl script running to do the same stuff as the python code on my page. Knock through the menus of the inverter to see.

          Lastly. You may want to try out
          rr = client.read_input_registers(1,44,unit=1)
          print rr.registers

          which is as pr the documentation.
          http://pymodbus.readthedocs.org/en/latest/library/async-client.html?highlight=read_input_registers#pymodbus.client.async.ModbusClientProtocol.read_input_registers

          There might be slight differences in the Growatt protocol between versions I guess. But you should be pretty close to getting something working now 🙂

          Are you running as root and have ensured that root is member of dialout group (as pr. description in the blog)?

          FYI my initial try was also to connect via TTL/serial over the Pi’s GPIO’s. But I never got that working. Not the same as it is not possible though 🙂 I just grew tied of worrying about questioning if RX/TX were being connected correctly.

          Lennart

        2. Also have a look at the debug code bit on the bottom of the page here.
          This may be more handy to work with until you get 44 numbers dumped from the inverter.

Leave a Reply

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

HTML Snippets Powered By : XYZScripts.com