diy solar

diy solar

Off-grid Solar / Battery monitoring and control freeware

I'm now trying to get the inverter up and running.
I get now the message: Epever Tech co., Ltd', 1: 'EPEVER1200W-11', 2: 'V1.00+V1.00
but I have no clue how to get the registers with Data.

Used a monitoring tool where it displayed loads of data, but somehow I don't manage to put that in the correct request.

Added the log files, hope someone can support or point me in the correct direction.

Thanks
 

Attachments

  • ip1500.zip
    34.1 KB · Views: 14
if it is the cable what is delivered with de Tracer, you should use the 1A driver version.
when all is installed you should have /dev/ttyXRUSB0.
Follow the instruction on: Github and all will be fine.
when you still have a issue do the TIP in line 32 and send the dmesg
Thanks wikkum! It turned out to be the latest module (5.4.49) was missing build files. Running rpi-source generated the missing folder/files, then I was finally able to compile the driver. Day 4 of the venture into Linux. Tell me it gets easier... lol
 
I'm now trying to get the inverter up and running.
I get now the message: Epever Tech co., Ltd', 1: 'EPEVER1200W-11', 2: 'V1.00+V1.00
but I have no clue how to get the registers with Data.

Used a monitoring tool where it displayed loads of data, but somehow I don't manage to put that in the correct request.

Added the log files, hope someone can support or point me in the correct direction.

Thanks
This might help?
 
This might help?
Thanks will try that this weekend and yes it will get easier xD

First I have to reposition my Solar Panels, if I check Grafana now during those sunny days I'm sure I can improve it to get more out of it.

will keep you posted
 
Reading the serial data from a Renogy wanderer.

To get the $20 Wanderer 10a Li that I used to talk to a Pi, I had to make my own cable, as there is nothing I could find off the shelf. So buy yourself a RJ crimper and a bag of 6 pin RJ12 network jacks. Its all cheap on Amazon. Earlier, I tried filing down an RJ45 (8 pin) jack to fit, but it was very unreliable.


This is a closeup of my prototype.

You can see the cable colors in the RJ12 jack, so strip out an old RJ45 cable and make what you see below. Test each Pin connection with a circuit tester. I didnt have a DB9 breakout board at the time (which I recommend), so I soldered directly to the pins On the RS232->USB adaptor.

RJ pin 1 Orange -> DB9 Pin 2
RJ Pin 2 Light Green -> DB9 Pin 3
RJ Pin 3 Blue -> DB9 Pin 5

Your cable colors may be different, but the pinout is the same.
I’ll post the Python code I used on my GItHub page. See the link below.

04508308-E38B-47D5-AF25-35BE4BA4904F.jpeg
 
Last edited:
Joe,
In an effort to teach myself Python, I've taken a stab at modifying your getChargeryData program to be compatible with the latest Chargery firmware which follows the v1.25 serial protocol, adding internal resistance readings for each cell among other things. Most of the new readings are in a Command 58 string, which is only transmitted during a mode change from Charge to Discharge, or vice versa. Instead of waiting around for a mode change to update the BMS_A file, I put the Command 58 readings in a separate BMS_B file. I created a few new defs for the new readings. The biggest addition was utilizing the checksum and data length. Lastly, I added a "-t" sys argument to use test strings for troubleshooting if you're not connected to the BMS. You just have to jumper Tx to Rx on the USBtoRS232 cable (making a loopback circuit).

I tried to mimic your programming style, so hopefully it'll be easy to follow. Below are the resulting prom files. Would you mind taking a look and let me know how badly i butchered this new (to me) language? Looks like .py attachments aren't allowed here. I can email the modified program or do a pull request. Any constructive criticisms appreciated!

