runtime/PyroServer.py
author Edouard Tisserant <edouard.tisserant@gmail.com>
Mon, 16 Oct 2023 23:50:58 +0200
changeset 3868 e9807c28a788
parent 3843 832bcf1b5b60
permissions -rw-r--r--
Fix template conflict in XSLT with lxml>=4.9.0 again

Earlier attempt was fixing conflict with -1.0 priority attribute,
as a side effect of such low priority, SFC Actions were not
editable anymore.

This time move template around instead of using explicit priority.
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     1
#!/usr/bin/env python
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     2
# -*- coding: utf-8 -*-
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     3
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     4
# This file is part of Beremiz runtime.
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     5
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     6
# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     7
# Copyright (C) 2017: Andrey Skvortsov
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     8
# Copyright (C) 2018: Edouard TISSERANT
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     9
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    10
# See COPYING file for copyrights details.
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    11
3750
f62625418bff automated conversion using 2to3-3.9 tool
GP Orcullo <kinsamanka@gmail.com>
parents: 3311
diff changeset
    12
f62625418bff automated conversion using 2to3-3.9 tool
GP Orcullo <kinsamanka@gmail.com>
parents: 3311
diff changeset
    13
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    14
import sys
2603
1ffdc62784cf Add some "pipe to self" trick in Pyro server to accelerate runtime shutdown instead of waiting for arbitrary pyro timeout.
Edouard Tisserant
parents: 2492
diff changeset
    15
import os
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    16
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    17
import Pyro5
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    18
import Pyro5.server
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    19
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    20
import runtime
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    21
from runtime.ServicePublisher import ServicePublisher
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    22
3808
3e219f00151a Use msgpack and remove serpent's bytes workaround
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3805
diff changeset
    23
Pyro5.config.SERIALIZER = "msgpack"
3e219f00151a Use msgpack and remove serpent's bytes workaround
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3805
diff changeset
    24
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    25
def make_pyro_exposed_stub(method_name):
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    26
    stub = lambda self, *args, **kwargs: \
3805
5a66d4be2e49 Pyro5: fix runtime typo + IDE exception handling
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3800
diff changeset
    27
        getattr(self.plc_object_instance, method_name)(*args, **kwargs)
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    28
    stub.__name__ = method_name
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    29
    Pyro5.server.expose(stub)
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    30
    return stub
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    31
    
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    32
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    33
class PLCObjectPyroAdapter(type("PLCObjectPyroStubs", (), {
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    34
    name: make_pyro_exposed_stub(name) for name in [
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    35
        "AppendChunkToBlob",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    36
        "GetLogMessage",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    37
        "GetPLCID",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    38
        "GetPLCstatus",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    39
        "GetTraceVariables",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    40
        "MatchMD5", 
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    41
        "NewPLC",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    42
        "PurgeBlobs",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    43
        "RemoteExec",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    44
        "RepairPLC",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    45
        "ResetLogCount",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    46
        "SeedBlob",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    47
        "SetTraceVariablesList",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    48
        "StartPLC",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    49
        "StopPLC"
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    50
    ]
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    51
})):
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    52
    def __init__(self, plc_object_instance):
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    53
        self.plc_object_instance = plc_object_instance
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    54
    
2309
d8fb90a2e11f Please pylint and pep8
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2270
diff changeset
    55
2476
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
    56
class PyroServer(object):
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    57
    def __init__(self, servicename, ip_addr, port):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    58
        self.continueloop = True
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    59
        self.daemon = None
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    60
        self.servicename = servicename
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    61
        self.ip_addr = ip_addr
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    62
        self.port = port
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    63
        self.servicepublisher = None
2603
1ffdc62784cf Add some "pipe to self" trick in Pyro server to accelerate runtime shutdown instead of waiting for arbitrary pyro timeout.
Edouard Tisserant
parents: 2492
diff changeset
    64
        self.piper, self.pipew = None, None
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    65
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    66
    def _to_be_published(self):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    67
        return self.servicename is not None and \
2311
bef2b4b87370 Beremiz_service now binds both pyro and nevow ports to interface given with '-i' argument.
Edouard Tisserant
parents: 2270
diff changeset
    68
               self.ip_addr not in ["", "localhost", "127.0.0.1"]
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    69
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    70
    def PrintServerInfo(self):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    71
        print(_("Pyro port :"), self.port)
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    72
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    73
        if self._to_be_published():
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    74
            print(_("Publishing service on local network"))
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    75
3843
832bcf1b5b60 Runtime/win32: no sys.stdout with pythonw.exe
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3808
diff changeset
    76
        if sys.stdout:
832bcf1b5b60 Runtime/win32: no sys.stdout with pythonw.exe
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3808
diff changeset
    77
            sys.stdout.flush()
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    78
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    79
    def PyroLoop(self, when_ready):
2492
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2476
diff changeset
    80
        if self._to_be_published():
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2476
diff changeset
    81
            self.Publish()
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2476
diff changeset
    82
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    83
        while self.continueloop:
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    84
            self.daemon = Pyro5.server.Daemon(host=self.ip_addr, port=self.port)
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    85
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    86
            self.daemon.register(PLCObjectPyroAdapter(runtime.GetPLCObjectSingleton()), "PLCObject")
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    87
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    88
            when_ready()
3308
358ccd42e052 Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2625
diff changeset
    89
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    90
            self.daemon.requestLoop()
3308
358ccd42e052 Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2625
diff changeset
    91
2476
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
    92
        self.Unpublish()
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    93
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    94
    def Restart(self):
2476
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
    95
        self.daemon.shutdown(True)
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    96
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    97
    def Quit(self):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    98
        self.continueloop = False
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    99
        self.daemon.shutdown()
3308
358ccd42e052 Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2625
diff changeset
   100
        if not sys.platform.startswith('win'):
358ccd42e052 Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2625
diff changeset
   101
            if self.pipew is not None:
358ccd42e052 Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2625
diff changeset
   102
                os.write(self.pipew, "goodbye")
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   103
2476
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   104
    def Publish(self):
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   105
        self.servicepublisher = ServicePublisher("PYRO")
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   106
        self.servicepublisher.RegisterService(self.servicename,
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   107
                                              self.ip_addr, self.port)
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   108
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   109
    def Unpublish(self):
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   110
        if self.servicepublisher is not None:
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   111
            self.servicepublisher.UnRegisterService()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   112
            self.servicepublisher = None