Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Losing connection to multiple clients when calling loseConnection #93

Closed
neldog2 opened this issue Jul 17, 2015 · 2 comments
Closed

Losing connection to multiple clients when calling loseConnection #93

neldog2 opened this issue Jul 17, 2015 · 2 comments
Assignees
Labels

Comments

@neldog2
Copy link

neldog2 commented Jul 17, 2015

I tried getting an answer from stackoverflow but no luck so I'm asking here. I cobbled together some code from different examples trying to get the async client reading multiple values from multiple different modbus targets(power meters). The clients all connect fine and get the first set of values I ask, but then they all disconnect before all the information is returned. Code:

#!/usr/bin/env python
import logging
from twisted.internet import reactor
from twisted.internet import defer, task
from twisted.internet.endpoints import TCP4ClientEndpoint
from pymodbus.constants import Defaults
from pymodbus.client.async import ModbusClientFactory
import time

logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)


hosts = ['10.3.72.89', '10.3.72.57']

start = time.time()


def show_hreg(response):
    log.debug('1st hreg = {0}'.format(response.getRegister(0)))
    print response.registers

def foo(protocol):
    rlist = []
    r2 = protocol.read_holding_registers(1699, 4, unit=1)
    r2.addCallback(show_hreg)
    r3 = protocol.read_holding_registers(1099, 3, unit=1)
    r3.addCallback(show_hreg)
    r4 = protocol.read_holding_registers(1599, 2, unit=1)
    r4.addCallback(show_hreg)
    r5 = protocol.read_holding_registers(1499, 1, unit=1)
    r5.addCallback(show_hreg)


    rlist.append(r2)
    rlist.append(r3)
    rlist.append(r4)
    rlist.append(r5)
    reactor.callLater(1, protocol.transport.loseConnection)
    #reactor.callLater(1.5, reactor.stop)
    results = defer.gatherResults(rlist)
    return results


def main(reactor, hosts):
    dlist = []
    for server in hosts:
        d = TCP4ClientEndpoint(reactor, server, Defaults.Port)
        protocol = d.connect(ModbusClientFactory())
        protocol.addCallback(foo)
        dlist.append(protocol)

    # finish the process when the "queue" is done
    results = defer.gatherResults(dlist).addCallback(printElapsedTime)
    return results


def printElapsedTime(ignore):
    print "Elapsed Time: %s" % (time.time() - start)


task.react(main, [hosts])

Is this even possible? I'm assuming the loseConnection is shutting down all instances of the connections instead of just the client its currently working with. Output seems to suggest the same. Its here:

DEBUG:pymodbus.client.async:Client connected to modbus server
DEBUG:pymodbus.transaction:adding transaction 1
DEBUG:pymodbus.transaction:adding transaction 2
DEBUG:pymodbus.transaction:adding transaction 3
DEBUG:pymodbus.transaction:adding transaction 4
DEBUG:pymodbus.client.async:Client connected to modbus server
DEBUG:pymodbus.transaction:adding transaction 1
DEBUG:pymodbus.transaction:adding transaction 2
DEBUG:pymodbus.transaction:adding transaction 3
DEBUG:pymodbus.transaction:adding transaction 4
DEBUG:pymodbus.factory:Factory Response[3]
DEBUG:pymodbus.transaction:getting transaction 1
DEBUG:root:1st hreg = 5315
[5315, 845, 50, 0]
DEBUG:pymodbus.factory:Factory Response[3]
DEBUG:pymodbus.transaction:getting transaction 2
DEBUG:root:1st hreg = 279
[279, 314, 303]
DEBUG:pymodbus.factory:Factory Response[3]
DEBUG:pymodbus.transaction:getting transaction 3
DEBUG:root:1st hreg = 1566
[1566, 29463]
DEBUG:pymodbus.factory:Factory Response[3]
DEBUG:pymodbus.transaction:getting transaction 4
DEBUG:root:1st hreg = 1565
[1565]
DEBUG:pymodbus.factory:Factory Response[3]
DEBUG:pymodbus.transaction:getting transaction 1
DEBUG:root:1st hreg = 8077
[8077, 1534, 126, 0]
DEBUG:pymodbus.client.async:Client disconnected from modbus server: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
]
DEBUG:pymodbus.transaction:getting transaction 2
main function encountered error
Traceback (most recent call last):
Failure: twisted.internet.defer.FirstError: FirstError[#1, [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.defer.FirstError'>: FirstError[#1, [Failure instance: Traceback (failure with no frames): <class 'pymodbus.exceptions.ConnectionException'>: Modbus Error: [Connection] Connection lost during request
]]
]]
DEBUG:pymodbus.transaction:getting transaction 3
DEBUG:pymodbus.transaction:getting transaction 4
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
Failure: pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Connection lost during request
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
Failure: pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Connection lost during request
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
Failure: pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Connection lost during request
DEBUG:pymodbus.client.async:Client disconnected from modbus server: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion: Connection lost.
]
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
Failure: twisted.internet.defer.FirstError: FirstError[#1, [Failure instance: Traceback (failure with no frames): <class 'pymodbus.exceptions.ConnectionException'>: Modbus Error: [Connection] Connection lost during request
]]

I'm guessing this isn't an issue with modbuspy. I'm not a python person or even a programmer so its probably something very obvious. Thanks!

@glinders
Copy link

glinders commented Mar 9, 2017

I had a similar issue, where I would get 'Connection to the other side was lost in a non-clean fashion: Connection lost' errors.

I fixed that by giving each request a different time in reactor.callLater, so the requests would be handled sequentially instead of simultaneously:

    wait_time_in_s = 0
    for master in masters:
        s = sendchange.Sender(master, auth=auth)
        d = defer.Deferred()
        reactor.callLater(wait_time_in_s, d.callback, None)
        wait_time_in_s += 8
        .....

@dhoomakethu dhoomakethu mentioned this issue Oct 14, 2017
21 tasks
@dhoomakethu dhoomakethu added this to the 1.4.0 milestone Dec 23, 2017
@dhoomakethu dhoomakethu mentioned this issue Dec 23, 2017
12 tasks
@rahulraghu94 rahulraghu94 self-assigned this Dec 29, 2017
@rahulraghu94
Copy link
Contributor

@neldog2, sorry for the (very :P) late response.
If you're still facing this issue, it looks like you're calling transport.loseConnection() before the entire message transaction can complete. Consider attempting the same with a longer delay or using task.deferLater as @glinders is suggesting.

Closing for now. Reopen if you face the same issue :)

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants