runtime/PLCObject.py
author Edouard Tisserant <edouard@beremiz.fr>
Fri, 08 Nov 2024 11:34:00 +0100
changeset 4034 6359536d60a9
parent 4032 1ffff67678ad
permissions -rw-r--r--
python_runtime: fix ExtendedCall register/unregistering.
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     1
#!/usr/bin/env python
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     2
# -*- coding: utf-8 -*-
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     3
1667
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
     4
# This file is part of Beremiz runtime.
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     5
#
1571
486f94a8032c fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1570
diff changeset
     6
# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     7
#
1667
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
     8
# See COPYING.Runtime file for copyrights details.
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     9
#
1667
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    10
# This library is free software; you can redistribute it and/or
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    11
# modify it under the terms of the GNU Lesser General Public
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    12
# License as published by the Free Software Foundation; either
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    13
# version 2.1 of the License, or (at your option) any later version.
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    14
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    15
# This library is distributed in the hope that it will be useful,
1571
486f94a8032c fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1570
diff changeset
    16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
1667
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    18
# Lesser General Public License for more details.
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    19
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    20
# You should have received a copy of the GNU Lesser General Public
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    21
# License along with this library; if not, write to the Free Software
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    22
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    23
1832
0f1081928d65 fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1831
diff changeset
    24
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
    25
from threading import Thread, Lock, Event, Condition
1732
94ffe74e6895 clean-up: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1730
diff changeset
    26
import ctypes
94ffe74e6895 clean-up: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1730
diff changeset
    27
import os
94ffe74e6895 clean-up: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1730
diff changeset
    28
import sys
1783
3311eea28d56 clean-up: fix PEP8 E402 module level import not at top of file
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1780
diff changeset
    29
import traceback
2537
eb4a4cc41914 Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    30
import shutil
3861
7e17f7e02a2b Runtime: add GetVersions() call to PLCObject, use it in web settings and expose it in WAMP and Pyro.
Edouard Tisserant
parents: 3578
diff changeset
    31
import platform as platform_module
1832
0f1081928d65 fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1831
diff changeset
    32
from time import time
2540
fca79ca84272 Replace md5 module with hashlib
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2537
diff changeset
    33
import hashlib
2537
eb4a4cc41914 Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    34
from tempfile import mkstemp
eb4a4cc41914 Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    35
from functools import wraps, partial
eb4a4cc41914 Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    36
import _ctypes
1832
0f1081928d65 fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1831
diff changeset
    37
1902
2b7e2db31d81 Clarify licensing, and packaging of runtime only files :
Edouard Tisserant
parents: 1881
diff changeset
    38
from runtime.typemapping import TypeTranslator
2b7e2db31d81 Clarify licensing, and packaging of runtime only files :
Edouard Tisserant
parents: 1881
diff changeset
    39
from runtime.loglevels import LogLevelsDefault, LogLevelsCount
2324
1cf3768ebf85 Automatically get PSK and ID when connecting to PYRO[S], so that future connection through PYROS can use that same key. Also fixed case to UPPER for *PSK.
Edouard Tisserant
parents: 2309
diff changeset
    40
from runtime.Stunnel import getPSKID
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
    41
from runtime import PlcStatus
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents: 1997
diff changeset
    42
from runtime import MainWorker
2583
e172ab28d04e Continue fixing deadlock of previous commit, this time occuring when waiting for 'cleanup' python runtime call to finish. Now 'init' and 'cleanup' python runtime calls are called directly from main thread, and aren't anymore invoked in the context of wxMainloop and/or twisted reactor.
Edouard Tisserant
parents: 2582
diff changeset
    43
from runtime import default_evaluator
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    44
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    45
if os.name in ("nt", "ce"):
1919
ccea0fa6ea91 Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents: 1906
diff changeset
    46
    dlopen = _ctypes.LoadLibrary
ccea0fa6ea91 Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents: 1906
diff changeset
    47
    dlclose = _ctypes.FreeLibrary
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    48
elif os.name == "posix":
1919
ccea0fa6ea91 Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents: 1906
diff changeset
    49
    dlopen = _ctypes.dlopen
ccea0fa6ea91 Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents: 1906
diff changeset
    50
    dlclose = _ctypes.dlclose
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    51
1736
7e61baa047f0 clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1734
diff changeset
    52
699
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    53
def get_last_traceback(tb):
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    54
    while tb.tb_next:
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    55
        tb = tb.tb_next
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    56
    return tb
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    57
1749
d73b64672238 clean-up: fix PEP8 E305 expected 2 blank lines after class or function definition
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1745
diff changeset
    58
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
    59
lib_ext = {
3776
1fbc900ca1ce switched to Pyro5
GP Orcullo <kinsamanka@gmail.com>
parents: 3772
diff changeset
    60
    "linux": ".so",
1878
fb73a6b6622d fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1868
diff changeset
    61
    "win32":  ".dll",
fb73a6b6622d fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1868
diff changeset
    62
}.get(sys.platform, "")
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    63
1736
7e61baa047f0 clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1734
diff changeset
    64
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    65
def PLCprint(message):
3843
832bcf1b5b60 Runtime/win32: no sys.stdout with pythonw.exe
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3811
diff changeset
    66
    if sys.stdout:
832bcf1b5b60 Runtime/win32: no sys.stdout with pythonw.exe
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3811
diff changeset
    67
        sys.stdout.write("PLCobject : "+message+"\n")
832bcf1b5b60 Runtime/win32: no sys.stdout with pythonw.exe
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3811
diff changeset
    68
        sys.stdout.flush()
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    69
1736
7e61baa047f0 clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1734
diff changeset
    70
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    71
def RunInMain(func):
2486
44c2a4e2b84d Fixed deadlock in runtime's Worker. Was discovered while using WAMP and PYRO simultaneously.
Edouard Tisserant
parents: 2485
diff changeset
    72
    @wraps(func)
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
    73
    def func_wrapper(*args, **kwargs):
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    74
        return MainWorker.call(func, *args, **kwargs)
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    75
    return func_wrapper
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
    76
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    77
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents: 1997
diff changeset
    78
class PLCObject(object):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents: 1997
diff changeset
    79
    def __init__(self, WorkingDir, argv, statuschange, evaluator, pyruntimevars):
2492
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2487
diff changeset
    80
        self.workingdir = WorkingDir  # must exits already
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
    81
        self.tmpdir = os.path.join(WorkingDir, 'tmp')
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
    82
        if os.path.exists(self.tmpdir):
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
    83
            shutil.rmtree(self.tmpdir)
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
    84
        os.mkdir(self.tmpdir)
3776
1fbc900ca1ce switched to Pyro5
GP Orcullo <kinsamanka@gmail.com>
parents: 3772
diff changeset
    85
        self.argv = []
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents: 1997
diff changeset
    86
        self.statuschange = statuschange
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents: 1997
diff changeset
    87
        self.evaluator = evaluator
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents: 1997
diff changeset
    88
        self.pyruntimevars = pyruntimevars
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
    89
        self.PLCStatus = PlcStatus.Empty
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    90
        self.PLClibraryHandle = None
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
    91
        self.PLClibraryLock = Lock()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    92
        # Creates fake C funcs proxies
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    93
        self._InitPLCStubCalls()
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
    94
        self._loading_error = None
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
    95
        self.python_runtime_vars = None
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
    96
        self.TraceThread = None
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
    97
        self.TraceLock = Lock()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
    98
        self.Traces = []
