Jump to content

ME3000SP RS485/Modbus


GAC
 Share

Recommended Posts

Hi, I am trying to read data from the inverter via rs485/modbus but not having much luck, has anyone done this successfully?

What I've tried so far:-

I've set the communication settings (presumably rs485)  to an address of 3 with 9600,8,N,1 (Address is confirmed in System Information)

I presume the connector to use is the 2 pin 485s, the plug had a label saying TX- TX+, I've connected this to an RS485-USB converter +to+ -to- (also tried putting a termination resistor on

and reversing connections, just in case) USB is then plugged into a raspberry pi running node-red with the node-red-contrib-modbus nodes.

I have a node-red flow set up with a modbus getter using the comms params above and trying to read 64 input registers starting at 518 (which seems where the interesting data is

according to the SOFARSOLAR modbus spec pdf).

Nothing happens! (see error messages below)

I should say I'm successfully using a similar setup to read data from an Eastron energy meter

Any ideas help gratefully received.

Thanks

 

3/15/2020, 9:01:19 PMnode: 2b51544c.0fb72cmsg : error
"Error: FSM Not Ready To Read At State init"
3/15/2020, 9:01:21 PMnode: 2b51544c.0fb72cmsg : string[65]
"FSM Reset On State {"value":"failed","actions":[],"changed":true}"
Link to comment
Share on other sites

Update, the communication side of it works ok as I have got a python program talking to the inverter successfully (not decoded the data though).

So it must be some issue with node-red. I would still like to use node-red but will pursue the python route in the meantime.

P.S. I should have put SOFAR ME3000SP in the title.

Link to comment
Share on other sites

  • 1 month later...

Did you get very far with this?

I do something similar with mine, I wrote a Python script to query the ME3000SP using their modbus protocol.  It works OK in general but does throw up spurious data sometimes - but that might just be my setup using an RS485 to Ethernet adapter, so there could be some interference corrupting the data on occasion.

My script publishes to MQTT (for consumption in Node-Red).

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pyModbusTCP.client import ModbusClient
import time
import struct
import paho.mqtt.client as mqtt
import bitstring


SERVER_HOST = "192.168.1.119"
SERVER_PORT = 10001
SLEEP_TIME = 2


c = ModbusClient()

c.debug(True)
c.host(SERVER_HOST)
c.port(SERVER_PORT)
c.mode(2)
c.timeout(5)
c.auto_open(True)
c.auto_close(True)

runningstate = "unknown"
voltageac = "unknown"
currentac = "unknown"
frequencyac = "unknown"
batterypower = "unknown"
batteryvoltage = "unknown"
batterycurrent = "unknown"
batterycapacity = "unknown"
batterytemperature = "unknown"
invertertemperature = "unknown"
feedinoutpower = "unknown"
loadpower = "unknown"
outputinoutpower = "unknown"
generationpower = "unknown"
inverteralertmessage = "unknown"
batterycycles = "unknown"
selfconsumption = "unknown"

gooddata = True

c._recv_mbus()

print("sofarsolar running at " + time.strftime('%d/%m/%Y %H:%M:%S'))

print("getting 512 0x0200")
reg1 = c.read_holding_registers(512, 1)
if reg1:
        print("reg 512 0x0200 running state: " + str(reg1))
        runningstates=["WaitState","CheckState","NormalState","CheckDischargeState","DischargeState","EPSState","FaultState","PermanentState"]
        if int(str(reg1[0])) <= 7:
                runningstate = runningstates[reg1[0]]
                print("runningstate = " + str(runningstate))
        else:
                gooddata = False
                runningstate = "unknown"
                print("runningstate = unknown")