Code:
BMS_A{mode="CellNum1"} 3.325
BMS_A{mode="CellNum2"} 3.332
BMS_A{mode="CellNum3"} 3.332
BMS_A{mode="CellNum4"} 3.33
BMS_A{mode="CellNum5"} 3.331
BMS_A{mode="CellNum6"} 3.332
BMS_A{mode="CellNum7"} 3.334
BMS_A{mode="CellNum8"} 3.329
BMS_A{mode="CellNum9"} 3.336
BMS_A{mode="CellNum10"} 3.33
BMS_A{mode="CellNum11"} 3.333
BMS_A{mode="CellNum12"} 3.326
BMS_A{mode="CellNum13"} 3.334
BMS_A{mode="CellNum14"} 3.323
BMS_A{mode="CellNum15"} 3.343
BMS_A{mode="CellNum16"} 3.324
BMS_A{mode="aggVolts"} 53.29
BMS_A{mode="Wh"} 47578.742
BMS_A{mode="Ah"} 922.723
BMS_A{mode="current"} 22.8
BMS_A{mode="maxVolts"} 3.62
BMS_A{mode="modeInt", myStr="Charge"} 1
BMS_A{mode="temp1"} 13.1
BMS_A{mode="temp2"} 13.2
BMS_A{mode="SOC"} 91

Code:
BMS_B{mode="CellNum1"} 0.1
BMS_B{mode="CellNum2"} 0.3
BMS_B{mode="CellNum3"} 0.3
BMS_B{mode="CellNum4"} 0.3
BMS_B{mode="CellNum5"} 0.2
BMS_B{mode="CellNum6"} 0.3
BMS_B{mode="CellNum7"} 0.0
BMS_B{mode="CellNum8"} 0.0
BMS_B{mode="CellNum9"} 0.1
BMS_B{mode="CellNum10"} 0.1
BMS_B{mode="CellNum11"} 0.1
BMS_B{mode="CellNum12"} 0.0
BMS_B{mode="CellNum13"} 0.5
BMS_B{mode="CellNum14"} 0.2
BMS_B{mode="CellNum15"} 0.3
BMS_B{mode="CellNum16"} 0.3
BMS_B{mode="aggIR"} 3.1
BMS_B{mode="current1"} 22.8
BMS_B{mode="modeInt", myStr="Charge"} 1
 
That looks great, thanks for all the hard work. let's make sure the code at GitHub/solarshed gets updated with your changes. Do you want to msg me the code mods or post them here?
Joe.

Joe,
In an effort to teach myself Python, I've taken a stab at modifying your getChargeryData program to be compatible with the latest Chargery firmware which follows the v1.25 serial protocol, adding internal resistance readings for each cell among other things.
 
This project has been very rewarding seeing others get their own systems up and running. If you want to try something similar on a minimal budget, I typically run in all my data collecting and presentation (Grafana) on a Pi Zero ($25), plugged into (for power) the USB socket on the Renogy Wanderer (or device Im monitoring). It monitors the Wanderer and collects the Chargery BMS data, DC data from the Shunt, as well as running Grafana/Prometheus/node_exporter on my Mobile 24v A123 LifePO4 test harness battery (where I do all my experiments). Its truly amazing you can do so much on one small device. You have to respect its limits, but it is all possible.

If you use the USB Pi Zero adaptor like I have (which I highly recommend, see image below) you need to modify the USB Enclosure to fix problems with the onboard PI USB sockets, which by default it disables to enable SSH. Let me know if you go this route and Ill post the details on how to fix that. Joe.

This is the adapter I use.

771D69B3-BC82-46ED-B1CD-94C2E3CD4B31.jpegB68AA505-121F-4A8A-8C1B-4BCDEFA52000.png
 
That looks great, thanks for all the hard work. let's make sure the code at GitHub/solarshed gets updated with your changes. Do you want to msg me the code mods or post them here?
Joe.

The complete sketch exceeded the 10k character limit here, so here's the first half of the revised code:

Code:
#!/usr/bin/env python3

# getChargeryData.py
# Description: open RS232 serial port and read Chargery BMS data.
# Output data in a format to be consumed by nodeexporter/prometheus/grafana
# in folder /ramdisk
# v0.4b 5-16-20 Joe Elliott joe@inetd.com
# modified 2-July-20 cass3825 for new protocol compatibility
# Protocol at http://chargery.com/uploadFiles/bms24_additional_protocol%20V1.25.pdf

import serial
import sys, os, io
import time
import binascii

devName='/dev/ttyUSB0'

modeList= ["Discharge", "Charge", "Storage"]
gotCellData = False;
gotSysData  = False;
gotIRData   = False;
debug=False
test=False

