question

dale-shacklock avatar image
dale-shacklock asked

Call MPPT 75/10 solar stats with Pi

Hi

Little bit of a noob but hoping someone can guide me or point me to an already existing page...


Currently using a Pi 4 which is powered by solar and running Raspbian OS with CCTV software (Nx Witness)...

what I'm wanting to know is, can I create a script that will allow the Pi to send a ping/call to the MPPT 75/10 (via USB) and in turn the MPPT fires back the battery, load and incoming solar stats....im then wanting to use these stats to monitor the remote units.

Our software doesn't work along side with the Venus images etc


Thanks Guys

MPPT SmartSolarRaspberry Pi
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

3 Answers
Matthias Lange - DE avatar image
Matthias Lange - DE answered ·

There are documents available with the protocols:
https://www.victronenergy.com/support-and-downloads/technical-information
(scroll down to VE.direct)

And there is the modifications space:
https://community.victronenergy.com/spaces/31/index.html

2 comments
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

dale-shacklock avatar image dale-shacklock commented ·

Hey mate

Ive had a look and i see there are projects similar however none that are able to point me in the right direction of just a simple call action.


I am a little noob at this and ideally we'd like a simple text command we send to the Smart Controller and receive a response. Either by SSH or directly from the Pi itself

0 Likes 0 ·
Erik Sporns avatar image Erik Sporns dale-shacklock commented ·

just as an idea: https://github.com/victronenergy/venus/wiki/install-venus-packages-on-Debian

not full fledged venus on the pi and still full solar logging and you could keep the cctv software.

0 Likes 0 ·
Mike Dorsett avatar image
Mike Dorsett answered ·

This is easily done using the VE-direct/usb adapter to the pi, and can be programed in python, referring to the VE direct hex protocol. Or you can just read the ASCII stream that is continually output from the MPPT. If you just want to read the parameters, the latter is the easiest - but it does mean a lot of string processing in your program.

2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

Mike Dorsett avatar image
Mike Dorsett answered ·

This is the code I use, and you are welcome to use it as an example:

com2 = serial.Serial('/dev/ttyUSB0', baudrate = 19200,parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS)

def long_to_short(long_byes):
temp = float(long_byes)
hi_byte = int(temp/65536)
lo_byte = int(temp-65536*hi_byte)
#print("152",long_byes,hi_byte,lo_byte)
return(hi_byte,lo_byte)

def readbytes2():

rxstring = ""
try:
while int(com2.inWaiting()) > 0:
byte1 =(ord(com2.read(1)))
rxstring +=(chr(byte1))

except Exception as e:
print("rxmsg",e,com2.inwaiting())

#print(rxstring)
nl = rxstring.find("PPV")
fl = rxstring.find(chr(0x09),nl) #Find the tab after "PPV"
nl2 = rxstring.find(chr(0x0d),fl) # find the new line after the data
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("PPV",pvp3)

try:
ppv = float(pvp3)
pvp_h,pvp_l = long_to_short(ppv)
except Exception as e:
print(97,pvp3,e)

# if fxfield == "V":
nl = rxstring.find(chr(0x0d)+chr(0x0a)+"V")
fl = rxstring.find(chr(0x09),nl) #Find the tab after "V"
nl2 = rxstring.find(chr(0x0d),fl) # find the new line after the data
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("V",pvp3)
#789 sf 10 uint16
try:
ppv = float(pvp3)
pvp_h,pvp_l = long_to_short(ppv)

except Exception as e:
print(112,pvp3,e)


# if fxfield == "I":
nl = rxstring.find(chr(0x0d)+chr(0x0a)+"I")
fl = rxstring.find(chr(0x09),nl)
nl2 = rxstring.find(chr(0x0d),fl)
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("I",pvp3)

try:
ppv = float(pvp3)
if ppv <0:
ppv+=32768
pvp_h,pvp_l = long_to_short(ppv)

except Exception as e:
print(131,pvp3,e)

nl = rxstring.find("H19")
fl = rxstring.find(chr(0x09),nl)
nl2 = rxstring.find(chr(0x0d),fl)
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("Yield tot",pvp3)

try:
ppv = float(pvp3)
pvp_h,pvp_l = long_to_short(ppv)

except Exception as e:
print(145,pvp3,e)


# if fxfield == "H20":
nl = rxstring.find("H20")
fl = rxstring.find(chr(0x09),nl)
nl2 = rxstring.find(chr(0x0d),fl) # find the new line after the data
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("Yield",pvp3)

try:
ppv = float(pvp3)
pvp_h,pvp_l = long_to_short(ppv)

except Exception as e:
print(165,pvp3,e)


nl = rxstring.find("H21")
fl = rxstring.find(chr(0x09),nl)
nl2 = rxstring.find(chr(0x0d),fl) # find the new line after the data
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("Max power",pvp3)

try:
ppv = float(pvp3)
pvp_h,pvp_l = long_to_short(ppv)

except Exception as e:
print(174,pvp3,e)

nl = rxstring.find("H22")
fl = rxstring.find(chr(0x09),nl)
nl2 = rxstring.find(chr(0x0d),fl) # find the new line after the data
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("Yield -24h",pvp3)
#772 sf 10 int16
try:
ppv = float(pvp3)
pvp_h,pvp_l = long_to_short(ppv)

except Exception as e:
print(139,pvp3,e)

nl = rxstring.find("H23")
fl = rxstring.find(chr(0x09),nl)
nl2 = rxstring.find(chr(0x0d),fl) # find the new line after the data
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("Max power -24h",pvp3)

try:
ppv = float(pvp3)
pvp_h,pvp_l = long_to_short(ppv)

except Exception as e:
print(202,pvp3,e)

nl = rxstring.find("ERR")
fl = rxstring.find(chr(0x09),nl)
nl2 = rxstring.find(chr(0x0d),fl) # find the new line after the data
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("Error ",pvp3)

try:
ppv = float(pvp3)
pvp_h,pvp_l = long_to_short(ppv)

except Exception as e:
print(202,pvp3,e)

# if fxfield == "VPV":
nl = rxstring.find("VPV")
fl = rxstring.find(chr(0x09),nl)
nl2 = rxstring.find(chr(0x0d),fl) # find the new line after the data
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("VPV",pvp3)

try:
ppv = float(pvp3)
pvp_h,pvp_l = long_to_short(ppv)

except Exception as e:
print(156,pvp3,e)


nl = rxstring.find("HSDS")
fl = rxstring.find(chr(0x09),nl)
nl2 = rxstring.find(chr(0x0d),fl) # find the new line after the data
if nl != -1:
pvp3=rxstring[fl+1:nl2+1]
print("Day No",pvp3)
#772 sf 10 int16
try:
ppv = float(pvp3)
pvp_h,pvp_l = long_to_short(ppv)

except Exception as e:
print(156,pvp3,e)



Not too pretty, and no warranty. ppv is used for the extracted variable in each block, so you need to do something wiht it before moving onto the next block. Have fun. There is no "simple" call to do this. This code decodes the continuous ASCII output from the usb com port.

2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.