if gooddata:
        time.sleep(SLEEP_TIME)
        print("getting 518 0x0206")
        reg2 = c.read_holding_registers(518, 1)
        if reg2:
                print("reg 518 0x0206 voltage ac: " + str(reg2))
                voltageac = reg2[0] * 0.1
                print("voltageac = " + str(voltageac) + "VAC")
        time.sleep(SLEEP_TIME)
        print("getting 519 0x0207")
        reg3 = c.read_holding_registers(519, 1)
        if reg3:
                print("reg 519 0x0207 current ac: " + str(reg3))
                currentac = bitstring.Bits(uint=reg3[0], length=16)
                currentac = currentac.unpack('int')[0] * 0.01
                print("currentac = " + str(currentac) + "A")
        time.sleep(SLEEP_TIME)
        print("getting 524 0x020C")
        reg4 = c.read_holding_registers(524, 1)
        if reg4:
                print("reg 524 0x020C frequency ac: " + str(reg4))
                frequencyac = reg4[0] * 0.01
                print("frequencyac = " + str(frequencyac) + "Hz")
        time.sleep(SLEEP_TIME)
        print("getting 525 0x020D")
        reg5 = c.read_holding_registers(525, 1)
        if reg5:
                print("reg 525 0x020D battery charge discharge power: " + str(reg5))
                batterypower = bitstring.Bits(uint=reg5[0], length=16)
                batterypower = batterypower.unpack('int')[0] * 0.01
                print("batterypower = " + str(batterypower) + "kW")
        time.sleep(SLEEP_TIME)
        print("getting 526 0x020E")
        reg6 = c.read_holding_registers(526, 1)
        if reg6:
                print("reg 526 0x020E battery voltage: " + str(reg6))
                batteryvoltage = reg6[0] * 0.01 #docs say 0.1 but seems wrong
                print("batteryvoltage = " + str(batteryvoltage) + "VDC")
        time.sleep(SLEEP_TIME)
        print("getting 527 0x020F")
        reg7 = c.read_holding_registers(527, 1)
        if reg7:
                print("reg 527 0x020F battery charge discharge current: " + str(reg7))
                batterycurrent = bitstring.Bits(uint=reg7[0], length=16)
                batterycurrent = batterycurrent.unpack('int')[0] * 0.01
                print("batterycurrent = " + str(batterycurrent) + "A")
        time.sleep(SLEEP_TIME)
        print("getting 528 0x0210")
        reg8 = c.read_holding_registers(528, 1)
        if reg8:
                print("reg 528 0x0210 battery capacity: " + str(reg8))
                batterycapacity = reg8[0] 
                print("batterycapacity = " + str(batterycapacity) + "%")
        time.sleep(SLEEP_TIME)
        print("getting 529 0x0211")
        reg9 = c.read_holding_registers(529, 1)
        if reg9:
                print("reg 529 0x0211 battery temperature: " + str(reg9))
                batterytemperature = reg9[0]
                print("batterytemperature = " + str(batterytemperature) + "C")
        time.sleep(SLEEP_TIME)
        print("getting 530 0x0212")
        reg10 = c.read_holding_registers(530, 1)
        if reg10:
                print("reg 530 0x0212 feed in / out power: " + str(reg10))
                feedinoutpower = bitstring.Bits(uint=reg10[0], length=16)
                feedinoutpower = feedinoutpower.unpack('int')[0] * 0.01
                print("feedinoutpower = " + str(feedinoutpower) + "kW")
        time.sleep(SLEEP_TIME)
        print("getting 531 0x0213")
        reg11 = c.read_holding_registers(531, 1)
        if reg11:
                print("reg 531 0x0212 load power: " + str(reg11))
                loadpower = reg11[0] * 0.01
                print("loadpower = " + str(loadpower) + "kW")
        time.sleep(SLEEP_TIME)
        print("getting 532 0x0214")
        reg12 = c.read_holding_registers(532, 1)
        if reg12:
                print("reg 532 0x0214 output in / out power: " + str(reg12))
                outputinoutpower = bitstring.Bits(uint=reg12[0], length=16)
                outputinoutpower = outputinoutpower.unpack('int')[0] * 0.01
                print("outputinoutpower = " + str(outputinoutpower) + "kW")
        time.sleep(SLEEP_TIME)
        print("getting 533 0x0215")
        reg13 = c.read_holding_registers(533, 1)
        if reg13:
                print("reg 533 0x0215 generation power: " + str(reg13))
                generationpower = reg13[0] * 0.01
                print("generationpower = " + str(generationpower) + "kW")
        time.sleep(SLEEP_TIME)
        print("getting 554 0x022A")
        reg14 = c.read_holding_registers(554, 1)
        if reg14:
                print("reg 554 0x022A countdown timer: " + str(reg14))
                countdowntimer = reg14[0]
                print("countdowntimer = " + str(countdowntimer) + "s")
        time.sleep(SLEEP_TIME)
        print("getting 555 0x022B")
        reg15 = c.read_holding_registers(555, 1)
        if reg15:
                print("reg 555 0x022B inverter alert message: " + str(reg15))
                inverteralertmessage = reg15[0] 
                print("inverteralertmessage = " + str(inverteralertmessage)) 
        time.sleep(SLEEP_TIME)
        print("getting 556 0x022C")
        reg16 = c.read_holding_registers(556, 1)
        if reg16:
                print("reg 556 0x022C battery cycles: " + str(reg16))
                batterycycles = reg16[0]              
                print("batterycycles = " + str(batterycycles))
        time.sleep(SLEEP_TIME)
        print("getting 566 0x0236")
        reg17 = c.read_holding_registers(566, 1)
        if reg17:
                print("reg 566 0x0236 generation current: " + str(reg17))#self consumption?
                selfconsumption = reg17[0]
                print("selfconsumption = " + str(selfconsumption) + "%")
        time.sleep(SLEEP_TIME)
        print("getting 568 0x0238")
        reg18 = c.read_holding_registers(568, 1)
        if reg18:
                print("reg 568 0x0238 inverter temperature: " + str(reg18))
                invertertemperature = reg18[0]
                invertertemperature = bitstring.Bits(uint=reg18[0], length=16)
                invertertemperature = invertertemperature.unpack('int')[0]
                print("invertertemperature = " + str(invertertemperature) + "C")
        mqttc = mqtt.Client("client")
        mqttc.username_pw_set("user","password")
        mqttc.connect("localhost")
        mqttc.publish("/sofarsolar", "{ \"runningstate\" : \"" + str(runningstate) + "\", \"voltageac\" : \"" + str(voltageac) + "\", \"currentac\" : \"" + str(currentac) + "\", \"frequencyac\" : \"" + str(frequencyac) + "\", \"batterypower\" : \"" + str(batterypower) + "\", \"batteryvoltage\" : \"" + str(batteryvoltage) + "\", \"batterycurrent\" : \"" + str(batterycurrent) + "\", \"batterycapacity\" : \"" + str(batterycapacity) + "\", \"batterytemperature\" : \"" + str(batterytemperature) + "\", \"feedinoutpower\" : \"" + str(feedinoutpower) + "\", \"invertertemperature\" : \"" + str(invertertemperature) + "\", \"loadpower\" : \"" + str(loadpower) + "\", \"outputinoutpower\" : \"" + str(outputinoutpower) + "\", \"generationpower\" : \"" + str(generationpower) + "\", \"inverteralertmessage\" : \"" + str(inverteralertmessage)+ "\", \"selfconsumption\" : \"" + str(selfconsumption) + "\", \"batterycycles\" : \"" + str(batterycycles) + "\" }")
        mqttc.loop(2)