if (len(sys.argv) > 1):
        if (sys.argv[1] == "-d"):
                debug=True
                print("sys.argv[1]: Debug: enabled")
        if (sys.argv[1] == "-t"):
                debug=True
                print("sys.argv[1]: Test Data: enabled")
if (len(sys.argv) > 2):
        if (sys.argv[2] == "-d"):
                debug=True
                print("sys.argv[2]: Debug: enabled")
        if (sys.argv[2] == "-t"):
                test=True
                print("sys.argv[2]: Test Data: enabled")

def bin2hex(str1):
        bytes_str = bytes(str1)
        return binascii.hexlify(bytes_str)

def get_voltage_value(byte1, byte2):
        return float((float(byte1 * 256) + float(byte2)) / 1000)

def get_current_value(byte1, byte2):
        return float((float(byte1 * 256) + float(byte2)) / 10)

def get_temp_value(byte1, byte2):
        return float((float(byte1 * 256) + float(byte2)) / 10)

def get_xh_value(byte1, byte2, byte3, byte4):
        return float((float(byte1) + (float(byte2) * 256) + (float(byte3) * 256 * 256) + (float(byte4) * 256 * 256 * 256)) / 1000)

def get_imped_value(byte1, byte2):
        return float((float(byte2 * 256) + float(byte1)) / 10) # note byte swap order

def getCellData(fileObj, hexLine, strLen):
        decStrLen = len(hexLine)
        minLen = 44     # minimal bytes for the 8s inc header (each byte is 2 chars)
        dataStart = 0   # cell voltage data starts at byte 9 in 2 byte chunks (hi-lo) was 8
        cellNum = 1
        aggVolts = 0    # total voltage of the battery
        global gotCellData

        if (debug): print("getCellData: called - ", hexLine)

#        if (debug):
#                header  = hexLine[0:4]          # header
#                command = hexLine[0:2]          # command
#                dataLen = hexLine[2:4]          # data length
#                print("header:", header)
#                print("command:", command)
#                print("dataLen:", int(dataLen, 16), "bytes")

        if (decStrLen < strLen) or (decStrLen < minLen):
                if (debug): print("Truncated cell block - len:", len(hexLine), "Expected:", strLen)
                return(True)
        else:
                if (debug): print("hexLine len", len(hexLine))

        for cell in range(dataStart, decStrLen-18, 4): # incorporate datalength for variable cell count
                cellVolts = get_voltage_value(int(hexLine[cell:cell+2], 16), int(hexLine[cell+2:cell+4], 16))
                if (debug): print("Cell ", cellNum, ":", cellVolts, "v")
                # format the data for node_exporter to read into prometheus
                #valName  = "mode={}{}".format("CellNum", cellNum)
                valName  = "mode=\"CellNum" + str(cellNum) + "\""
                valName = "{" + valName + "}"
                dataStr  = f"BMS_A{valName} {cellVolts}"
                print(dataStr, file=fileObj)

                aggVolts += cellVolts
                cellNum += 1

        aggVolts = "{:4.2f}".format(aggVolts)
        valName  = "mode=\"aggVolts\""
        valName  = "{" + valName + "}"
        dataStr  = f"BMS_A{valName} {aggVolts}"
        print(dataStr, file=fileObj)

#        soc = int(hexLine[cell], 16)
        Wh = get_xh_value(int(hexLine[cell+4:cell+6], 16), int(hexLine[cell+6:cell+8], 16), int(hexLine[cell+8:cell+10], 16), int(hexLine[cell+10:cell+12], 16))
        valName  = "mode=\"Wh\""
        valName = "{" + valName + "}"
        dataStr  = f"BMS_A{valName} {Wh}"
        print(dataStr, file=fileObj)

        Ah = get_xh_value(int(hexLine[cell+12:cell+14], 16), int(hexLine[cell+14:cell+16], 16), int(hexLine[cell+16:cell+18], 16), int(hexLine[cell+18:cell+20], 16))
        valName  = "mode=\"Ah\""
        valName = "{" + valName + "}"
        dataStr  = f"BMS_A{valName} {Ah}"
        print(dataStr, file=fileObj)

        if (debug):
                print("Battery Wh:", Wh, "Wh")
                print("Battery Ah:", Ah, "Ah")
