0

Basically I'm supposed to test modbus functionality right now and for whatever reason modbus fails to read the registers every second call, ex: Functions:

# Modbus functions
def read_system_uptime(c, ssh):
    try:
        # Get uptime with ubus
        ssh_result = str(exec_ssh("ubus call system info", ssh))
        ssh_obj = json.loads(ssh_result)
        uptime = str(ssh_obj['uptime'])

        regs = c.read_holding_registers(1, 2)
        if (regs != None and regs[0] == 0):
            result = check_match(uptime, regs[1])
            logger("System uptime", uptime, regs[1], result)
        elif (regs != None and regs[0] != 0):
            #Check results
            temp = regs[0] * 65536 + regs[1]
            result = check_match(uptime, temp)
            logger("System uptime", uptime, temp, result)
        else:
            error_logger("System hostname", "Could not read register value")
    except Exception as error:
        error_logger("system uptime", error)
def read_mobile_strength(c, ssh):
    try:
        regs = c.read_holding_registers(3, 2)
        if regs != None:
            bits = decimal_To_Binary(regs[1])
            a = str(binary_To_Complement(bits)).strip()

            #Check results
            gsmctl = str(exec_ssh("gsmctl -q", ssh)).strip()
            result = check_match(gsmctl, a)
            logger("Mobile signal strength", gsmctl, a, result)
        else:
            error_logger("Mobile signal strength", "Could not read register value")
    except Exception as error:
        error_logger("Mobile signal strength", error)
def read_system_hostname(c, ssh):
    try:
        regs = c.read_holding_registers(7, 16)
        if regs != None:
            a = str(dec_to_text(regs)).strip()

            #Check results
            name = str(exec_ssh("uci get system.system.hostname", ssh)).strip()
            result = check_match(name, a)
            logger("System hostname", name, a, result)
        else:
            error_logger("System hostname", "Could not read register value")

    except Exception as error:
        error_logger("System hostname", error)

Main:

# Main fuction
def main():
    #router_ip, router_port, router_username, router_password = run_args(sys.argv[1:])
    ssh = paramiko.SSHClient()
    if ssh_connect(ssh, router_ip, router_port, router_username, router_password) != False:
        modbus = modbus_start(router_ip, modbus_port, modbus_id)
        if modbus != False:
            read_system_hostname(modbus, ssh)
            read_system_uptime(modbus, ssh)
            read_mobile_strength(modbus, ssh)


# Run main()
if __name__ == '__main__':
    main()

If I run the code like this, I won't get value for system uptime.

        if modbus != False:
            read_system_hostname(modbus, ssh)
            read_mobile_strength(modbus, ssh)
            read_system_uptime(modbus, ssh)

And Now I won't get mobile strength value, this happens with every second function, I can move those functions around, like move them to first position and it will work, so it's not functions fault, my guess it's pyModbusTCP or maybe even the devices that I'm working with fault, but I am not sure. Anybody knows how to deal with this? Because I never worked with this library before. Do I have to clear out the data I read or something like that? Currently I have one stupid solution of just placing a "Fake" function that reads the register and does nothing with it and place it in between others, so important ones would work, but I would like to avoid that if possible.

EDIT: Modbus start function:

def modbus_start(ip, port, device):
    try:
        client = ModbusClient(host=ip, port=port, unit_id=device, auto_open=True)
        print("Modbus client start: Success")
        logging.info("Started Modbus client")
        return client
    except Exception as error:
        print("ERROR: Failed to start Modbus client: ")
        print(error)
        logging.error("Failed to start Modbus client: %s", error)
        return False
Wowy
  • 137
  • 2
  • 11
  • You have left out two important things: the `modbus_start` function, which might be, in my opinion quite important, and the type of devices you are connecting to. So this is just a wild guess: some (or many) devices don't like when you open and close the connection repeatedly, are you setting `auto_open` and `auto_close` to `True`? – Marcos G. May 13 '21 at 17:30
  • Edited the post, sorry – Wowy May 14 '21 at 07:24
  • OK, thanks. I would try to set both `auto_open` and `auto_close` to `False` to check if you see changes in behavior. If that is not good, maybe set both to `True`. – Marcos G. May 14 '21 at 09:30
  • For now it seems that setting both to True fixes it, but I check a lot of registers, so it's hard to tell if it anything is missing, I will have to go over in better detail to be 100%. Any idea why that happens, cause it's really weird that every 2nd function stopped working – Wowy May 14 '21 at 13:49
  • I cannot be sure but it looks like your device is closing the connection unilaterally. Maybe you should check its manual to see what's going on – Marcos G. May 14 '21 at 14:16

0 Answers0