Je veux arrêter un pymodbus
async ModbusTcpServer
puis démarrer un nouveau serveur. Par conséquent, j'ai essayé avec l'extrait de code simplifié suivant, mais j'ai eu une erreur:
INFO:pymodbus.server.async:Starting Modbus TCP Server on localhost:5020 DEBUG:pymodbus.server.async:Running in Main thread DEBUG:pymodbus.server.async:Running in spawned thread DEBUG:pymodbus.server.async:Stopping Server from another thread INFO:pymodbus.server.async:Starting Modbus TCP Server on localhost:5020 DEBUG:pymodbus.server.async:Running in Main thread Traceback (most recent call last): File "stack.py", line 41, in <module> main() File "stack.py", line 39, in main main() # Recursive File "stack.py", line 35, in main defer_reactor_run=False File "/usr/local/lib/python3.6/dist-packages/pymodbus/server/async.py", line 257, in StartTcpServer reactor.run(installSignalHandlers=_is_main_thread()) File "/usr/local/lib/python3.6/dist-packages/twisted/internet/base.py", line 1260, in run self.startRunning(installSignalHandlers=installSignalHandlers) File "/usr/local/lib/python3.6/dist-packages/twisted/internet/base.py", line 1240, in startRunning ReactorBase.startRunning(self) File "/usr/local/lib/python3.6/dist-packages/twisted/internet/base.py", line 748, in startRunning raise error.ReactorNotRestartable() twisted.internet.error.ReactorNotRestartable
Out:
import threading import logging from pymodbus.server.async import StartTcpServer, StopServer from pymodbus.device import ModbusDeviceIdentification from pymodbus.datastore import ModbusSequentialDataBlock from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext logging.basicConfig() log = logging.getLogger() log.setLevel(logging.DEBUG) def stop(): StopServer() def main(name='Pymodbus'): store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [17]*100)) context = ModbusServerContext(slaves=store, single=True) identity = ModbusDeviceIdentification() identity.VendorName = name identity.ProductCode = 'PM' identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' identity.ProductName = 'Pymodbus Server' identity.ModelName = 'Pymodbus Server' identity.MajorMinorRevision = '1.0' t = threading.Timer(5, stop) t.daemon = True t.start() StartTcpServer( context, identity=identity, address=("localhost", 5020), defer_reactor_run=False ) name += 'stuff' main(name) # Recursive main()
[UPDATE]
J'ai également essayé avec un autre thread d'arrêter le ModbusTcpServer
avec l'argument defer_reactor_run = False
(par défaut) dans ModbusTcpServer
, mais malgré cela, le comportement reste le même:
INFO:pymodbus.server.async:Starting Modbus TCP Server on localhost:5020 DEBUG:pymodbus.server.async:Running in Main thread Traceback (most recent call last): File "stack.py", line 42, in <module> main() File "stack.py", line 38, in main StopServer() File "/usr/local/lib/python3.6/dist-packages/pymodbus/server/async.py", line 328, in StopServer reactor.stop() File "/usr/local/lib/python3.6/dist-packages/twisted/internet/base.py", line 630, in stop "Can't stop reactor that isn't running.") twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running.
Out:
from pymodbus.server.async import StartTcpServer, StopServer from pymodbus.device import ModbusDeviceIdentification from pymodbus.datastore import ModbusSequentialDataBlock from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext from time import sleep import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.DEBUG) def main(name='Pymodbus'): store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [17]*100)) context = ModbusServerContext(slaves=store, single=True) identity = ModbusDeviceIdentification() identity.VendorName = name identity.ProductCode = 'PM' identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' identity.ProductName = 'Pymodbus Server' identity.ModelName = 'Pymodbus Server' identity.MajorMinorRevision = '1.0' StartTcpServer( context, identity=identity, address=("localhost", 5020), defer_reactor_run=True ) sleep(3) name += 'stuff' StopServer() sleep(3) main(name) # Recursive main()
3 Réponses :
Dans le premier exemple, le serveur TCP n'est pas exécuté depuis que vous avez défini le paramètre defer_reactor_run sur True, mais vous ne l'avez pas explicitement exécuté. Ainsi, lorsque vous essayez de l'arrêter, il échoue car il n'a pas été démarré.
Dans le deuxième exemple, vous l'exécutez, mais vous l'appelez une prochaine fois de manière récursive avec l'appel principal (name)! donc, il échoue avec une erreur puisqu'il est déjà démarré! le code suivant devrait fonctionner:
from twisted.internet import reactor StartTcpServer(context, identity=identity, address=("localhost", 5020), defer_reactor_run=True) reactor.run()
Si vous voulez différer l'exécution, vous devez appeler:
from pymodbus.server.async import StartTcpServer, StopServer from pymodbus.device import ModbusDeviceIdentification from pymodbus.datastore import ModbusSequentialDataBlock from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext from time import sleep import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.DEBUG) def main(name='Pymodbus'): store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [17]*100)) context = ModbusServerContext(slaves=store, single=True) identity = ModbusDeviceIdentification() identity.VendorName = name identity.ProductCode = 'PM' identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' identity.ProductName = 'Pymodbus Server' identity.ModelName = 'Pymodbus Server' identity.MajorMinorRevision = '1.0' StartTcpServer( context, identity=identity, address=("localhost", 5020), defer_reactor_run=False ) sleep(3) # for the fun ? # and do your stuff StopServer() main()
Dans le deuxième exemple, j'arrête le réacteur par un autre thread après 5sec avec le StopServer ()
intégré dans pymodbus
peut-être, mais en attendant, vous essayez de redémarrer le serveur déjà démarré, avant que le minuteur ne se réveille.
Avez-vous essayé cet extrait de code? Ce code est coincé dans StartTcpServe ()
car defer_reactor_run
est faux. Cependant, je souhaite arrêter et redémarrer le serveur
Il n'est pas bloqué, il exécute un serveur .... si vous voulez l'arrêter, tuez la tâche. J'ai mis à jour comment l'exécuter en mode différé
Ma question est évidente, ce n'est pas ma réponse, et merci pour la réponse.
Je n'ai aucun problème pour exécuter le serveur, je veux exécuter un serveur puis l'arrêter puis démarrer le serveur avec un nouveau contenu pour une raison quelconque (mon code de question est simplifié du code pour simuler ce que je veux). Si je n'ai pas trouvé de réponse pour redémarrer une boucle réacteur
je le fais par un autre code
J'ai trouvé une solution alternative pour arrêter et démarrer un Async ModbusTcpServer par un autre code Python car apparemment, nous ne pouvons pas redémarrer une boucle d'événement réacteur
.
Voici le runner.py
code:
$ python3 runner.py 2019-01-24 12:45:05,126 MainThread INFO async :254 Starting Modbus TCP Server on localhost:5020 2019-01-24 12:45:10,129 Thread-1 DEBUG async :222 Running in spawned thread 2019-01-24 12:45:10,129 Thread-1 DEBUG async :332 Stopping Server from another thread b'Start an async server.\nProcess will be down.\nServer was stopped.\n' 2019-01-24 12:45:13,389 MainThread INFO async :254 Starting Modbus TCP Server on localhost:5020 2019-01-24 12:45:18,392 Thread-1 DEBUG async :222 Running in spawned thread 2019-01-24 12:45:18,392 Thread-1 DEBUG async :332 Stopping Server from another thread b'Start an async server.\nProcess will be down.\nServer was stopped.\n' 2019-01-24 12:45:21,653 MainThread INFO async :254 Starting Modbus TCP Server on localhost:5020 2019-01-24 12:45:26,656 Thread-1 DEBUG async :222 Running in spawned thread 2019-01-24 12:45:26,657 Thread-1 DEBUG async :332 Stopping Server from another thread b'Start an async server.\nProcess will be down.\nServer was stopped.\n' . . .
Voici l'extrait de code async_server.py
:
from pymodbus.server.async import StartTcpServer, StopServer from pymodbus.device import ModbusDeviceIdentification from pymodbus.datastore import ModbusSequentialDataBlock from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext import threading import sys import logging FORMAT = ('%(asctime)-15s %(threadName)-15s' ' %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s') logging.basicConfig(format=FORMAT) log = logging.getLogger() log.setLevel(logging.DEBUG) def stop(): print('Process will be down.') StopServer() # Stop server. sys.exit(0) # Kill the server code. def run_async_server(): store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [17] * 100)) slaves = { 0x01: store, 0x02: store, 0x03: store, } context = ModbusServerContext(slaves=slaves, single=False) identity = ModbusDeviceIdentification() identity.VendorName = 'Pymodbus' identity.ProductCode = 'PM' identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' identity.ProductName = 'Pymodbus Server' identity.ModelName = 'Pymodbus Server' identity.MajorMinorRevision = '1.5' from twisted.internet import reactor StartTcpServer(context, identity=identity, address=("localhost", 5020), defer_reactor_run=True) print('Start an async server.') t = threading.Timer(5, stop) t.daemon = True t.start() reactor.run() print('Server was stopped.') if __name__ == "__main__": run_async_server()
Sortie:
import subprocess python_version = '3' path_to_run = './' py_name = 'async_server.py' def run(): args = [f"python{python_version}", f"{path_to_run}{py_name}"] sub_process = subprocess.Popen(args, stdout=subprocess.PIPE) output, error_ = sub_process.communicate() if not error_: print(output) else: print(error_) run() # Recursively. if __name__ == '__main__': run()
Vous pouvez utiliser l'exemple inclus dans les dossiers de la bibliothèque: asynchronous-server.py
dans python3.7 async a été inclus comme mot-clé, mais dans pymodbus 2.3.0 pymodbus.server.async a été changé en pymodbus.server. asynchrone
Je vous partage un exemple qui fonctionne bien pour moi:
Si vous avez d'autres questions, écrivez-moi à l'adresse e-mail: Danielsalazr@hotmail.com
< pre> XXXSalutations de Colombie
Bonjour Daniel, Depuis que cette bibliothèque pymodbus a été mise à jour, pymodbus.server.async
a été transformé en pymodbus.server.asynchronous
dans la nouvelle version et je suis conscient (ma question a été posée il y a un an avec la version antérieure de pymodbus). Cependant, ce n'est pas mon problème. Comme je l'ai mentionné dans la question, le problème est StopServer
et non StartTcpServer