#                print("Checksum:", int(hexLine[cell+16:cell+18], 16))
                print("Battery voltage:", aggVolts, "v")

        gotCellData = True;
        return(False)

def getSysData(fileObj, hexLine, strLen):
        decStrLen = len(hexLine)
        dataStart = 4   # data starts at byte 8 in 2 byte chunks (hi-lo)
        minLen = 20     # minimal bytes inc header (each byte is 2 chars)
        global gotSysData

        if (debug): print("getSysData: called - ", hexLine)

        if (decStrLen < strLen) or (decStrLen < minLen):
                if (debug): print("Truncated system block - len:", len(hexLine), "Expected:", strLen)
                return(True)
        else:
                if (debug): print("hexLine len", len(hexLine))

        # first 3 fields for debug only)
#        header     = hexLine[0:4]       # header
#        command    = hexLine[0:2]       # command
#        dataLen    = hexLine[2:4]       # data length

        endVolt_hi = hexLine[0:2]       # End voltage of cell
        endVolt_lo = hexLine[2:4]       # End voltage of cell
        mode       = hexLine[4:6]       # Current mode
        amps_hi    = hexLine[6:8]       # Current amps
        amps_lo    = hexLine[8:10]      # Current amps
        temp1_hi   = hexLine[10:12]     # Temp 1
        temp1_lo   = hexLine[12:14]     # Temp 1
        temp2_hi   = hexLine[14:16]     # Temp 2
        temp2_lo   = hexLine[16:18]     # Temp 2
        soc        = hexLine[18:20]     # SOC
        chksum     = hexLine[20:22]     # Checksum

        maxVolts = get_voltage_value(int(endVolt_hi, 16), int(endVolt_lo, 16))
        currentFlow = get_current_value(int(amps_hi, 16), int(amps_lo, 16))
        modeName = modeList[int(mode, 16)]
        modeInt = int(mode, 16)
        temp1 = get_temp_value(int(temp1_hi, 16), int(temp1_lo, 16))
        temp2 = get_temp_value(int(temp2_hi, 16), int(temp2_lo, 16))
        socInt = int(soc, 16)

        if (debug):
#                print("dataLen:", int(dataLen, 16), "bytes")
                print("End voltage of cell:",  maxVolts, "v")
                print("mode:", modeInt, modeName)
                print("Current:", currentFlow, "A")
                print("Temp 1:", temp1, "c, ", temp1 * 9 / 5 + 32, "f")
                print("Temp 2:", temp2, "c, ", temp2 * 9 / 5 + 32, "f")
                print("SOC:", socInt, "%")
                print("Checksum:", int(chksum, 16))

        if (int(mode) == 0):
                currentFlow = currentFlow * -1 # flow is in or out of the battery?
                #print("currentFlow:", currentFlow)

        valName  = "mode=\"current\""
        valName  = "{" + valName + "}"
        dataStr  = f"BMS_A{valName} {currentFlow}"
        print(dataStr, file=fileObj)

        valName  = "mode=\"maxVolts\""
        valName  = "{" + valName + "}"
        dataStr  = f"BMS_A{valName} {maxVolts}"
        print(dataStr, file=fileObj)

        valName  = "mode=\"modeInt\", myStr=\""
        valName  = valName + modeName + "\""
        valName  = "{" + valName + "}"
        dataStr  = f"BMS_A{valName} {modeInt}"
        print(dataStr, file=fileObj)

        valName  = "mode=\"temp1\""
        valName  = "{" + valName + "}"
        dataStr  = f"BMS_A{valName} {temp1}"
        print(dataStr, file=fileObj)

        valName  = "mode=\"temp2\""
        valName  = "{" + valName + "}"
        dataStr  = f"BMS_A{valName} {temp2}"
        print(dataStr, file=fileObj)

        valName  = "mode=\"SOC\""
        valName  = "{" + valName + "}"
        dataStr  = f"BMS_A{valName} {socInt}"
        print(dataStr, file=fileObj)

        if (debug):