#        reg = c.read_holding_registers(557, 1)
#        if reg:
#                print("reg 557 inv bus voltage: " + str(reg))
#        c.close()

#        reg = c.read_holding_registers(558, 1)
#        if reg:
#                print("reg 558 llc bus voltage: " + str(reg))               
#        c.close()

#        reg = c.read_holding_registers(559, 1)
#        if reg:
#                print("reg 559 buck current: " + str(reg))               
#        c.close()

#        reg = c.read_holding_registers(560, 1)
#        if reg:
#                print("reg 560 grid r voltage: " + str(reg))               
#        c.close()

#        reg = c.read_holding_registers(561, 1)
#        if reg:
#                print("reg 561 grid r current: " + str(reg))               
#        c.close()

 

Link to comment
Share on other sites

  • 2 months later...

Sorry I've only just seen this:-

The main issue I have is the battery capacity jumps from 89% to 99%, i.e. it doesn't show intermediate values in this range, the battery current is updated continually so I don't suspect a read problem.

This is my code, running on a pi3 connected to Sofar with a USB<>RS485 converter

#!/usr/bin/python

import minimalmodbus
from time import sleep
import paho.mqtt.client as mqtt

ME3000 = minimalmodbus.Instrument('/dev/ttyUSB1', 2)
ME3000.serial.baudrate = 9600
ME3000.serial.bytesize = 8
ME3000.serial.parity = minimalmodbus.serial.PARITY_NONE
ME3000.serial.stopbits = 1
ME3000.serial.timeout = 1
ME3000.debug = False
ME3000.mode = minimalmodbus.MODE_RTU
#print ME3000
#mqtt stuff
mqttPubName="sofar" # publish data
client =mqtt.Client("", True, None, mqtt.MQTTv31)
client.username_pw_set("user",password="pass")
client.connect("192.168.0.61",1883,60)

# addresses of data
batCapacity=0x0210
batVoltage=0x20E
batCurrent=0x020F #signed

#------------------------------------------------------
def getReg(addr,dec,signed):  # get one 16bit register to dec decimal places, signed determines if signed or unsigned integer
    try:
        data=ME3000.read_register(addr,dec,3,signed)
        if data!=None:
            return data
    except IOError:
        print("Failed to read from instrument")
#------------------------------------------------------
            
while True:
    cur = getReg(batCurrent,2,True)
    sleep(.2)
    cap = getReg(batCapacity,0,False)
    sleep(.2)
    vol = getReg(batVoltage,2,False)
    sleep(.2)
    client.publish(mqttPubName+"/capacity",cap)
    client.publish(mqttPubName+"/amps",cur)
    client.publish(mqttPubName+"/volts",vol)
    sleep(5)


 

Link to comment
Share on other sites

  • 3 weeks later...

I am trying to get a RPi Z to talk to my ME3000SP unit but not getting anywhere. Do you need to have the inverter in Passive mode for 485 communications to work correctly? Looking to control unit so that I can take advantage of negative electricity prices. Currently have other systems to switch over with pricing but battery inverter currently isn't controlled remotely.

Any assistance is greatly appreciated.

Link to comment
Share on other sites

  • 1 month later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...