2485
ef327451d067 Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents: 2463
diff changeset
    99
        self.DebugToken = 0
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   100
3950
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   101
        # Event to signal when PLC is stopped.
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   102
        self.PlcStopped = Event()
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   103
        self.PlcStopped.set()
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   104
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   105
        self._init_blobs()
4032
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   106
        
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   107
        # initialize extended calls with GetVersions call, ignoring arguments
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   108
        self.extended_calls = {"GetVersions":lambda *_args:self.GetVersions().encode()}
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   109
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   110
    # First task of worker -> no @RunInMain
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents: 1997
diff changeset
   111
    def AutoLoad(self, autostart):
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   112
        # Get the last transfered PLC
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   113
        try:
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   114
            self.CurrentPLCFilename = open(
1878
fb73a6b6622d fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1868
diff changeset
   115
                self._GetMD5FileName(),
fb73a6b6622d fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1868
diff changeset
   116
                "r").read().strip() + lib_ext
2608
a332f989f0b8 Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents: 2602
diff changeset
   117
            self.PLCStatus = PlcStatus.Stopped
a332f989f0b8 Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents: 2602
diff changeset
   118
            if autostart:
a332f989f0b8 Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents: 2602
diff changeset
   119
                if self.LoadPLC():
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents: 1997
diff changeset
   120
                    self.StartPLC()
3282
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   121
                else:
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   122
                    self._fail(_("Problem autostarting PLC : can't load PLC"))
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   123
                return
1846
14b40afccd69 remove unused variables found by pylint
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1832
diff changeset
   124
        except Exception:
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
   125
            self.PLCStatus = PlcStatus.Empty
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   126
            self.CurrentPLCFilename = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   127
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents: 1997
diff changeset
   128
        self.StatusChange()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents: 1997
diff changeset
   129
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   130
    def StatusChange(self):
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   131
        if self.statuschange is not None:
1438
19ebe96b41c0 Moved twisted/nevow/athena away from Berermiz_service.py + some minor cleanup
Edouard Tisserant
parents: 1435
diff changeset
   132
            for callee in self.statuschange:
19ebe96b41c0 Moved twisted/nevow/athena away from Berermiz_service.py + some minor cleanup
Edouard Tisserant
parents: 1435
diff changeset
   133
                callee(self.PLCStatus)
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   134
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   135
    def LogMessage(self, *args):
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   136
        if len(args) == 2:
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   137
            level, msg = args
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   138
        else:
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   139
            level = LogLevelsDefault
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   140
            msg, = args
1906
60edd0c901f1 Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents: 1902
diff changeset
   141
        PLCprint(msg)
60edd0c901f1 Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents: 1902
diff changeset
   142
        if self._LogMessage is not None:
3811
fcd2826f5c9e Fix bytes/string confusion with Logging
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3808
diff changeset
   143
            bmsg = msg.encode()
fcd2826f5c9e Fix bytes/string confusion with Logging
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3808
diff changeset
   144
            return self._LogMessage(level, bmsg, len(bmsg))
1906
60edd0c901f1 Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents: 1902
diff changeset
   145
        return None
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   146
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   147
    @RunInMain
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   148
    def ResetLogCount(self):
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   149
        if self._ResetLogCount is not None:
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   150
            self._ResetLogCount()
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   151
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   152
    # used internaly
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   153
    def GetLogCount(self, level):
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   154
        if self._GetLogCount is not None:
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   155
            return int(self._GetLogCount(level))
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   156
        elif self._loading_error is not None and level == 0:
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   157
            return 1
3884
34da877021d5 Replace PYRO with ERPC. Work In Progress.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3881
diff changeset
   158
        return 0
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   159
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   160
    @RunInMain
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   161
    def GetLogMessage(self, level, msgid):
921
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   162
        tick = ctypes.c_uint32()
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   163
        tv_sec = ctypes.c_uint32()
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   164
        tv_nsec = ctypes.c_uint32()
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   165
        if self._GetLogMessage is not None:
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   166
            maxsz = len(self._log_read_buffer)-1
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   167
            sz = self._GetLogMessage(level, msgid,
1768
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   168
                                     self._log_read_buffer, maxsz,
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   169
                                     ctypes.byref(tick),
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   170
                                     ctypes.byref(tv_sec),
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   171
                                     ctypes.byref(tv_nsec))
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   172
            if sz and sz <= maxsz:
3772
ec2babbd5698 str encoding fixes
GP Orcullo <kinsamanka@gmail.com>
parents: 3752
diff changeset
   173
                return (self._log_read_buffer[:sz].decode(), tick.value,
ec2babbd5698 str encoding fixes
GP Orcullo <kinsamanka@gmail.com>
parents: 3752
diff changeset
   174
                        tv_sec.value, tv_nsec.value)
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   175
        elif self._loading_error is not None and level == 0:
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   176
            return self._loading_error, 0, 0, 0
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   177
        return None
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   178
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   179
    def _GetMD5FileName(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   180
        return os.path.join(self.workingdir, "lasttransferedPLC.md5")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   181
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   182
    def _GetLibFileName(self):
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   183
        return os.path.join(self.workingdir, self.CurrentPLCFilename)
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   184
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   185
    def _LoadPLC(self):
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   186
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   187
        Load PLC library
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   188
        Declare all functions, arguments and return values
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   189
        """
1457
ff7cfce737ca Added PLCID variable accessible from C side, set with binarie's MD5. Added retain init and cleanup calls. Extended tests/python to test PLCID
Edouard Tisserant
parents: 1447
diff changeset
   190
        md5 = open(self._GetMD5FileName(), "r").read()
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   191
        self.PLClibraryLock.acquire()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   192
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   193
            self._PLClibraryHandle = dlopen(self._GetLibFileName())
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   194
            self.PLClibraryHandle = ctypes.CDLL(self.CurrentPLCFilename, handle=self._PLClibraryHandle)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   195
1463
de311ffe3961 Changed runtime's global PLCID to PLC_ID, working around redefinition in windoze' headers.
Edouard Tisserant
parents: 1457
diff changeset
   196
            self.PLC_ID = ctypes.c_char_p.in_dll(self.PLClibraryHandle, "PLC_ID")
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   197
            if len(md5) == 32:
3772
ec2babbd5698 str encoding fixes
GP Orcullo <kinsamanka@gmail.com>
parents: 3752
diff changeset
   198
                self.PLC_ID.value = md5.encode()
1457
ff7cfce737ca Added PLCID variable accessible from C side, set with binarie's MD5. Added retain init and cleanup calls. Extended tests/python to test PLCID
Edouard Tisserant
parents: 1447
diff changeset
   199
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   200
            self._startPLC = self.PLClibraryHandle.startPLC
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   201
            self._startPLC.restype = ctypes.c_int
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   202
            self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)]
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   203
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   204
            self._stopPLC_real = self.PLClibraryHandle.stopPLC
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   205
            self._stopPLC_real.restype = None
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   206
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   207
            self._PythonIterator = getattr(self.PLClibraryHandle, "PythonIterator", None)
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   208
            if self._PythonIterator is not None:
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   209
                self._PythonIterator.restype = ctypes.c_char_p
851
666f5bdad301 Added FBID variable to PY_EVAL evaluation context. FBID does identify uniquely py_eval block instance triggering execution
Edouard Tisserant
parents: 798
diff changeset
   210
                self._PythonIterator.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_void_p)]
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   211
483
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   212
                self._stopPLC = self._stopPLC_real
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   213
            else:
717
1c23952dbde1 refactoring
Edouard Tisserant
parents: 699
diff changeset
   214
                # If python confnode is not enabled, we reuse _PythonIterator
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   215
                # as a call that block pythonthread until StopPLC
1442
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   216
                self.PlcStopping = Event()
1750
acf02488f37f clean-up: fix PEP8 E306 expected 1 blank line before a nested definition, found X
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1749
diff changeset
   217
868
7e5da4962bea Fix bug of PythonIterator signature in PLCObject when not using PythonLibrary
Edouard Tisserant
parents: 867
diff changeset
   218
                def PythonIterator(res, blkid):
1442
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   219
                    self.PlcStopping.clear()
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   220
                    self.PlcStopping.wait()
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   221
                    return None
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   222
                self._PythonIterator = PythonIterator
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   223
483
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   224
                def __StopPLC():
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   225
                    self._stopPLC_real()
1442
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   226
                    self.PlcStopping.set()
483
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   227
                self._stopPLC = __StopPLC
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   228
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   229
            self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   230
            self._ResetDebugVariables.restype = None
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   231
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   232
            self._RegisterDebugVariable = self.PLClibraryHandle.RegisterDebugVariable
3395
93ad018fb602 RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents: 3282
diff changeset
   233
            self._RegisterDebugVariable.restype = ctypes.c_int
3887
2df45e4bd500 Fix variable forcing. Now works with eRPC. PLCObject API changed.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3884
diff changeset
   234
            self._RegisterDebugVariable.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_uint32]
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   235
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   236
            self._FreeDebugData = self.PLClibraryHandle.FreeDebugData
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   237
            self._FreeDebugData.restype = None
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   238
450
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   239
            self._GetDebugData = self.PLClibraryHandle.GetDebugData
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   240
            self._GetDebugData.restype = ctypes.c_int
450
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   241
            self._GetDebugData.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_void_p)]
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   242
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   243
            self._suspendDebug = self.PLClibraryHandle.suspendDebug
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   244
            self._suspendDebug.restype = ctypes.c_int
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   245
            self._suspendDebug.argtypes = [ctypes.c_int]
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   246
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   247
            self._resumeDebug = self.PLClibraryHandle.resumeDebug
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   248
            self._resumeDebug.restype = None
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   249
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   250
            self._ResetLogCount = self.PLClibraryHandle.ResetLogCount
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   251
            self._ResetLogCount.restype = None
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   252
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   253
            self._GetLogCount = self.PLClibraryHandle.GetLogCount
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   254
            self._GetLogCount.restype = ctypes.c_uint32
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   255
            self._GetLogCount.argtypes = [ctypes.c_uint8]
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   256
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   257
            self._LogMessage = self.PLClibraryHandle.LogMessage
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   258
            self._LogMessage.restype = ctypes.c_int
971
c4550f76ae05 reverted PLCObject.py. ctypes.POINTER(ctypes.c_uint8) != string
Edouard Tisserant
parents: 969
diff changeset
   259
            self._LogMessage.argtypes = [ctypes.c_uint8, ctypes.c_char_p, ctypes.c_uint32]
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   260
1760
ed2e2afb9573 clean-up: fix PEP8 E262 inline comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1750
diff changeset
   261
            self._log_read_buffer = ctypes.create_string_buffer(1 << 14)  # 16K
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   262
            self._GetLogMessage = self.PLClibraryHandle.GetLogMessage
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   263
            self._GetLogMessage.restype = ctypes.c_uint32
921
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   264
            self._GetLogMessage.argtypes = [ctypes.c_uint8, ctypes.c_uint32, ctypes.c_char_p, ctypes.c_uint32, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)]
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   265
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   266
            self._loading_error = None
1035
0f905e027d18 Better mdns resolution failure signaling, added fixed bug whith runtime autostart
Edouard Tisserant
parents: 1027
diff changeset
   267
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   268
        except Exception:
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   269
            self._loading_error = traceback.format_exc()
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   270
            PLCprint(self._loading_error)
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   271
            return False
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   272
        finally:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   273
            self.PLClibraryLock.release()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   274
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   275
        return True
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   276
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   277
    @RunInMain
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   278
    def LoadPLC(self):
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   279
        res = self._LoadPLC()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   280
        if res:
3282
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   281
            try:
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   282
                self.PythonRuntimeInit()
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   283
            except Exception:
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   284
                self._loading_error = traceback.format_exc()
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   285
                PLCprint(self._loading_error)
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   286
                return False
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   287
        else:
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   288
            self._FreePLC()
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   289
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   290
        return res
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   291
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   292
    @RunInMain
1045
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   293
    def UnLoadPLC(self):
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   294
        self.PythonRuntimeCleanup()
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   295
        self._FreePLC()
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   296
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   297
    def _InitPLCStubCalls(self):
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   298
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   299
        create dummy C func proxies
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   300
        """
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   301
        self._startPLC = lambda x, y: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   302
        self._stopPLC = lambda: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   303
        self._ResetDebugVariables = lambda: None
3395
93ad018fb602 RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents: 3282
diff changeset
   304
        self._RegisterDebugVariable = lambda x, y: 0
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   305
        self._IterDebugData = lambda x, y: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   306
        self._FreeDebugData = lambda: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   307
        self._GetDebugData = lambda: -1
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   308
        self._suspendDebug = lambda x: -1
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   309
        self._resumeDebug = lambda: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   310
        self._PythonIterator = lambda: ""
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   311
        self._GetLogCount = None
1906
60edd0c901f1 Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents: 1902
diff changeset
   312
        self._LogMessage = None
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   313
        self._GetLogMessage = None
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   314
        self._PLClibraryHandle = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   315
        self.PLClibraryHandle = None
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   316
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   317
    def _FreePLC(self):
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   318
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   319
        Unload PLC library.
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   320
        This is also called by __init__ to create dummy C func proxies
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   321
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   322
        self.PLClibraryLock.acquire()
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   323
        try:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   324
            # Unload library explicitely
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   325
            if getattr(self, "_PLClibraryHandle", None) is not None:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   326
                dlclose(self._PLClibraryHandle)
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   327
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   328
            # Forget all refs to library
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   329
            self._InitPLCStubCalls()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   330
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   331
        finally:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   332
            self.PLClibraryLock.release()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   333
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   334
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   335
3959
d5edde0c145b Revert unwanted changes potentially breaking wxGlade support.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3950
diff changeset
   336
    def PythonRuntimeCall(self, methodname, use_evaluator=True, reverse_order=False):
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   337
        """
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   338
        Calls init, start, stop or cleanup method provided by
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   339
        runtime python files, loaded when new PLC uploaded
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   340
        """
2635
ae099881d800 PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents: 2625
diff changeset
   341
        methods = self.python_runtime_vars.get("_runtime_%s" % methodname, [])
ae099881d800 PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents: 2625
diff changeset
   342
        if reverse_order:
ae099881d800 PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents: 2625
diff changeset
   343
            methods = reversed(methods)
ae099881d800 PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents: 2625
diff changeset
   344
        for method in methods:
3959
d5edde0c145b Revert unwanted changes potentially breaking wxGlade support.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3950
diff changeset
   345
            if use_evaluator:
d5edde0c145b Revert unwanted changes potentially breaking wxGlade support.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3950
diff changeset
   346
                _res, exp = self.evaluator(method)
d5edde0c145b Revert unwanted changes potentially breaking wxGlade support.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3950
diff changeset
   347
            else:
d5edde0c145b Revert unwanted changes potentially breaking wxGlade support.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3950
diff changeset
   348
                _res, exp = default_evaluator(method)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   349
            if exp is not None:
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   350
                self.LogMessage(0, '\n'.join(traceback.format_exception(*exp)))
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   351
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   352
    # used internaly
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   353
    def PythonRuntimeInit(self):
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   354
        MethodNames = ["init", "start", "stop", "cleanup"]
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   355
        self.python_runtime_vars = globals().copy()
1438
19ebe96b41c0 Moved twisted/nevow/athena away from Berermiz_service.py + some minor cleanup
Edouard Tisserant
parents: 1435
diff changeset
   356
        self.python_runtime_vars.update(self.pyruntimevars)
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   357
        parent = self
1438
19ebe96b41c0 Moved twisted/nevow/athena away from Berermiz_service.py + some minor cleanup
Edouard Tisserant
parents: 1435
diff changeset
   358
1831
56b48961cc68 fix (old-style-class) Old-style class defined error for most parts of
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1783
diff changeset
   359
        class PLCSafeGlobals(object):
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   360
            def __getattr__(self, name):
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   361
                try:
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   362
                    t = parent.python_runtime_vars["_"+name+"_ctype"]
1156
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   363
                except KeyError:
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   364
                    raise KeyError("Try to get unknown shared global variable : %s" % name)
1156
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   365
                v = t()
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   366
                parent.python_runtime_vars["_PySafeGetPLCGlob_"+name](ctypes.byref(v))
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   367
                return parent.python_runtime_vars["_"+name+"_unpack"](v)
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   368
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   369
            def __setattr__(self, name, value):
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   370
                try:
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   371
                    t = parent.python_runtime_vars["_"+name+"_ctype"]
1156
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   372
                except KeyError:
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   373
                    raise KeyError("Try to set unknown shared global variable : %s" % name)
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   374
                v = parent.python_runtime_vars["_"+name+"_pack"](t, value)
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   375
                parent.python_runtime_vars["_PySafeSetPLCGlob_"+name](ctypes.byref(v))
1447
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   376
2697
93333d206198 Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2689
diff changeset
   377
        class OnChangeStateClass(object):
93333d206198 Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2689
diff changeset
   378
            def __getattr__(self, name):
93333d206198 Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2689
diff changeset
   379
                u = parent.python_runtime_vars["_"+name+"_unpack"]
2698
e50d32c747b3 Fixed "Onchange" object added in previous commit
Edouard Tisserant
parents: 2697
diff changeset
   380
                return type("changedesc",(),dict(
e50d32c747b3 Fixed "Onchange" object added in previous commit
Edouard Tisserant
parents: 2697
diff changeset
   381
                    count = parent.python_runtime_vars["_PyOnChangeCount_"+name].value,
e50d32c747b3 Fixed "Onchange" object added in previous commit
Edouard Tisserant
parents: 2697
diff changeset
   382
                    first = u(parent.python_runtime_vars["_PyOnChangeFirst_"+name]),
e50d32c747b3 Fixed "Onchange" object added in previous commit
Edouard Tisserant
parents: 2697
diff changeset
   383
                    last = u(parent.python_runtime_vars["_PyOnChangeLast_"+name])))
2697
93333d206198 Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2689
diff changeset
   384
93333d206198 Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2689
diff changeset
   385
1447
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   386
        self.python_runtime_vars.update({
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   387
            "PLCGlobals":     PLCSafeGlobals(),
2697
93333d206198 Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2689
diff changeset
   388
            "OnChange":       OnChangeStateClass(),
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   389
            "WorkingDir":     self.workingdir,
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   390
            "PLCObject":      self,
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   391
            "PLCBinary":      self.PLClibraryHandle,
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   392
            "PLCGlobalsDesc": []})
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   393
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   394
        for methodname in MethodNames:
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   395
            self.python_runtime_vars["_runtime_%s" % methodname] = []
1447
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   396
972
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   397
        try:
1447
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   398
            filenames = os.listdir(self.workingdir)
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   399
            filenames.sort()
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   400
            for filename in filenames:
972
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   401
                name, ext = os.path.splitext(filename)
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   402
                if name.upper().startswith("RUNTIME") and ext.upper() == ".PY":
3750
f62625418bff automated conversion using 2to3-3.9 tool
GP Orcullo <kinsamanka@gmail.com>
parents: 3642
diff changeset
   403
                    exec(compile(open(os.path.join(self.workingdir, filename), "rb").read(), os.path.join(self.workingdir, filename), 'exec'), self.python_runtime_vars)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   404
                    for methodname in MethodNames:
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   405
                        method = self.python_runtime_vars.get("_%s_%s" % (name, methodname), None)
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   406
                        if method is not None:
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   407
                            self.python_runtime_vars["_runtime_%s" % methodname].append(method)
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   408
        except Exception:
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   409
            self.LogMessage(0, traceback.format_exc())
972
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   410
            raise
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   411
3959
d5edde0c145b Revert unwanted changes potentially breaking wxGlade support.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3950
diff changeset
   412
        self.PythonRuntimeCall("init", use_evaluator=False)
2583
e172ab28d04e Continue fixing deadlock of previous commit, this time occuring when waiting for 'cleanup' python runtime call to finish. Now 'init' and 'cleanup' python runtime calls are called directly from main thread, and aren't anymore invoked in the context of wxMainloop and/or twisted reactor.
Edouard Tisserant
parents: 2582
diff changeset
   413
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   414
        self.PythonThreadCondLock = Lock()
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   415
        self.PythonThreadCmdCond = Condition(self.PythonThreadCondLock)
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   416
        self.PythonThreadAckCond = Condition(self.PythonThreadCondLock)
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   417
        self.PythonThreadCmd = None
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   418
        self.PythonThreadAck = None
2600
0e20a0d48fae Named runtime's threads to ease debugging
Edouard Tisserant
parents: 2596
diff changeset
   419
        self.PythonThread = Thread(target=self.PythonThreadProc, name="PLCPythonThread")
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   420
        self.PythonThread.start()
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   421
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   422
    # used internaly
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   423
    def PythonRuntimeCleanup(self):
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   424
        if self.python_runtime_vars is not None:
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   425
            self.PythonThreadCommand("Finish")
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   426
            self.PythonThread.join()
3959
d5edde0c145b Revert unwanted changes potentially breaking wxGlade support.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3950
diff changeset
   427
            self.PythonRuntimeCall("cleanup", use_evaluator=False, reverse_order=True)
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   428
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   429
        self.python_runtime_vars = None
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   430
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   431
    def PythonThreadLoop(self):
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   432
        res, cmd, blkid = "None", "None", ctypes.c_void_p()
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   433
        compile_cache = {}
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   434
        while True:
3772
ec2babbd5698 str encoding fixes
GP Orcullo <kinsamanka@gmail.com>
parents: 3752
diff changeset
   435
            cmd = self._PythonIterator(res.encode(), blkid)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   436
            FBID = blkid.value
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   437
            if cmd is None:
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   438
                break
3772
ec2babbd5698 str encoding fixes
GP Orcullo <kinsamanka@gmail.com>
parents: 3752
diff changeset
   439
            cmd = cmd.decode()
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   440
            try:
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   441
                self.python_runtime_vars["FBID"] = FBID
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   442
                ccmd, AST = compile_cache.get(FBID, (None, None))
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   443
                if ccmd is None or ccmd != cmd:
867
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   444
                    AST = compile(cmd, '<plc>', 'eval')
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   445
                    compile_cache[FBID] = (cmd, AST)
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   446
                result, exp = self.evaluator(eval, AST, self.python_runtime_vars)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   447
                if exp is not None:
1052
fa7c5034c1d2 Better display of Python exceptions from Py_Eval
Edouard Tisserant
parents: 1051
diff changeset
   448
                    res = "#EXCEPTION : "+str(exp[1])
1768
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   449
                    self.LogMessage(1, ('PyEval@0x%x(Code="%s") Exception "%s"') % (
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   450
                        FBID, cmd, '\n'.join(traceback.format_exception(*exp))))
867
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   451
                else:
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   452
                    res = str(result)
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   453
                self.python_runtime_vars["FBID"] = None
2418
5587c490a070 Use python 3 compatible exception syntax everywhere
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2416
diff changeset
   454
            except Exception as e:
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   455
                res = "#EXCEPTION : "+str(e)
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   456
                self.LogMessage(1, ('PyEval@0x%x(Code="%s") Exception "%s"') % (FBID, cmd, str(e)))
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   457
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   458
    def PythonThreadProc(self):
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   459
        while True:
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   460
            self.PythonThreadCondLock.acquire()
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   461
            cmd = self.PythonThreadCmd
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   462
            while cmd is None:
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   463
                self.PythonThreadCmdCond.wait()
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   464
                cmd = self.PythonThreadCmd
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   465
            self.PythonThreadCmd = None
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   466
            self.PythonThreadCondLock.release()
2586
b89484560a97 pep8 white spaces
Edouard Tisserant
parents: 2583
diff changeset
   467
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   468
            if cmd == "PreStart":
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   469
                self.PreStartPLC()
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   470
                # Ack once PreStart done, must be finished before StartPLC
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   471
                self.PythonThreadAcknowledge(cmd)
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   472
            elif cmd == "Start":
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   473
                # Ack Immediately, for responsiveness
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   474
                self.PythonThreadAcknowledge(cmd)
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   475
                self.PythonRuntimeCall("start")
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   476
                self.LogMessage("Python extensions started")
3578
d74eb1be6abe Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents: 3577
diff changeset
   477
                self._PostStartPLC()
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   478
                self.PythonThreadLoop()
2635
ae099881d800 PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents: 2625
diff changeset
   479
                self.PythonRuntimeCall("stop", reverse_order=True)
3950
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   480
                
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   481
                # Signal that python runtime has stopped
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   482
                self.PlcStopped.set()
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   483
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   484
            elif cmd == "Finish":
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   485
                self.PythonThreadAcknowledge(cmd)
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   486
                break
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   487
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   488
    def PythonThreadAcknowledge(self, ack):
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   489
        self.PythonThreadCondLock.acquire()
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   490
        self.PythonThreadAck = ack
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   491
        self.PythonThreadAckCond.notify()
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   492
        self.PythonThreadCondLock.release()
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   493
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   494
    def PythonThreadCommand(self, cmd):
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   495
        self.PythonThreadCondLock.acquire()
2586
b89484560a97 pep8 white spaces
Edouard Tisserant
parents: 2583
diff changeset
   496
        self.PythonThreadCmd = cmd
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   497
        self.PythonThreadCmdCond.notify()
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   498
        ack = None
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   499
        while ack != cmd:
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   500
            self.PythonThreadAckCond.wait()
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   501
            ack = self.PythonThreadAck
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   502
            self.PythonThreadAck = None
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   503
2582
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   504
        self.PythonThreadCondLock.release()
8f0d6c5fd55f Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents: 2546
diff changeset
   505
2682
4d3320fdab19 Runtime: Fix typo in PLCObject leading to exception when reporting failure.
Edouard Tisserant
parents: 2678
diff changeset
   506
    def _fail(self, msg):
2646
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   507
        self.LogMessage(0, msg)
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   508
        self.PLCStatus = PlcStatus.Broken
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   509
        self.StatusChange()
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   510
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   511
    def PreStartPLC(self):
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   512
        """ 
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   513
        Here goes actions to be taken just before PLC starts, 
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   514
        with all libraries and python object already created.
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   515
        For example : restore saved proprietary parameters
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   516
        """
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   517
        pass
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   518
3578
d74eb1be6abe Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents: 3577
diff changeset
   519
    def _PostStartPLC(self):
d74eb1be6abe Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents: 3577
diff changeset
   520
        try:
d74eb1be6abe Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents: 3577
diff changeset
   521
            self.PostStartPLC()
d74eb1be6abe Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents: 3577
diff changeset
   522
        except Exception:
d74eb1be6abe Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents: 3577
diff changeset
   523
            self.LogMessage(0, 'Post Start Exception'+'\n'.join(
d74eb1be6abe Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents: 3577
diff changeset
   524
                traceback.format_exception(*sys.exc_info())))
d74eb1be6abe Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents: 3577
diff changeset
   525
2732
a3f0e4148714 Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents: 2720
diff changeset
   526
    def PostStartPLC(self):
a3f0e4148714 Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents: 2720
diff changeset
   527
        """ 
a3f0e4148714 Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents: 2720
diff changeset
   528
        Here goes actions to be taken after PLC is started, 
a3f0e4148714 Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents: 2720
diff changeset
   529
        with all libraries and python object already created,
a3f0e4148714 Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents: 2720
diff changeset
   530
        and python extensions "Start" methods being called.
a3f0e4148714 Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents: 2720
diff changeset
   531
        This is called before python thread processing py_eval blocks starts.
a3f0e4148714 Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents: 2720
diff changeset
   532
        For example : attach additional ressource to web services
a3f0e4148714 Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents: 2720
diff changeset
   533
        """
a3f0e4148714 Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents: 2720
diff changeset
   534
        pass
a3f0e4148714 Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents: 2720
diff changeset
   535
1988
19ca02e8074f PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents: 1987
diff changeset
   536
    @RunInMain
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   537
    def StartPLC(self):
2608
a332f989f0b8 Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents: 2602
diff changeset
   538
3950
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   539
        # Prevent accidental call to StartPLC when already Started
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   540
        if self.PLCStatus != PlcStatus.Stopped:
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   541
            self.LogMessage(0,_("Problem starting PLC : PLC is not Stopped"))
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   542
            return
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   543
2608
a332f989f0b8 Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents: 2602
diff changeset
   544
        if self.PLClibraryHandle is None:
a332f989f0b8 Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents: 2602
diff changeset
   545
            if not self.LoadPLC():
2646
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   546
                self._fail(_("Problem starting PLC : can't load PLC"))
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   547
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
   548
        if self.CurrentPLCFilename is not None and self.PLCStatus == PlcStatus.Stopped:
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   549
            self.PythonThreadCommand("PreStart")
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   550
            c_argv = ctypes.c_char_p * len(self.argv)
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   551
            res = self._startPLC(len(self.argv), c_argv(*self.argv))
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   552
            if res == 0:
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   553
                self.LogMessage("PLC started")
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
   554
                self.PLCStatus = PlcStatus.Started
1442
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   555
                self.StatusChange()
2720
971bb3503957 PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents: 2702
diff changeset
   556
                self.PythonThreadCommand("Start")
3950
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   557
                self.PlcStopped.clear()
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   558
            else:
2646
d692e01d94f4 PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents: 2635
diff changeset
   559
                self._fail(_("Problem starting PLC : error %d" % res))
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   560
1988
19ca02e8074f PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents: 1987
diff changeset
   561
    @RunInMain
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   562
    def StopPLC(self):
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
   563
        if self.PLCStatus == PlcStatus.Started:
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   564
            self.LogMessage("PLC stopped")
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   565
            self._stopPLC()
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   566
            if self.TraceThread is not None:
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   567
                self.TraceThread.join()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   568
                self.TraceThread = None
3950
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   569
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   570
            # Wait for python runtime stop to complete
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   571
            if self.PlcStopped.wait(timeout=5):
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   572
                self.PLCStatus = PlcStatus.Stopped
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   573
                self.StatusChange()
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   574
            else:
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   575
                self._fail(_("PLC timed out while stopping"))
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   576
                
79bdee48ced8 Python runtime: ensure that python thread finished before returning from StopPLC.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3941
diff changeset
   577
        return self.PLCStatus == PlcStatus.Stopped
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   578
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   579
    def GetPLCstatus(self):
2602
19dc6b830e7d If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents: 2600
diff changeset
   580
        try:
19dc6b830e7d If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents: 2600
diff changeset
   581
            return self._GetPLCstatus()
19dc6b830e7d If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents: 2600
diff changeset
   582
        except EOFError:
3884
34da877021d5 Replace PYRO with ERPC. Work In Progress.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3881
diff changeset
   583
            return (PlcStatus.Disconnected, [0]*LogLevelsCount)
2602
19dc6b830e7d If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents: 2600
diff changeset
   584
19dc6b830e7d If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents: 2600
diff changeset
   585
    @RunInMain
19dc6b830e7d If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents: 2600
diff changeset
   586
    def _GetPLCstatus(self):
3750
f62625418bff automated conversion using 2to3-3.9 tool
GP Orcullo <kinsamanka@gmail.com>
parents: 3642
diff changeset
   587
        return self.PLCStatus, list(map(self.GetLogCount, range(LogLevelsCount)))
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   588
1988
19ca02e8074f PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents: 1987
diff changeset
   589
    @RunInMain
2324
1cf3768ebf85 Automatically get PSK and ID when connecting to PYRO[S], so that future connection through PYROS can use that same key. Also fixed case to UPPER for *PSK.
Edouard Tisserant
parents: 2309
diff changeset
   590
    def GetPLCID(self):
2492
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2487
diff changeset
   591
        return getPSKID(partial(self.LogMessage, 0))
2324
1cf3768ebf85 Automatically get PSK and ID when connecting to PYRO[S], so that future connection through PYROS can use that same key. Also fixed case to UPPER for *PSK.
Edouard Tisserant
parents: 2309
diff changeset
   592
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   593
    def _init_blobs(self):
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   594
        self.blobs = {}
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   595
        if os.path.exists(self.tmpdir):
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   596
            shutil.rmtree(self.tmpdir)
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   597
        os.mkdir(self.tmpdir)
2492
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2487
diff changeset
   598
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   599
    @RunInMain
2487
6a4f9a061994 Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents: 2486
diff changeset
   600
    def SeedBlob(self, seed):
2540
fca79ca84272 Replace md5 module with hashlib
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2537
diff changeset
   601
        blob = (mkstemp(dir=self.tmpdir) + (hashlib.new('md5'),))
2651
231f8bd2cd7d Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents: 2646
diff changeset
   602
        _fd, _path, md5sum = blob
2487
6a4f9a061994 Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents: 2486
diff changeset
   603
        md5sum.update(seed)
6a4f9a061994 Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents: 2486
diff changeset
   604
        newBlobID = md5sum.digest()
6a4f9a061994 Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents: 2486
diff changeset
   605
        self.blobs[newBlobID] = blob
6a4f9a061994 Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents: 2486
diff changeset
   606
        return newBlobID
6a4f9a061994 Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents: 2486
diff changeset
   607
6a4f9a061994 Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents: 2486
diff changeset
   608
    @RunInMain
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   609
    def AppendChunkToBlob(self, data, blobID):
2487
6a4f9a061994 Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents: 2486
diff changeset
   610
        blob = self.blobs.pop(blobID, None)
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   611
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   612
        if blob is None:
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   613
            return None
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   614
2651
231f8bd2cd7d Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents: 2646
diff changeset
   615
        fd, _path, md5sum = blob
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   616
        md5sum.update(data)
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   617
        newBlobID = md5sum.digest()
2651
231f8bd2cd7d Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents: 2646
diff changeset
   618
        os.write(fd, data)
2487
6a4f9a061994 Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents: 2486
diff changeset
   619
        self.blobs[newBlobID] = blob
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   620
        return newBlobID
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   621
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   622
    @RunInMain
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   623
    def PurgeBlobs(self):
3750
f62625418bff automated conversion using 2to3-3.9 tool
GP Orcullo <kinsamanka@gmail.com>
parents: 3642
diff changeset
   624
        for fd, _path, _md5sum in list(self.blobs.values()):
2651
231f8bd2cd7d Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents: 2646
diff changeset
   625
            os.close(fd)
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   626
        self._init_blobs()
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   627
2702
f0a70f0246da Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents: 2698
diff changeset
   628
    def BlobAsFile(self, blobID, newpath):
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   629
        blob = self.blobs.pop(blobID, None)
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   630
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   631
        if blob is None:
3772
ec2babbd5698 str encoding fixes
GP Orcullo <kinsamanka@gmail.com>
parents: 3752
diff changeset
   632
            raise Exception(
ec2babbd5698 str encoding fixes
GP Orcullo <kinsamanka@gmail.com>
parents: 3752
diff changeset
   633
                _(f"Missing data to create file: {newpath}").decode())
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   634
2702
f0a70f0246da Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents: 2698
diff changeset
   635
        self._BlobAsFile(blob, newpath)
f0a70f0246da Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents: 2698
diff changeset
   636
f0a70f0246da Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents: 2698
diff changeset
   637
    def _BlobAsFile(self, blob, newpath):
2651
231f8bd2cd7d Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents: 2646
diff changeset
   638
        fd, path, _md5sum = blob
231f8bd2cd7d Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents: 2646
diff changeset
   639
        fobj = os.fdopen(fd)
231f8bd2cd7d Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents: 2646
diff changeset
   640
        fobj.flush()
231f8bd2cd7d Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents: 2646
diff changeset
   641
        os.fsync(fd)
231f8bd2cd7d Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents: 2646
diff changeset
   642
        fobj.close()
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   643
        shutil.move(path, newpath)
2492
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2487
diff changeset
   644
2594
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   645
    def _extra_files_log_path(self):
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   646
        return os.path.join(self.workingdir, "extra_files.txt")
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   647
2596
779e8dbf1ee1 Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents: 2594
diff changeset
   648
    def RepairPLC(self):
779e8dbf1ee1 Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents: 2594
diff changeset
   649
        self.PurgePLC()
3642
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3578
diff changeset
   650
        MainWorker.finish()
2596
779e8dbf1ee1 Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents: 2594
diff changeset
   651
2594
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   652
    @RunInMain
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   653
    def PurgePLC(self):
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   654
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   655
        extra_files_log = self._extra_files_log_path()
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   656
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   657
        old_PLC_filename = os.path.join(self.workingdir, self.CurrentPLCFilename) \
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   658
            if self.CurrentPLCFilename is not None \
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   659
            else None
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   660
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   661
        try:
2613
e05458405ff4 Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents: 2612
diff changeset
   662
            allfiles = open(extra_files_log, "rt").readlines()
e05458405ff4 Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents: 2612
diff changeset
   663
            allfiles.extend([extra_files_log, old_PLC_filename, self._GetMD5FileName()])
2594
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   664
        except Exception:
2613
e05458405ff4 Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents: 2612
diff changeset
   665
            self.LogMessage("No files to purge")
e05458405ff4 Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents: 2612
diff changeset
   666
            allfiles = []
2594
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   667
2596
779e8dbf1ee1 Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents: 2594
diff changeset
   668
        for filename in allfiles:
2613
e05458405ff4 Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents: 2612
diff changeset
   669
            if filename:
e05458405ff4 Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents: 2612
diff changeset
   670
                filename = filename.strip()
e05458405ff4 Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents: 2612
diff changeset
   671
                try:
e05458405ff4 Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents: 2612
diff changeset
   672
                    os.remove(os.path.join(self.workingdir, filename))
e05458405ff4 Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents: 2612
diff changeset
   673
                except Exception:
e05458405ff4 Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents: 2612
diff changeset
   674
                    self.LogMessage("Couldn't purge " + filename)
2596
779e8dbf1ee1 Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents: 2594
diff changeset
   675
2594
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   676
        self.PLCStatus = PlcStatus.Empty
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   677
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   678
        # TODO: PLCObject restart
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   679
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   680
    @RunInMain
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   681
    def NewPLC(self, md5sum, plc_object, extrafiles):
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
   682
        if self.PLCStatus in [PlcStatus.Stopped, PlcStatus.Empty, PlcStatus.Broken]:
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   683
            NewFileName = md5sum + lib_ext
2594
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   684
            extra_files_log = self._extra_files_log_path()
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   685
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   686
            new_PLC_filename = os.path.join(self.workingdir, NewFileName)
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   687
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   688
            self.UnLoadPLC()
1045
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   689
2594
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   690
            self.PurgePLC()
f1e182818434 Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents: 2586
diff changeset
   691
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   692
            self.LogMessage("NewPLC (%s)" % md5sum)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   693
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   694
            try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   695
                # Create new PLC file
2702
f0a70f0246da Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents: 2698
diff changeset
   696
                self.BlobAsFile(plc_object, new_PLC_filename)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   697
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   698
                # Then write the files
2442
b13f021c68a5 python3 support: pylint, W1607 # (file-builtin) file built-in referenced
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2432
diff changeset
   699
                log = open(extra_files_log, "w")
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   700
                for fname, blobID in extrafiles:
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   701
                    fpath = os.path.join(self.workingdir, fname)
2702
f0a70f0246da Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents: 2698
diff changeset
   702
                    self.BlobAsFile(blobID, fpath)
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   703
                    log.write(fname+'\n')
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   704
2653
8b612b357679 Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents: 2651
diff changeset
   705
                # Store new PLC filename based on md5 key
8b612b357679 Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents: 2651
diff changeset
   706
                with open(self._GetMD5FileName(), "w") as f:
8b612b357679 Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents: 2651
diff changeset
   707
                    f.write(md5sum)
8b612b357679 Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents: 2651
diff changeset
   708
                    f.flush()
8b612b357679 Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents: 2651
diff changeset
   709
                    os.fsync(f.fileno())
8b612b357679 Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents: 2651
diff changeset
   710
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   711
                # Store new PLC filename
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   712
                self.CurrentPLCFilename = NewFileName
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   713
            except Exception:
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
   714
                self.PLCStatus = PlcStatus.Broken
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   715
                self.StatusChange()
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   716
                PLCprint(traceback.format_exc())
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   717
                return False
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   718
2463
8742337a9fe3 Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents: 2459
diff changeset
   719
            if self.LoadPLC():
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
   720
                self.PLCStatus = PlcStatus.Stopped
3282
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   721
                self.StatusChange()
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   722
            else:
3282
725d3e9ac913 Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents: 2732
diff changeset
   723
                self._fail(_("Problem installing new PLC : can't load PLC"))
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   724
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
   725
            return self.PLCStatus == PlcStatus.Stopped
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   726
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   727
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   728
    def MatchMD5(self, MD5):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   729
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   730
            last_md5 = open(self._GetMD5FileName(), "r").read()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   731
            return last_md5 == MD5
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   732
        except Exception:
1440
e8daabf2c438 Runtime : Added PLCobject methods registring. IDE : Added WAMP connector. Still need some fixes
Edouard Tisserant
parents: 1438
diff changeset
   733
            pass
e8daabf2c438 Runtime : Added PLCobject methods registring. IDE : Added WAMP connector. Still need some fixes
Edouard Tisserant
parents: 1438
diff changeset
   734
        return False
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   735
2485
ef327451d067 Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents: 2463
diff changeset
   736
    @RunInMain
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   737
    def SetTraceVariablesList(self, idxs):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   738
        """
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   739
        Call ctype imported function to append
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   740
        these indexes to registred variables in PLC debugger
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   741
        """
2485
ef327451d067 Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents: 2463
diff changeset
   742
        self.DebugToken += 1
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   743
        if idxs:
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   744
            # suspend but dont disable
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   745
            if self._suspendDebug(False) == 0:
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   746
                # keep a copy of requested idx
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   747
                self._ResetDebugVariables()
3887
2df45e4bd500 Fix variable forcing. Now works with eRPC. PLCObject API changed.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3884
diff changeset
   748
                for idx, force in idxs:
2df45e4bd500 Fix variable forcing. Now works with eRPC. PLCObject API changed.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3884
diff changeset
   749
                    res = self._RegisterDebugVariable(idx, force, 0 if force is None else len(force))
3395
93ad018fb602 RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents: 3282
diff changeset
   750
                    if res != 0:
93ad018fb602 RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents: 3282
diff changeset
   751
                        self._resumeDebug()
93ad018fb602 RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents: 3282
diff changeset
   752
                        self._suspendDebug(True)
93ad018fb602 RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents: 3282
diff changeset
   753
                        return -res
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   754
                self._TracesSwap()
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   755
                self._resumeDebug()
2485
ef327451d067 Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents: 2463
diff changeset
   756
                return self.DebugToken
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   757
        else:
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   758
            self._suspendDebug(True)
3941
09aa8a10026c ERPC: fix SetTraceVariablesList interface
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3887
diff changeset
   759
        return -5 # DEBUG_SUSPENDED
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   760
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   761
    def _TracesSwap(self):
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   762
        self.LastSwapTrace = time()
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
   763
        if self.TraceThread is None and self.PLCStatus == PlcStatus.Started:
2600
0e20a0d48fae Named runtime's threads to ease debugging
Edouard Tisserant
parents: 2596
diff changeset
   764
            self.TraceThread = Thread(target=self.TraceThreadProc, name="PLCTrace")
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   765
            self.TraceThread.start()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   766
        self.TraceLock.acquire()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   767
        Traces = self.Traces
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   768
        self.Traces = []
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   769
        self.TraceLock.release()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   770
        return Traces
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   771
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   772
    @RunInMain
2485
ef327451d067 Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents: 2463
diff changeset
   773
    def GetTraceVariables(self, DebugToken):
2546
f5dae7b85906 Fix pylint warning [C0325(superfluous-parens), ] Unnecessary parens after u'if' keyword
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2540
diff changeset
   774
        if DebugToken is not None and DebugToken == self.DebugToken:
2485
ef327451d067 Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents: 2463
diff changeset
   775
            return self.PLCStatus, self._TracesSwap()
ef327451d067 Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents: 2463
diff changeset
   776
        return PlcStatus.Broken, []
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   777
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   778
    def TraceThreadProc(self):
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   779
        """
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   780
        Return a list of traces, corresponding to the list of required idx
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   781
        """
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   782
        self._resumeDebug()  # Re-enable debugger
2416
1ca207782dde Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1997
diff changeset
   783
        while self.PLCStatus == PlcStatus.Started:
450
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   784
            tick = ctypes.c_uint32()
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   785
            size = ctypes.c_uint32()
1075
8078c01ae464 Now Debug Buffer Unpacking is a separate function, declared in typemapping.py
Edouard Tisserant
parents: 1074
diff changeset
   786
            buff = ctypes.c_void_p()
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   787
            TraceBuffer = None
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   788
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   789
            self.PLClibraryLock.acquire()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   790
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   791
            res = self._GetDebugData(ctypes.byref(tick),
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   792
                                     ctypes.byref(size),
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   793
                                     ctypes.byref(buff))
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   794
            if res == 0:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   795
                if size.value:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   796
                    TraceBuffer = ctypes.string_at(buff.value, size.value)
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   797
                self._FreeDebugData()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   798
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   799
            self.PLClibraryLock.release()
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   800
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   801
            # leave thread if GetDebugData isn't happy.
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   802
            if res != 0:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   803
                break
1990
2e0fbdd152de Fixed Xenomai 3 PLC stop freeze. Now use explicit finish command with pipes. Closing both ends of pipes doesn't abort blocking read anymore.
Edouard Tisserant
parents: 1988
diff changeset
   804
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   805
            if TraceBuffer is not None:
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   806
                self.TraceLock.acquire()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   807
                lT = len(self.Traces)
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   808
                if lT != 0 and lT * len(self.Traces[0]) > 1024 * 1024:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   809
                    self.Traces.pop(0)
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   810
                self.Traces.append((tick.value, TraceBuffer))
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   811
                self.TraceLock.release()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   812
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   813
            # TraceProc stops here if Traces not polled for 3 seconds
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   814
            traces_age = time() - self.LastSwapTrace
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   815
            if traces_age > 3:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   816
                self.TraceLock.acquire()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   817
                self.Traces = []
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   818
                self.TraceLock.release()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   819
                self._suspendDebug(True)  # Disable debugger
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   820
                break
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   821
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   822
        self.TraceThread = None
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   823
3861
7e17f7e02a2b Runtime: add GetVersions() call to PLCObject, use it in web settings and expose it in WAMP and Pyro.
Edouard Tisserant
parents: 3578
diff changeset
   824
    def GetVersions(self):
7e17f7e02a2b Runtime: add GetVersions() call to PLCObject, use it in web settings and expose it in WAMP and Pyro.
Edouard Tisserant
parents: 3578
diff changeset
   825
        return platform_module.system() + " " + platform_module.release()
7e17f7e02a2b Runtime: add GetVersions() call to PLCObject, use it in web settings and expose it in WAMP and Pyro.
Edouard Tisserant
parents: 3578
diff changeset
   826
4032
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   827
    @RunInMain
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   828
    def ExtendedCall(self, method, argument):
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   829
        """ Dispatch argument to registered service """
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   830
        return self.extended_calls[method](argument)
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   831
4034
6359536d60a9 python_runtime: fix ExtendedCall register/unregistering.
Edouard Tisserant <edouard@beremiz.fr>
parents: 4032
diff changeset
   832
    def RegisterExtendedCall(self, method, callback):
4032
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   833
        self.extended_calls[method] = callback
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   834
4034
6359536d60a9 python_runtime: fix ExtendedCall register/unregistering.
Edouard Tisserant <edouard@beremiz.fr>
parents: 4032
diff changeset
   835
    def UnregisterExtendedCall(self, method):
4032
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   836
        del self.extended_calls[method]
1ffff67678ad Add ExtendedCall to PLCObject as a replacement of RemoteExec and reflect it in eRPC interface.
Edouard Tisserant <edouard@beremiz.fr>
parents: 3959
diff changeset
   837