#                print("header:", header)
#                print("command:", command)
#                print("dataLen:", int(dataLen, 16), "bytes")
                print("End voltage of cell_hi:", int(endVolt_hi, 16), "v")
                print("End voltage of cell_lo:", int(endVolt_lo, 16), "v")
                print("mode:", int(mode, 16))
                print("amps_hi:", int(amps_hi, 16), "a")
                print("amps_lo:", int(amps_lo, 16), "a")
                print("Temp 1_hi:", int(temp1_hi, 16), "c")
                print("Temp 1_lo:", int(temp1_lo, 16), "c")
                print("Temp 2_hi:", int(temp2_hi, 16), "c")
                print("Temp 2_lo:", int(temp2_lo, 16), "c")
                print("SOC:", int(soc, 16), "%")
                print("Checksum:", int(chksum, 16))

        gotSysData = True;
        return(False)
 
Here's the rest. I forgot to mention earlier the code should now dynamically adjust to the cell count set by the Chargery.

Code:
def getIRData(fileObj, hexLine, strLen):
        decStrLen = len(hexLine)
        dataStart = 6   # data starts at byte 8 in 2 byte chunks (hi-lo)
        minLen = 30     # minimal bytes inc header (each byte is 2 chars)
        aggIR = 0    # total internal resistance of the battery
        cellNum = 1
        global gotIRData

        if (debug): print("getIRData: called - ", hexLine)

        if (decStrLen < strLen) or (decStrLen < minLen):
                if (debug): print("Truncated system block - len:", len(hexLine), "Expected:", strLen)
                return(True)
        else:
                if (debug): print("hexLine len", len(hexLine))

        # first 3 fields for debug only)
#        header     = hexLine[0:4]       # header
#        command    = hexLine[0:2]       # command
#        dataLen    = hexLine[2:4]       # data length

        mode1      = hexLine[0:2]       # Current mode
        amps1_lo   = hexLine[2:4]       # Current amps  low byte first!
        amps1_hi   = hexLine[4:6]       # Current amps

        for cell in range(dataStart, decStrLen-4, 4): # incorporate datalength for variable cell count
                cellImped = get_imped_value(int(hexLine[cell:cell+2], 16), int(hexLine[cell+2:cell+4], 16))
                if (debug): print("Cell ", cellNum, ":", cellImped, "mohm")
                # format the data for node_exporter to read into prometheus
                #valName  = "mode={}{}".format("CellNum", cellNum)
                valName  = "mode=\"CellNum" + str(cellNum) + "\""
                valName = "{" + valName + "}"
                dataStr  = f"BMS_B{valName} {cellImped}"
                print(dataStr, file=fileObj)
                aggIR += cellImped
                if (debug): print("aggIR:", aggIR, "mohm")
                cellNum += 1

        chksum     = hexLine[cell:cell+1]     # Checksum

        currentFlow1 = get_current_value(int(amps1_hi, 16), int(amps1_lo, 16))
        modeName1 = modeList[int(mode1, 16)]
        modeInt1 = int(mode1, 16)

        if (debug):
#                print("dataLen:", int(dataLen, 16), "bytes")
                print("current:",  currentFlow1, "A")
                print("mode:", modeInt1, modeName1)
                print("Checksum:", int(chksum, 16))

        if (int(mode1) == 0):
                currentFlow1 = currentFlow1 * -1 # flow is in or out of the battery?

        valName  = "mode=\"aggIR\""
        valName  = "{" + valName + "}"
        dataStr  = f"BMS_B{valName} {aggIR}"
        print(dataStr, file=fileObj)

        valName  = "mode=\"current1\""
        valName  = "{" + valName + "}"
        dataStr  = f"BMS_B{valName} {currentFlow1}"
        print(dataStr, file=fileObj)

        valName  = "mode=\"modeInt\", myStr=\""
        valName  = valName + modeName1 + "\""
        valName  = "{" + valName + "}"
        dataStr  = f"BMS_B{valName} {modeInt1}"
        print(dataStr, file=fileObj)

        gotIRData = True;
        return(False)

################ main ##################

# id id type len data                          checksum
# 24 24 57   0F  10 68 02 00 00 FF 21 FF 21 00 68
# 24 24 56   16  00 0A 00 0A 00 09 00 0B 00 0D 00 11 00 01 00 15 00 10
# len includes id & type

