@@ -320,7 +391,9 @@ Setzt Prozessabbild auf NULL.
RevPiPlc.newlogfile
newlogfile()
-
+
+Konfiguriert die FileHandler auf neue Logdatei.
+
RevPiPlc.run
run()
diff --git a/doc/revpipyload.revpipyload.html b/doc/revpipyload.revpipyload.html
deleted file mode 100644
index 42bae03..0000000
--- a/doc/revpipyload.revpipyload.html
+++ /dev/null
@@ -1,555 +0,0 @@
-
-
-revpipyload.revpipyload
-
-
-
-
-revpipyload.revpipyload
-
-
-Global Attributes
-
-| configrsc |
| picontrolreset |
| procimg |
| pyloadverion |
-
-
-Classes
-
-
-| LogReader |
-Ermoeglicht den Zugriff auf die Logdateien. |
-
-| RevPiPlc |
-Verwaltet das PLC Python Programm. |
-
-| RevPiPyLoad |
-Hauptklasse, die alle Funktionen zur Verfuegung stellt. |
-
-
-
-Functions
-
-
-
-LogReader
-
-Ermoeglicht den Zugriff auf die Logdateien.
-
- Beinhaltet Funktionen fuer den Abruf der gesamten Logdatei fuer das
- RevPiPyLoad-System und die Logdatei der PLC-Anwendung.
- Ausserdem koennen nur neue Zeilen abgerufen werden, um eine dynamische
- Logansicht zu ermoeglichen.
-
-
-
-
-Derived from
-None
-
-Class Attributes
-
-
-Class Methods
-
-
-Methods
-
-
-| LogReader |
-Instantiiert LogReader-Klasse. |
-
-| get_applines |
-Gibt neue Zeilen ab letzen Aufruf zurueck. |
-
-| get_applog |
-Gibt die gesamte Logdatei zurueck. |
-
-| get_plclines |
-Gibt neue Zeilen ab letzen Aufruf zurueck. |
-
-| get_plclog |
-Gibt die gesamte Logdatei zurueck. |
-
-
-
-Static Methods
-
-
-
-LogReader (Constructor)
-LogReader()
-
-Instantiiert LogReader-Klasse.
-
-
-LogReader.get_applines
-get_applines()
-
-Gibt neue Zeilen ab letzen Aufruf zurueck.
-
-- Returns:
--
-list() mit neuen Zeilen
-
-
-
-LogReader.get_applog
-get_applog()
-
-Gibt die gesamte Logdatei zurueck.
-
-- Returns:
--
-str() mit Logdaten
-
-
-
-LogReader.get_plclines
-get_plclines()
-
-Gibt neue Zeilen ab letzen Aufruf zurueck.
-
-- Returns:
--
-list() mit neuen Zeilen
-
-
-
-LogReader.get_plclog
-get_plclog()
-
-Gibt die gesamte Logdatei zurueck.
-
-- Returns:
--
-str() mit Logdaten
-
-
-
-
-
-RevPiPlc
-
-Verwaltet das PLC Python Programm.
-
- Dieser Thread startet das PLC Python Programm und ueberwacht es. Sollte es
- abstuerzen kann es automatisch neu gestartet werden. Die Ausgaben des
- Programms werden in eine Logdatei umgeleitet, damit der Entwickler sein
- Programm analysieren und debuggen kann.
-
-
-
-
-Derived from
-Thread
-
-Class Attributes
-
-
-Class Methods
-
-
-Methods
-
-
-| RevPiPlc |
-Instantiiert RevPiPlc-Klasse. |
-
-| _zeroprocimg |
-Setzt Prozessabbild auf NULL. |
-
-| run |
-Fuehrt PLC-Programm aus und ueberwacht es. |
-
-| stop |
-Beendet PLC-Programm. |
-
-
-
-Static Methods
-
-
-
-RevPiPlc (Constructor)
-RevPiPlc(program, pversion)
-
-Instantiiert RevPiPlc-Klasse.
-
-
-RevPiPlc._zeroprocimg
-_zeroprocimg()
-
-Setzt Prozessabbild auf NULL.
-
-
-RevPiPlc.run
-run()
-
-Fuehrt PLC-Programm aus und ueberwacht es.
-
-
-RevPiPlc.stop
-stop()
-
-Beendet PLC-Programm.
-
-
-
-
-RevPiPyLoad
-
-Hauptklasse, die alle Funktionen zur Verfuegung stellt.
-
- Hier wird die gesamte Konfiguraiton eingelesen und der ggf. aktivierte
- XML-RPC-Server gestartet.
-
-
-
-
-Derived from
-proginit.ProgInit
-
-Class Attributes
-
-
-Class Methods
-
-
-Methods
-
-
-Static Methods
-
-
-
-RevPiPyLoad (Constructor)
-RevPiPyLoad()
-
-Instantiiert RevPiPyLoad-Klasse.
-
-
-RevPiPyLoad._loadconfig
-_loadconfig()
-
-Load configuration file and setup modul.
-
-
-RevPiPyLoad._plcthread
-_plcthread()
-
-Konfiguriert den PLC-Thread fuer die Ausfuehrung.
-
-- Returns:
--
-PLC-Thread Object or None
-
-
-
-RevPiPyLoad._sigexit
-_sigexit(signum, frame)
-
-Signal handler to clean and exit program.
-
-
-RevPiPyLoad._sigloadconfig
-_sigloadconfig(signum, frame)
-
-Signal handler to load configuration.
-
-
-RevPiPyLoad.packapp
-packapp(mode="tar", pictory=False)
-
-Erzeugt aus dem PLC-Programm ein TAR-File.
-
-- mode:
--
-Packart 'tar' oder 'zip'
-
- pictory:
--
-piCtory Konfiguration mit einpacken
-
-
-- Returns:
--
-Dateinamen des Archivs
-
-
-
-RevPiPyLoad.start
-start()
-
-Start plcload and PLC python program.
-
-
-RevPiPyLoad.stop
-stop()
-
-Stop PLC python program and plcload.
-
-
-RevPiPyLoad.xml_getconfig
-xml_getconfig()
-
-Uebertraegt die RevPiPyLoad Konfiguration.
-
-- Returns:
--
-dict() der Konfiguration
-
-
-
-RevPiPyLoad.xml_getfilelist
-xml_getfilelist()
-
-Uebertraegt die Dateiliste vom plcworkdir.
-
-- Returns:
--
-list() mit Dateinamen
-
-
-
-RevPiPyLoad.xml_getpictoryrsc
-xml_getpictoryrsc()
-
-Gibt die config.rsc Datei von piCotry zurueck.
-
-- Returns:
--
-xmlrpc.client.Binary()
-
-
-
-RevPiPyLoad.xml_getprocimg
-xml_getprocimg()
-
-Gibt die Rohdaten aus piControl0 zurueck.
-
-- Returns:
--
-xmlrpc.client.Binary()
-
-
-
-RevPiPyLoad.xml_plcdownload
-xml_plcdownload(mode="tar", pictory=False)
-
-Uebertraegt ein Archiv vom plcworkdir.
-
-- mode:
--
-Archivart 'tar' 'zip'
-
- pictory:
--
-piCtory Konfiguraiton mit einpacken
-
-
-- Returns:
--
-Binary() mit Archivdatei
-
-
-
-RevPiPyLoad.xml_plcexitcode
-xml_plcexitcode()
-
-Gibt den aktuellen exitcode vom PLC Programm zurueck.
-
-- Returns:
--
-int() exitcode oder -1 lauuft noch -2 lief nie
-
-
-
-RevPiPyLoad.xml_plcrunning
-xml_plcrunning()
-
-Prueft ob das PLC Programm noch lauft.
-
-- Returns:
--
-True, wenn das PLC Programm noch lauft
-
-
-
-RevPiPyLoad.xml_plcstart
-xml_plcstart()
-
-Startet das PLC Programm.
-
-- Returns:
--
-int() Status:
- -1 Programm lauft noch
- 100 Fehler
-
-
-
-RevPiPyLoad.xml_plcstop
-xml_plcstop()
-
-Stoppt das PLC Programm.
-
-- Returns:
--
-int() Exitcode vom PLC Programm
-
-
-
-RevPiPyLoad.xml_plcupload
-xml_plcupload(filedata, filename)
-
-Empfaengt Dateien fuer das PLC Programm.
-
-- filedata:
--
-GZIP Binary data der datei
-
- filename:
--
-Name inkl. Unterverzeichnis der Datei
-
-
-- Returns:
--
-Ture, wenn Datei erfolgreich gespeichert wurde
-
-
-
-RevPiPyLoad.xml_plcuploadclean
-xml_plcuploadclean()
-
-Loescht das gesamte plcworkdir Verzeichnis.
-
-- Returns:
--
-True, wenn erfolgreich
-
-
-
-RevPiPyLoad.xml_reload
-xml_reload()
-
-Startet RevPiPyLoad neu und verwendet neue Konfiguraiton.
-
-
-RevPiPyLoad.xml_setconfig
-xml_setconfig(dc, loadnow=False)
-
-Empfaengt die RevPiPyLoad Konfiguration.
-
-
-RevPiPyLoad.xml_setpictoryrsc
-xml_setpictoryrsc(filebytes, reset=False)
-
-Schreibt die config.rsc Datei von piCotry.
-
-- filebytes:
--
-xmlrpc.client.Binary()-Objekt
-
- reset:
--
-Reset piControl Device
-
-
-- Returns:
--
-Statuscode:
- 0 Alles erfolgreich
- -1 Kann JSON-Datei nicht laden
- -2 piCtory Elemente in JSON-Datei nicht gefunden
- -3 Konnte Konfiguraiton nicht schreiben
- Positive Zahl ist exitcode von piControlReset
-
-
-
-
-
\ No newline at end of file
diff --git a/revpipyload.api b/revpipyload.api
new file mode 100644
index 0000000..080cf22
--- /dev/null
+++ b/revpipyload.api
@@ -0,0 +1,58 @@
+proginit.cleanup?4()
+proginit.configure?4()
+proginit.forked?7
+proginit.globalconffile?7
+proginit.logapp?7
+proginit.logger?7
+proginit.logplc?7
+proginit.pargs?7
+proginit.startdir?7
+revpipyload.LogReader.closeall?4()
+revpipyload.LogReader.get_applines?4()
+revpipyload.LogReader.get_applog?4()
+revpipyload.LogReader.get_plclines?4()
+revpipyload.LogReader.get_plclog?4()
+revpipyload.LogReader?1()
+revpipyload.PipeLogwriter.__del__?6()
+revpipyload.PipeLogwriter._configurefh?5()
+revpipyload.PipeLogwriter.logline?4(message)
+revpipyload.PipeLogwriter.newlogfile?4()
+revpipyload.PipeLogwriter.run?4()
+revpipyload.PipeLogwriter.stop?4()
+revpipyload.PipeLogwriter?1(logfilename)
+revpipyload.RevPiPlc._configureplw?5()
+revpipyload.RevPiPlc._setuppopen?5()
+revpipyload.RevPiPlc._spopen?5(lst_proc)
+revpipyload.RevPiPlc._zeroprocimg?5()
+revpipyload.RevPiPlc.newlogfile?4()
+revpipyload.RevPiPlc.run?4()
+revpipyload.RevPiPlc.stop?4()
+revpipyload.RevPiPlc?1(program, arguments, pversion)
+revpipyload.RevPiPyLoad._loadconfig?5()
+revpipyload.RevPiPyLoad._plcthread?5()
+revpipyload.RevPiPyLoad._sigexit?5(signum, frame)
+revpipyload.RevPiPyLoad._sigloadconfig?5(signum, frame)
+revpipyload.RevPiPyLoad._signewlogfile?5(signum, frame)
+revpipyload.RevPiPyLoad.packapp?4(mode="tar", pictory=False)
+revpipyload.RevPiPyLoad.root?7
+revpipyload.RevPiPyLoad.start?4()
+revpipyload.RevPiPyLoad.stop?4()
+revpipyload.RevPiPyLoad.xml_getconfig?4()
+revpipyload.RevPiPyLoad.xml_getfilelist?4()
+revpipyload.RevPiPyLoad.xml_getpictoryrsc?4()
+revpipyload.RevPiPyLoad.xml_getprocimg?4()
+revpipyload.RevPiPyLoad.xml_plcdownload?4(mode="tar", pictory=False)
+revpipyload.RevPiPyLoad.xml_plcexitcode?4()
+revpipyload.RevPiPyLoad.xml_plcrunning?4()
+revpipyload.RevPiPyLoad.xml_plcstart?4()
+revpipyload.RevPiPyLoad.xml_plcstop?4()
+revpipyload.RevPiPyLoad.xml_plcupload?4(filedata, filename)
+revpipyload.RevPiPyLoad.xml_plcuploadclean?4()
+revpipyload.RevPiPyLoad.xml_reload?4()
+revpipyload.RevPiPyLoad.xml_setconfig?4(dc, loadnow=False)
+revpipyload.RevPiPyLoad.xml_setpictoryrsc?4(filebytes, reset=False)
+revpipyload.RevPiPyLoad?1()
+revpipyload.configrsc?7
+revpipyload.picontrolreset?7
+revpipyload.procimg?7
+revpipyload.pyloadverion?7
diff --git a/revpipyload.bas b/revpipyload.bas
new file mode 100644
index 0000000..9aaa29e
--- /dev/null
+++ b/revpipyload.bas
@@ -0,0 +1,2 @@
+PipeLogwriter Thread
+RevPiPlc Thread
diff --git a/revpipyload/proginit.py b/revpipyload/proginit.py
index 4898188..ac51060 100644
--- a/revpipyload/proginit.py
+++ b/revpipyload/proginit.py
@@ -7,10 +7,10 @@
# -*- coding: utf-8 -*-
"""Main functions of our program."""
import logging
+import os.path
import sys
from argparse import ArgumentParser
from os import fork as osfork
-from os.path import exists as ospexists
forked = False
@@ -19,6 +19,7 @@ logapp = "revpipyloadapp.log"
logplc = "revpipyload.log"
logger = None
pargs = None
+startdir = None
def cleanup():
@@ -54,13 +55,22 @@ def configure():
global pargs
pargs = parser.parse_args()
+ # Pfade absolut umschreiben
+ global startdir
+ if startdir is None:
+ startdir = os.path.abspath(".")
+ if pargs.conffile is not None and os.path.dirname(pargs.conffile) == "":
+ pargs.conffile = os.path.join(startdir, pargs.confffile)
+ if pargs.logfile is not None and os.path.dirname(pargs.logfile) == "":
+ pargs.logfile = os.path.join(startdir, pargs.logfile)
+
# Prüfen ob als Daemon ausgeführt werden soll
global forked
pidfile = "/var/run/revpipyload.pid"
pid = 0
if pargs.daemon and not forked:
# Prüfen ob daemon schon läuft
- if ospexists(pidfile):
+ if os.path.exists(pidfile):
raise SystemError(
"program already running as daemon. check {}".format(pidfile)
)
@@ -74,16 +84,17 @@ def configure():
else:
forked = True
+ global logapp
+ global logplc
if pargs.daemon:
- global logapp
- global logplc
-
# Ausgaben umhängen in Logfile
logapp = "/var/log/revpipyloadapp"
logplc = "/var/log/revpipyload"
pargs.conffile = "/etc/revpipyload/revpipyload.conf"
sys.stdout = open(logplc, "a")
sys.stderr = sys.stdout
+ elif pargs.logfile is not None:
+ logplc = pargs.logfile
# Initialize configparser globalconfig
global globalconffile
diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py
index 8824ac9..fa9f274 100755
--- a/revpipyload/revpipyload.py
+++ b/revpipyload/revpipyload.py
@@ -43,8 +43,9 @@ from configparser import ConfigParser
from json import loads as jloads
from re import match as rematch
from shutil import rmtree
+from sys import stdout as sysstdout
from tempfile import mktemp
-from threading import Thread, Event
+from threading import Thread, Event, Lock
from time import sleep, asctime
from xmlrpc.client import Binary
from xmlrpc.server import SimpleXMLRPCServer
@@ -162,35 +163,107 @@ class LogReader():
class PipeLogwriter(Thread):
- def __init__(self, fh):
+ """File PIPE fuer das Schreiben des APP Log.
+
+ Spezieller LogFile-Handler fuer die Ausgabe des subprocess fuer das Python
+ PLC Programm. Die Ausgabe kann nicht auf einen neuen FileHandler
+ umgeschrieben werden. Dadurch waere es nicht moeglich nach einem logrotate
+ die neue Datei zu verwenden. Ueber die PIPE wird dies umgangen.
+
+ """
+
+ def __init__(self, logfilename):
+ """Instantiiert PipeLogwriter-Klasse.
+ @param logfilename: Dateiname fuer Logdatei"""
super().__init__()
self._exit = Event()
- self.fh = fh
- if fh is None:
- self.pipeout = None
+ self._fh = None
+ self._lckfh = Lock()
+ self.logfile = logfilename
+
+ # Logdatei öffnen
+ self._fh = self._configurefh()
+
+ # Pipes öffnen
+ self._fdr, self.fdw = os.pipe()
+ proginit.logger.debug("pipe fd read: {} / write: {}".format(
+ self._fdr, self.fdw
+ ))
+
+ def __del__(self):
+ if self._fh is not None:
+ self._fh.close()
+
+ def _configurefh(self):
+ """Konfiguriert den FileHandler fuer Ausgaben der PLCAPP.
+ @returns: FileHandler-Objekt"""
+ proginit.logger.debug("enter PipeLogwriter._configurefh()")
+
+ dirname = os.path.dirname(self.logfile)
+
+ proginit.logger.debug("dirname = {}".format(os.path.abspath(dirname)))
+
+ if os.access(dirname, os.R_OK | os.W_OK):
+ logfile = open(self.logfile, "a")
else:
- self._pipein, self.pipeout = os.pipe()
+ raise RuntimeError("can not open logfile {}".format(self.logfile))
+
+ proginit.logger.debug("leave PipeLogwriter._configurefh()")
+ return logfile
+
+ def logline(self, message):
+ """Schreibt eine Zeile in die Logdatei oder stdout.
+ @param message: Logzeile zum Schreiben"""
+ with self._lckfh:
+ self._fh.write("{}\n".format(message))
+ self._fh.flush()
+
+ def newlogfile(self):
+ """Konfiguriert den FileHandler auf eine neue Logdatei."""
+ proginit.logger.debug("enter RevPiPlc.newlogfile()")
+ with self._lckfh:
+ self._fh.close()
+ self._fh = self._configurefh()
+ proginit.logger.debug("leave RevPiPlc.newlogfile()")
def run(self):
- if self.fh is not None:
- fhread = os.fdopen(self._pipein)
- proginit.logger.debug("enter logreader pipe")
- while not self._exit.is_set():
- line = fhread.readline()
- try:
- self.fh.write(line)
- self.fh.flush()
- except:
- pass
- proginit.logger.debug("leave logreader pipe")
+ """Prueft auf neue Logzeilen und schreibt diese."""
+ proginit.logger.debug("enter PipeLogwriter.run()")
+
+ fhread = os.fdopen(self._fdr)
+ proginit.logger.debug("enter logreader pipe loop")
+ while not self._exit.is_set():
+ line = fhread.readline()
+ self._lckfh.acquire()
+ try:
+ self._fh.write(line)
+ self._fh.flush()
+ except:
+ proginit.logger.exception("PipeLogwriter write log line")
+ finally:
+ self._lckfh.release()
+ proginit.logger.debug("leave logreader pipe loop")
+
+ proginit.logger.debug("close all pipes")
+ os.close(self._fdr)
+ os.close(self.fdw)
+ proginit.logger.debug("closed all pipes")
+
+ proginit.logger.debug("leave PipeLogwriter.run()")
def stop(self):
- proginit.logger.debug("quit pipe logreader")
+ """Beendetden Thread und die FileHandler werden geschlossen."""
+ proginit.logger.debug("enter PipeLogwriter.stop()")
self._exit.set()
- if self.pipeout is not None:
- os.write(self.pipeout, b"\n")
- os.close(self.pipeout)
- os.close(self._pipein)
+ self._lckfh.acquire()
+ try:
+ os.write(self.fdw, b"\n")
+ except:
+ pass
+ finally:
+ self._lckfh.release()
+
+ proginit.logger.debug("leave PipeLogwriter.stop()")
class RevPiPlc(Thread):
@@ -211,9 +284,8 @@ class RevPiPlc(Thread):
self._arguments = arguments
self._evt_exit = Event()
self.exitcode = None
- self._fh = self._configurefh()
self.gid = 65534
- self.plw = None
+ self._plw = self._configureplw()
self._program = program
self._procplc = None
self._pversion = pversion
@@ -221,9 +293,10 @@ class RevPiPlc(Thread):
self.zeroonerror = False
self.zeroonexit = False
- def _configurefh(self):
- # Ausgaben konfigurieren und ggf. umleiten
- proginit.logger.debug("configure fh applog")
+ def _configureplw(self):
+ """Konfiguriert den PipeLogwriter fuer Ausgaben der PLCAPP.
+ @returns: PipeLogwriter()"""
+ proginit.logger.debug("enter RevPiPlc._configureplw()")
logfile = None
if proginit.pargs.daemon:
if os.access(os.path.dirname(proginit.logapp), os.R_OK | os.W_OK):
@@ -231,10 +304,11 @@ class RevPiPlc(Thread):
elif proginit.pargs.logfile is not None:
logfile = proginit.pargs.logfile
- if logfile is not None:
- return open(logfile, "a")
- else:
- return None
+ if not logfile is None:
+ logfile = PipeLogwriter(logfile)
+
+ proginit.logger.debug("leave RevPiPlc._configureplw()")
+ return logfile
def _setuppopen(self):
"""Setzt UID und GID fuer das PLC Programm."""
@@ -243,19 +317,21 @@ class RevPiPlc(Thread):
os.setgid(self.gid)
os.setuid(self.uid)
- def _spopen(self, lst_proc, filenum=None):
+ def _spopen(self, lst_proc):
"""Startet das PLC Programm.
@param lst_proc: Prozessliste
@returns: subprocess"""
- proginit.logger.debug("configure subprocess")
- return subprocess.Popen(
+ proginit.logger.debug("enter RevPiPlc._spopen({})".format(lst_proc))
+ sp = subprocess.Popen(
lst_proc,
preexec_fn=self._setuppopen,
cwd=os.path.dirname(self._program),
bufsize=1,
- stdout=subprocess.STDOUT if filenum is None else filenum,
+ stdout=sysstdout if self._plw is None else self._plw.fdw,
stderr=subprocess.STDOUT
)
+ proginit.logger.debug("leave RevPiPlc._spopen()")
+ return sp
def _zeroprocimg(self):
"""Setzt Prozessabbild auf NULL."""
@@ -264,21 +340,18 @@ class RevPiPlc(Thread):
f.write(bytes(4096))
def newlogfile(self):
- if self._fh is not None:
- self._fh.close()
+ """Konfiguriert die FileHandler auf neue Logdatei."""
+ proginit.logger.debug("enter RevPiPlc.newlogfile()")
+ if self._plw is not None:
+ self._plw.newlogfile()
+ self._plw.logline("-" * 55)
+ self._plw.logline("start new logfile: {}".format(asctime()))
- self._fh = self._configurefh()
- if self.plw is not None:
- self.plw.fh = self._fh
-
- self._fh.write("-" * 55)
- self._fh.write("\nstart new logfile: {}\n".format(asctime()))
- self._fh.flush()
-
- proginit.logger.info("new plc logfile")
+ proginit.logger.debug("leave RevPiPlc.newlogfile()")
def run(self):
"""Fuehrt PLC-Programm aus und ueberwacht es."""
+ proginit.logger.debug("enter RevPiPlc.run()")
if self._pversion == 2:
lst_proc = shlex.split("/usr/bin/env python2 -u {} {}".format(
self._program, self._arguments
@@ -288,21 +361,17 @@ class RevPiPlc(Thread):
self._program, self._arguments
))
- # Logausgabe
- if self._fh is not None:
- self._fh.write("-" * 55)
- self._fh.write("\nplc: {} started: {}\n".format(
- os.path.basename(self._program), asctime()
- ))
- self._fh.flush()
-
- # LogWriter
- self.plw = PipeLogwriter(self._fh)
- self.plw.start()
-
# Prozess erstellen
proginit.logger.info("start plc program {}".format(self._program))
- self._procplc = self._spopen(lst_proc, self.plw.pipeout)
+ self._procplc = self._spopen(lst_proc)
+
+ # LogWriter starten und Logausgaben schreiben
+ if self._plw is not None:
+ self._plw.logline("-" * 55)
+ self._plw.logline("plc: {} started: {}".format(
+ os.path.basename(self._program), asctime()
+ ))
+ self._plw.start()
while not self._evt_exit.is_set():
@@ -333,7 +402,7 @@ class RevPiPlc(Thread):
if not self._evt_exit.is_set() and self.autoreload:
# Prozess neu starten
- self._procplc = self._spopen(lst_proc, self.plw.pipeout)
+ self._procplc = self._spopen(lst_proc)
if self.exitcode == 0:
proginit.logger.warning(
"restart plc program after clean exit"
@@ -347,15 +416,23 @@ class RevPiPlc(Thread):
self._evt_exit.wait(1)
+ proginit.logger.debug("leave RevPiPlc.run()")
+
def stop(self):
"""Beendet PLC-Programm."""
+ proginit.logger.debug("enter RevPiPlc.stop()")
proginit.logger.info("stop revpiplc thread")
self._evt_exit.set()
# Prüfen ob es einen subprocess gibt
if self._procplc is None:
- if self.plw is not None:
- self.plw.stop()
+ if self._plw is not None:
+ self._plw.stop()
+ proginit.logger.debug("join after NONE pipe thread")
+ self._plw.join()
+ proginit.logger.debug("joined after NONE pipe thread")
+
+ proginit.logger.debug("leave RevPiPlc.stop()")
return
# Prozess beenden
@@ -382,8 +459,13 @@ class RevPiPlc(Thread):
or self.zeroonerror and self.exitcode != 0:
self._zeroprocimg()
- if self.plw is not None:
- self.plw.stop()
+ if self._plw is not None:
+ self._plw.stop()
+ proginit.logger.debug("join pipe thread")
+ self._plw.join()
+ proginit.logger.debug("joined pipe thread")
+
+ proginit.logger.debug("leave RevPiPlc.stop()")
class RevPiPyLoad():
@@ -554,6 +636,8 @@ class RevPiPyLoad():
# Programm aufräumen
proginit.cleanup()
+ proginit.logger.debug("end revpipyload program")
+
def _sigloadconfig(self, signum, frame):
"""Signal handler to load configuration."""
proginit.logger.debug("got reload config signal")