を使用して単純な modbus-tcp ポーリングを行うねじれたアプリケーションで、最近導入され たクラスを利用しようとしています。私の問題は、私が使用している modbus プロトコルとは何の関係もないと感じています。低レベルのツイスト API を使用して、他にもかなりの数の実用的なプロトタイプを作成したからです。しかし、この新しいものは私のニーズにぴったり合っているように見えるので、コードのフットプリントを削減し、機能させることができればきれいに保つ必要があります.twisted.application.internet.ClientService
pymodbus
ClientService
私のテストClientService
では、期待どおりにハンドルの再接続が示され、最初の接続に簡単にアクセスできますProtocol
。私が抱えている問題は、再接続のために後続のProtocol
オブジェクトを取得することです。これは、私が問題を抱えているコードの簡略版です。
from twisted.application import internet, service
from twisted.internet.protocol import ClientFactory
from twisted.internet import reactor, endpoints
from pymodbus.client.async import ModbusClientProtocol
class ModbusPollingService(internet.ClientService):
def __init__(self, addrstr, numregs=5):
self.numregs=numregs
internet.ClientService.__init__(self,
endpoints.clientFromString(reactor, addrstr),
ClientFactory.forProtocol(ModbusClientProtocol))
def startService(self):
internet.ClientService.startService(self)
self._pollWhenConnected()
def _pollWhenConnected(self):
d = self.whenConnected()
d.addCallback(self._connected)
d.addErrback(self._connfail)
def _connected(self, p):
self._log.debug("connected: {p}", p=p)
self._mbp = p
self._poll()
return True
def _connfail(self, failstat):
self._log.failure('connection failure', failure=failstat)
self._mbp = None
self._pollWhenConnected()
def _poll(self):
self._log.debug("poll: {n}", n=self.numregs)
d = self._mbp.read_holding_registers(0, self.numregs)
d.addCallback(self._regs)
d.addErrback(self._connfail)
def _regs(self, res):
self._log.debug("regs: {r}", r=res.registers)
# Do real work of dealing storing registers here
reactor.callLater(1, self._poll)
return res
application = service.Application("ModBus Polling Test")
mbpollsvc = ModbusPollingService('tcp:127.0.0.1:502')
mbpollsvc.setServiceParent(application)
接続が(何らかの理由で)失敗するerrback
と、deferred
返された fromread_holding_registers()
が呼び出され、サービスがそれを放棄し、新しい接続がコールバックによって返されるのProtocol
を待つ状態に戻ることができます...しかし、どう思われますか起こっているのは、ClientService が接続が切断されたことをまだ認識しておらず、同じ切断されたプロトコルを返し、次のようなログが表示されることです。Protocol
whenConnected()
2016-05-05 17:28:25-0400 [-] connected: <pymodbus.client.async.ModbusClientProtocol object at 0x000000000227b558>
2016-05-05 17:28:25-0400 [-] poll: 5
2016-05-05 17:28:25-0400 [-] connection failure
Traceback (most recent call last):
Failure: pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Client is not connected
2016-05-05 17:28:25-0400 [-] connected: <pymodbus.client.async.ModbusClientProtocol object at 0x000000000227b558>
2016-05-05 17:28:25-0400 [-] poll: 5
2016-05-05 17:28:25-0400 [-] connection failure
Traceback (most recent call last):
Failure: pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Client is not connected
または非常に似ています。ModbusClientProtocol オブジェクト アドレスの繰り返しに注意してください。
おそらくこの API のパターンの選択を誤っただけだと確信していますが、独自のパターンを作成し、そのクラス内で完全にポーリング メカニズムに基づいて処理するProtocol
などFactory
、いくつかの異なる可能性を繰り返しました。ModbusClientProtocol
しかし、ポーリングされたデータをそのように保存するための永続的な構成とメカニズムを渡すのは少し面倒だと感じました.ClientServiceレベル以上でこれを処理することはよりクリーンなアプローチのようですが、現在接続されているプロトコル。私が本当に探しているのは、拡張ポーリングの状況でクラスを使用するためのベスト プラクティスの推奨事項だと思います。ClientService