# data is written to the serial port every second or less, waiting too long results in garbled lines.
# Read fast and often to get the best results. System and Cell data is written at different frequencies.

ser = serial.Serial(devName, 115200, bytesize=8, parity='N', stopbits=1, timeout=0.1)
if (debug): print("Opened:", ser.name)

while (ser.is_open):

        if (test):
                testStr='2424562D0CFD0D040D040D020D030D040D060D010D080D020D050CFE0D060CFB0D0F0CFC76FED50263140E0095'
                if (gotCellData): testStr='2424570F0E240100E4008300845B27'
                if (gotSysData): testStr='2424582801E4000100030003000300020003000000000001000100010000000500020003000300CC'
                print("sending",ser.write(binascii.unhexlify(testStr)),"bytes")

        ser.read_until(b'$$',255)        # wait for message header
        aggChecksum = 72                 # seed checksum with header
        myBin  = ser.read()              # read command
        byteC  = bin2hex(myBin)
        byteC  = byteC.decode('utf-8')
        aggChecksum += int(byteC[0:2], 16)
        aggChecksum &= 255
        if (debug):
                print("Cmd:",byteC[0:2], "  aggChecksum:",aggChecksum)
        myBin  = ser.read()              # read number of bytes to expect
        byteD  = bin2hex(myBin)
        byteD  = byteD.decode('utf-8')
        aggChecksum += int(byteD[0:2], 16)
        aggChecksum &= 255
        if (debug):
                print("Len:",byteD[0:2], " aggChecksum:",hex(aggChecksum))
        myPid  = os.getpid()    # for temp file buffering

        myBin = ser.read(int(byteD[0:2], 16)-4)   # read remainder of data
        hexLine = bin2hex(myBin)
        hexLine = hexLine.decode('utf-8')
        dataLen = len(hexLine)
        for bite in range (0, dataLen-2, 2):
                aggChecksum += int(hexLine[bite:bite+2], 16)
                aggChecksum &= 255
                if (debug):
                        print("Data:",hexLine[bite:bite+2], " aggChecksum:",hex(aggChecksum))
        if (debug): print("Checksum:",hexLine[bite+2:bite+4])
        if (gotSysData or gotCellData):
                if (debug): print("Skip new tmpA file")
        else:
                if (debug): print("Opened new tmp file /ramdisk/BMS_A.prom.tmp")
                file_object = open('/ramdisk/BMS_A.prom.tmp', mode='w')

        if (gotIRData):
                if (debug): print("Skip new tmpB file")
        else:
                if (debug): print("Opened new tmp file /ramdisk/BMS_B.prom.tmp")
                file_objectB = open('/ramdisk/BMS_B.prom.tmp', mode='w')

        if (debug): print("Read ", len(hexLine), "nybbles: ", hexLine, "gotSysData:", gotSysData, "gotCellData:", gotCellData)

        if (aggChecksum == int(hexLine[bite+2:bite+4], 16)): # good checksum

#                if (byteA == "24" and byteB == "24"):

                if (gotSysData and gotCellData):
                        # We have a complete set, before we overwrite, copy the temp file to its final dest
                        if (debug): print("BINGO!!! - complete set - copying file to /ramdisk/BMS_A.prom")
                        file_object.flush()
                        file_object.close()
                        outLine = os.system('/bin/mv /ramdisk/BMS_A.prom.tmp /ramdisk/BMS_A.prom')
                        if (debug): outLine = os.system('/bin/cat /ramdisk/BMS_A.prom')
                        #if (debug): sys.exit()
                        # open new temp file as we have data to write
                        file_object = open('/ramdisk/BMS_A.prom.tmp', mode='w')
                        if (debug): print("Opened new tmp file /ramdisk/BMS_A.prom.tmp")
                        gotSysData  = False;    # start all over again
                        gotCellData = False;

                if (gotIRData):
                        # We have a complete set, before we overwrite, copy the temp file to its final dest
                        if (debug): print("BINGO!!! - complete set - copying file to /ramdisk/BMS_B.prom")
                        file_objectB.flush()
                        file_objectB.close()
                        outLine = os.system('/bin/mv /ramdisk/BMS_B.prom.tmp /ramdisk/BMS_B.prom')
                        if (debug): outLine = os.system('/bin/cat /ramdisk/BMS_B.prom')
                        #if (debug): sys.exit()
                        # open new temp file as we have data to write
                        file_objectB = open('/ramdisk/BMS_B.prom.tmp', mode='w')
                        if (debug): print("Opened new tmp file /ramdisk/BMS_B.prom.tmp")
                        gotIRData  = False;    # start all over again

                if (byteC == "56"):
                        if (debug): print("Found Cell block", byteC, hexLine)
                        if (not gotCellData):
                                getCellData(file_object, hexLine, int(byteD, 16))
                elif (byteC == "57"):
                        if (debug): print("Found System block", byteC, hexLine)
                        if (not gotSysData):
                                getSysData(file_object, hexLine, int(byteD, 16))
                elif (byteC == "58"):
                        if (debug): print("Found Impedance block", byteC, hexLine)
                        if (not gotIRData):
                                getIRData(file_objectB, hexLine, int(byteD, 16))
                else:
                        if (debug): print("Found Unexpected command block", byteC, hexLine)
        else:
                if (debug): print("Bad checksum")

ser.close()

# End.
 
Last edited:
HI All,

I followed the cheat sheet and have Grafana, Prometheus, and Node Exporter up and running. My question is how to I get the data from the Renogy Wanderer? I have it connected to the RS232 port directly connected to the Pi via USB. IT registers on ttyUSB0. Apologies in advance as I am new to this. Any help is appreciated. Thanks!
 
Great to hear you got grafana up and running on your pi, your 90% of the way there. Have you looked at the code on my github site for the Renogy wanderer?


Read thro the code introduction if you get stuck. Joe.
 
Great to hear you got grafana up and running on your pi, your 90% of the way there. Have you looked at the code on my github site for the Renogy wanderer?


Read thro the code introduction if you get stuck. Joe.

Hi I updated the serial information and when I run the script I get "Reading Renogy Wanderer data... Failed to read from instrument"
 
I am running this off a RPi3 (had one laying around) connected to directly to the Wanderer. I wonder if it is under powered and that is the issue. I have this in a DIY solar generator I made. Ill see if this works using the proper power supply and if so then ill pick up the Rpi zero and then everything should work fine (fingers crossed).
 
The rj 12 plugs listed in #105 are for stranded wire if you use them on solid wire they can cause poor connections.
 
@BarkingSpider Hi Joe , have you done any monitoring from the JBD BMS (Overkill Solar) ? I use their app on Windows 10 via RS485 /UART to USB cable but would like a graphical display the data captured.
I have just set up the following : Pi 4B (16GB) , Rasp 7” display , keyboard and mouse. Small camera connected and GPIO cable connected to breadboard for experiments ( managed to get pulsing LED working on the board ?) I am totally new to Python coding (old guy used to program PLC’s way back) At my age new technology takes time to learn but slowly getting there.
Thank you very much for all your contributions / efforts and patience to help the clueless.
PS. I have VNC Viewer set up on a few devices and can monitor / control the Pi from a terminal with larger display and easier to do coding.
 
Last edited:
  • Like
Reactions: Dzl
Some help please : I have Python 3.7.3 and 2.7.16 installed on my Pi 4B and would like to make 3.7 the default editor. I have tried all kinds of coding instructions but to no avail. I followed DroneBot's instructions and get "access denied" amongst other messages. Kindly point me in the right direction ,
thanks.
 
Hi Pierre, i haven't used that exact equipment, so i don't have any code for that. But given there is a windows to using RS485, you know it can be read by a Pi. Persistence is the key.
I'm off grid for a few weeks so i don't have access to my lab, all i can say is key trying and learning and post questions here. You can work it out.

Did you get node_exporter working?
Joe.

Some help please : I have Python 3.7.3 and 2.7.16 installed on my Pi 4B and would like to make 3.7 the default editor. I have tried all kinds of coding instructions but to no avail. I followed DroneBot's instructions and get "access denied" amongst other messages. Kindly point me in the right direction ,
thanks.
 
Back
Top