Zugriffsrechte
diff --git a/doc/proginit.html b/doc/proginit.html
index d9f6e46..162e9f9 100644
--- a/doc/proginit.html
+++ b/doc/proginit.html
@@ -12,7 +12,7 @@ Main functions of our program.
Global Attributes
-forked globalconffile logapp logger logplc pargs startdir
+forked globalconffile logapp logger logplc pargs picontrolreset rapcatalog startdir
Classes
@@ -23,6 +23,9 @@ Classes
Functions
+_zeroprocimg
+Setzt Prozessabbild auf NULL.
+
cleanup
Clean up program.
@@ -31,6 +34,14 @@ Functions
+
+_zeroprocimg
+_zeroprocimg (self )
+
+Setzt Prozessabbild auf NULL.
+
+
+
cleanup
cleanup ( )
diff --git a/doc/revpipyload.html b/doc/revpipyload.html
index 8edc9dc..a531907 100644
--- a/doc/revpipyload.html
+++ b/doc/revpipyload.html
@@ -32,21 +32,12 @@ begrenzt werden!
Global Attributes
-configrsc picontrolreset procimg pyloadverion rapcatalog
+pyloadverion
Classes
-LogReader
-Ermoeglicht den Zugriff auf die Logdateien.
-
-PipeLogwriter
-File PIPE fuer das Schreiben des APP Log.
-
-RevPiPlc
-Verwaltet das PLC Python Programm.
-
RevPiPyLoad
Hauptklasse, die alle Funktionen zur Verfuegung stellt.
@@ -57,345 +48,6 @@ Functions
None
-
-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.
-
-
-
-
-Derived from
-None
-
-Class Attributes
-
-
-Class Methods
-
-
-Methods
-
-
-LogReader
-Instantiiert LogReader-Klasse.
-
-closeall
-Fuehrt close auf File Handler durch.
-
-load_applog
-Uebertraegt Logdaten des PLC Programms Binaer.
-
-load_plclog
-Uebertraegt Logdaten des Loaders Binaer.
-
-
-
-Static Methods
-
-
-
-LogReader (Constructor)
-LogReader ( )
-
-Instantiiert LogReader-Klasse.
-
-
-LogReader.closeall
-closeall ( )
-
-Fuehrt close auf File Handler durch.
-
-
-LogReader.load_applog
-load_applog (start, count )
-
-Uebertraegt Logdaten des PLC Programms Binaer.
-
-start
-
-Startbyte
- count
-
-Max. Byteanzahl zum uebertragen
-
-
-Returns:
-
-Binary() der Logdatei
-
-
-
-LogReader.load_plclog
-load_plclog (start, count )
-
-Uebertraegt Logdaten des Loaders Binaer.
-
-start
-
-Startbyte
- count
-
-Max. Byteanzahl zum uebertragen
-
-
-Returns:
-
-Binary() der Logdatei
-
-
-
-
-
-PipeLogwriter
-
-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.
-
-
-
-
-Derived from
-Thread
-
-Class Attributes
-
-
-Class Methods
-
-
-Methods
-
-
-PipeLogwriter
-Instantiiert PipeLogwriter-Klasse.
-
-__del__
-Close file handler.
-
-_configurefh
-Konfiguriert den FileHandler fuer Ausgaben der PLCAPP.
-
-logline
-Schreibt eine Zeile in die Logdatei oder stdout.
-
-newlogfile
-Konfiguriert den FileHandler auf eine neue Logdatei.
-
-run
-Prueft auf neue Logzeilen und schreibt diese.
-
-stop
-Beendetden Thread und die FileHandler werden geschlossen.
-
-
-
-Static Methods
-
-
-
-PipeLogwriter (Constructor)
-PipeLogwriter (logfilename )
-
-Instantiiert PipeLogwriter-Klasse.
-
-logfilename
-
-Dateiname fuer Logdatei
-
-
-
-PipeLogwriter.__del__
-__del__ ( )
-
-Close file handler.
-
-
-PipeLogwriter._configurefh
-_configurefh ( )
-
-Konfiguriert den FileHandler fuer Ausgaben der PLCAPP.
-
-Returns:
-
-FileHandler-Objekt
-
-
-
-PipeLogwriter.logline
-logline (message )
-
-Schreibt eine Zeile in die Logdatei oder stdout.
-
-message
-
-Logzeile zum Schreiben
-
-
-
-PipeLogwriter.newlogfile
-newlogfile ( )
-
-Konfiguriert den FileHandler auf eine neue Logdatei.
-
-
-PipeLogwriter.run
-run ( )
-
-Prueft auf neue Logzeilen und schreibt diese.
-
-
-PipeLogwriter.stop
-stop ( )
-
-Beendetden Thread und die FileHandler werden geschlossen.
-
-
-
-
-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.
-
-_configureplw
-Konfiguriert den PipeLogwriter fuer Ausgaben der PLCAPP.
-
-_setuppopen
-Setzt UID und GID fuer das PLC Programm.
-
-_spopen
-Startet das PLC Programm.
-
-_zeroprocimg
-Setzt Prozessabbild auf NULL.
-
-newlogfile
-Konfiguriert die FileHandler auf neue Logdatei.
-
-run
-Fuehrt PLC-Programm aus und ueberwacht es.
-
-stop
-Beendet PLC-Programm.
-
-
-
-Static Methods
-
-
-
-RevPiPlc (Constructor)
-RevPiPlc (program, arguments, pversion )
-
-Instantiiert RevPiPlc-Klasse.
-
-
-RevPiPlc._configureplw
-_configureplw ( )
-
-Konfiguriert den PipeLogwriter fuer Ausgaben der PLCAPP.
-
-Returns:
-
-PipeLogwriter()
-
-
-
-RevPiPlc._setuppopen
-_setuppopen ( )
-
-Setzt UID und GID fuer das PLC Programm.
-
-
-RevPiPlc._spopen
-_spopen (lst_proc )
-
-Startet das PLC Programm.
-
-lst_proc
-
-Prozessliste
-
-
-Returns:
-
-subprocess
-
-
-
-RevPiPlc._zeroprocimg
-_zeroprocimg ( )
-
-Setzt Prozessabbild auf NULL.
-
-
-RevPiPlc.newlogfile
-newlogfile ( )
-
-Konfiguriert die FileHandler auf neue Logdatei.
-
-
-RevPiPlc.run
-run ( )
-
-Fuehrt PLC-Programm aus und ueberwacht es.
-
-
-RevPiPlc.stop
-stop ( )
-
-Beendet PLC-Programm.
-
-
-
RevPiPyLoad
diff --git a/eric-revpipyload.api b/eric-revpipyload.api
index bdcbe29..d5c2abb 100644
--- a/eric-revpipyload.api
+++ b/eric-revpipyload.api
@@ -1,3 +1,21 @@
+logsystem.LogReader.closeall?4()
+logsystem.LogReader.load_applog?4(start, count)
+logsystem.LogReader.load_plclog?4(start, count)
+logsystem.LogReader?1()
+logsystem.PipeLogwriter.__del__?6()
+logsystem.PipeLogwriter._configurefh?5()
+logsystem.PipeLogwriter.logline?4(message)
+logsystem.PipeLogwriter.newlogfile?4()
+logsystem.PipeLogwriter.run?4()
+logsystem.PipeLogwriter.stop?4()
+logsystem.PipeLogwriter?1(logfilename)
+plcsystem.RevPiPlc._configureplw?5()
+plcsystem.RevPiPlc._setuppopen?5()
+plcsystem.RevPiPlc._spopen?5(lst_proc)
+plcsystem.RevPiPlc.newlogfile?4()
+plcsystem.RevPiPlc.run?4()
+plcsystem.RevPiPlc.stop?4()
+plcsystem.RevPiPlc?1(program, arguments, pversion)
procimgserver.ProcimgServer.devices?4()
procimgserver.ProcimgServer.ios?4(type)
procimgserver.ProcimgServer.loadrevpimodio?4()
@@ -5,7 +23,8 @@ procimgserver.ProcimgServer.setvalue?4(device, io, value)
procimgserver.ProcimgServer.start?4()
procimgserver.ProcimgServer.stop?4()
procimgserver.ProcimgServer.values?4()
-procimgserver.ProcimgServer?1(logger, xmlserver, configrsc, procimg, aclmode)
+procimgserver.ProcimgServer?1(xmlserver, aclmode)
+proginit._zeroprocimg?5(self)
proginit.cleanup?4()
proginit.configure?4()
proginit.forked?7
@@ -14,26 +33,9 @@ proginit.logapp?7
proginit.logger?7
proginit.logplc?7
proginit.pargs?7
+proginit.picontrolreset?7
+proginit.rapcatalog?7
proginit.startdir?7
-revpipyload.LogReader.closeall?4()
-revpipyload.LogReader.load_applog?4(start, count)
-revpipyload.LogReader.load_plclog?4(start, count)
-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)
@@ -60,8 +62,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
-revpipyload.rapcatalog?7
diff --git a/revpipyload.e4p b/revpipyload.e4p
index eff7f78..b25c5a4 100644
--- a/revpipyload.e4p
+++ b/revpipyload.e4p
@@ -1,7 +1,7 @@
-
+
en_US
@@ -9,15 +9,17 @@
Python3
Console
Dieser Loader wird über das Init-System geladen und führt das angegebene Pythonprogramm aus. Es ist für den RevolutionPi gedacht um automatisch das SPS-Programm zu starten.
- 0.4.2
+ 0.4.3
Sven Sager
akira@narux.de
-
+
revpipyload/proginit.py
setup.py
revpipyload/revpipyload.py
revpipyload/procimgserver.py
+ revpipyload/logsystem.py
+ revpipyload/plcsystem.py
diff --git a/revpipyload/logsystem.py b/revpipyload/logsystem.py
new file mode 100644
index 0000000..370b918
--- /dev/null
+++ b/revpipyload/logsystem.py
@@ -0,0 +1,186 @@
+# -*- coding: utf-8 -*-
+#
+# RevPiPyLoad
+#
+# Webpage: https://revpimodio.org/revpipyplc/
+# (c) Sven Sager, License: LGPLv3
+#
+"""Modul fuer die Verwaltung der Logdateien."""
+import os
+import proginit
+from threading import Event, Lock, Thread
+from xmlrpc.client import Binary
+
+
+class 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.
+
+ """
+
+ def __init__(self):
+ """Instantiiert LogReader-Klasse."""
+ self.fhapp = None
+ self.fhapplk = Lock()
+ self.fhplc = None
+ self.fhplclk = Lock()
+
+ def closeall(self):
+ """Fuehrt close auf File Handler durch."""
+ if self.fhapp is not None:
+ self.fhapp.close()
+ if self.fhplc is not None:
+ self.fhplc.close()
+
+ def load_applog(self, start, count):
+ """Uebertraegt Logdaten des PLC Programms Binaer.
+
+ @param start Startbyte
+ @param count Max. Byteanzahl zum uebertragen
+ @return Binary() der Logdatei
+
+ """
+ if not os.access(proginit.logapp, os.R_OK):
+ return Binary(b'\x16') #
+ elif start > os.path.getsize(proginit.logapp):
+ return Binary(b'\x19') #
+ else:
+ with self.fhapplk:
+ if self.fhapp is None or self.fhapp.closed:
+ self.fhapp = open(proginit.logapp, "rb")
+
+ self.fhapp.seek(start)
+ return Binary(self.fhapp.read(count))
+
+ def load_plclog(self, start, count):
+ """Uebertraegt Logdaten des Loaders Binaer.
+
+ @param start Startbyte
+ @param count Max. Byteanzahl zum uebertragen
+ @return Binary() der Logdatei
+
+ """
+ if not os.access(proginit.logplc, os.R_OK):
+ return Binary(b'\x16') #
+ elif start > os.path.getsize(proginit.logplc):
+ return Binary(b'\x19') #
+ else:
+ with self.fhplclk:
+ if self.fhplc is None or self.fhplc.closed:
+ self.fhplc = open(proginit.logplc, "rb")
+
+ self.fhplc.seek(start)
+ return Binary(self.fhplc.read(count))
+
+
+class PipeLogwriter(Thread):
+
+ """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._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):
+ """Close der FileHandler."""
+ # FileHandler schließen
+ if self._fh is not None:
+ self._fh.close()
+
+ def _configurefh(self):
+ """Konfiguriert den FileHandler fuer Ausgaben der PLCAPP.
+ @return FileHandler-Objekt"""
+ proginit.logger.debug("enter PipeLogwriter._configurefh()")
+
+ logfile = None
+ dirname = os.path.dirname(self.logfile)
+
+ if os.access(dirname, os.R_OK | os.W_OK):
+ logfile = open(self.logfile, "a")
+ else:
+ 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):
+ """Prueft auf neue Logzeilen und schreibt diese."""
+ proginit.logger.debug("enter PipeLogwriter.run()")
+
+ fhread = os.fdopen(self._fdr)
+ 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 in write log line")
+ finally:
+ self._lckfh.release()
+ proginit.logger.debug("leave logreader pipe loop")
+
+ proginit.logger.debug("close all pipes")
+ fhread.close()
+ os.close(self.fdw)
+ proginit.logger.debug("closed all pipes")
+
+ # FileHandler schließen
+ if self._fh is not None:
+ self._fh.close()
+
+ proginit.logger.debug("leave PipeLogwriter.run()")
+
+ def stop(self):
+ """Beendetden Thread und die FileHandler werden geschlossen."""
+ proginit.logger.debug("enter PipeLogwriter.stop()")
+ self._exit.set()
+
+ self._lckfh.acquire()
+ # Letzten Log in Pipe schreiben zum befreien
+ try:
+ os.write(self.fdw, b"\n")
+ except:
+ pass
+ finally:
+ self._lckfh.release()
+
+ proginit.logger.debug("leave PipeLogwriter.stop()")
diff --git a/revpipyload/plcsystem.py b/revpipyload/plcsystem.py
new file mode 100644
index 0000000..bc3ae2c
--- /dev/null
+++ b/revpipyload/plcsystem.py
@@ -0,0 +1,224 @@
+# -*- coding: utf-8 -*-
+#
+# RevPiPyLoad
+#
+# Webpage: https://revpimodio.org/revpipyplc/
+# (c) Sven Sager, License: LGPLv3
+#
+"""Modul fuer die Verwaltung der PLC Funktionen."""
+import os
+import proginit
+import shlex
+import subprocess
+from logsystem import PipeLogwriter
+from sys import stdout as sysstdout
+from threading import Event, Thread
+from time import sleep, asctime
+
+
+class RevPiPlc(Thread):
+
+ """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.
+
+ """
+
+ def __init__(self, program, arguments, pversion):
+ """Instantiiert RevPiPlc-Klasse."""
+ super().__init__()
+
+ self._arguments = arguments
+ self._evt_exit = Event()
+ self._plw = self._configureplw()
+ self._program = program
+ self._procplc = None
+ self._pversion = pversion
+ self.autoreload = False
+ self.exitcode = None
+ self.gid = 65534
+ self.uid = 65534
+ self.zeroonerror = False
+ self.zeroonexit = False
+
+ def _configureplw(self):
+ """Konfiguriert den PipeLogwriter fuer Ausgaben der PLCAPP.
+ @return 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):
+ logfile = proginit.logapp
+ elif proginit.pargs.logfile is not None:
+ logfile = proginit.pargs.logfile
+
+ if logfile is not None:
+ logfile = PipeLogwriter(logfile)
+
+ proginit.logger.debug("leave RevPiPlc._configureplw()")
+ return logfile
+
+ def _setuppopen(self):
+ """Setzt UID und GID fuer das PLC Programm."""
+ proginit.logger.info(
+ "set uid {} and gid {} for plc program".format(
+ self.uid, self.gid)
+ )
+ os.setgid(self.gid)
+ os.setuid(self.uid)
+
+ def _spopen(self, lst_proc):
+ """Startet das PLC Programm.
+ @param lst_proc Prozessliste
+ @return subprocess"""
+ 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=sysstdout if self._plw is None else self._plw.fdw,
+ stderr=subprocess.STDOUT
+ )
+ proginit.logger.debug("leave RevPiPlc._spopen()")
+ return sp
+
+ def newlogfile(self):
+ """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()))
+
+ 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
+ ))
+ else:
+ lst_proc = shlex.split("/usr/bin/env python3 -u {} {}".format(
+ self._program, self._arguments
+ ))
+
+ # Prozess erstellen
+ proginit.logger.info("start plc program {}".format(self._program))
+ 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():
+
+ # Auswerten
+ self.exitcode = self._procplc.poll()
+
+ if self.exitcode is not None:
+ if self.exitcode > 0:
+ # PLC Python Programm abgestürzt
+ proginit.logger.error(
+ "plc program crashed - exitcode: {}".format(
+ self.exitcode
+ )
+ )
+ if self.zeroonerror:
+ proginit._zeroprocimg()
+ proginit.logger.warning(
+ "set piControl0 to ZERO after PLC program error")
+
+ else:
+ # PLC Python Programm sauber beendet
+ proginit.logger.info("plc program did a clean exit")
+ if self.zeroonexit:
+ proginit._zeroprocimg()
+ proginit.logger.info(
+ "set piControl0 to ZERO after PLC program returns "
+ "clean exitcode")
+
+ if not self._evt_exit.is_set() and self.autoreload:
+ # Prozess neu starten
+ self._procplc = self._spopen(lst_proc)
+ if self.exitcode == 0:
+ proginit.logger.warning(
+ "restart plc program after clean exit"
+ )
+ else:
+ proginit.logger.warning(
+ "restart plc program after crash"
+ )
+ else:
+ break
+
+ self._evt_exit.wait(1)
+
+ if self._plw is not None:
+ self._plw.logline("-" * 55)
+ self._plw.logline("plc: {} stopped: {}".format(
+ os.path.basename(self._program), asctime()
+ ))
+
+ 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()
+ self._plw.join()
+ proginit.logger.debug("log pipes successfully closed")
+
+ proginit.logger.debug("leave RevPiPlc.stop()")
+ return
+
+ # Prozess beenden
+ count = 0
+ proginit.logger.info("term plc program {}".format(self._program))
+ self._procplc.terminate()
+
+ while self._procplc.poll() is None and count < 10:
+ count += 1
+ proginit.logger.info(
+ "wait term plc program {} seconds".format(count * 0.5)
+ )
+ sleep(0.5)
+ if self._procplc.poll() is None:
+ proginit.logger.warning(
+ "can not term plc program {}".format(self._program)
+ )
+ self._procplc.kill()
+ proginit.logger.warning("killed plc program")
+
+ # Exitcode auswerten
+ self.exitcode = self._procplc.poll()
+ if self.zeroonexit and self.exitcode == 0 \
+ or self.zeroonerror and self.exitcode != 0:
+ proginit._zeroprocimg()
+
+ if self._plw is not None:
+ self._plw.stop()
+ self._plw.join()
+ proginit.logger.debug("log pipes successfully closed")
+
+ proginit.logger.debug("leave RevPiPlc.stop()")
diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py
index c135843..627c801 100644
--- a/revpipyload/procimgserver.py
+++ b/revpipyload/procimgserver.py
@@ -1,10 +1,10 @@
+# -*- coding: utf-8 -*-
#
# RevPiPyLoad
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
-# -*- coding: utf-8 -*-
"""Stellt Funktionen bereit um das Prozessabbild zu ueberwachen.
Bei ausreichend Rechten koennen Ausgaenge auch gesetzt werden um einen
@@ -12,6 +12,7 @@ IO-Check bei Inbetriebname durchzufuehren.
"""
import pickle
+import proginit
import revpimodio
from xmlrpc.client import Binary
@@ -27,22 +28,17 @@ class ProcimgServer():
"""
- def __init__(self, logger, xmlserver, configrsc, procimg, aclmode):
+ def __init__(self, xmlserver, aclmode):
"""Instantiiert RevPiCheckServer()-Klasse.
@param xmlserver XML-RPC Server
- @param procimg Pfad zum Prozessabbild
- @param configrsc Pfad zur piCtory Konfigurationsdatei
- @param logger Loggerinstanz
@param aclmode Zugriffsrechte
"""
# Logger übernehmen
- self.logger = logger
- self.logger.debug("enter ProcimgServer.__init__()")
+ proginit.logger.debug("enter ProcimgServer.__init__()")
+
self.acl = aclmode
- self.configrsc = configrsc
- self.procimg = procimg
self.rpi = None
# XML-Server übernehmen
@@ -60,7 +56,7 @@ class ProcimgServer():
self.loadrevpimodio()
- self.logger.debug("leave ProcimgServer.__init__()")
+ proginit.logger.debug("leave ProcimgServer.__init__()")
def devices(self):
"""Generiert Deviceliste mit Position und Namen.
@@ -104,19 +100,19 @@ class ProcimgServer():
if self.rpi is not None:
self.rpi.cleanup()
- self.logger.debug("create revpimodio class")
+ proginit.logger.debug("create revpimodio class")
try:
self.rpi = revpimodio.RevPiModIO(
- configrsc=self.configrsc,
- procimg=self.procimg,
+ configrsc=proginit.pargs.configrsc,
+ procimg=proginit.pargs.procimg
)
except:
self.rpi = None
- self.logger.error("piCtory configuration not loadable")
+ proginit.logger.error("piCtory configuration not loadable")
return False
self.rpi.devices.syncoutputs(device=0)
- self.logger.debug("created revpimodio class")
+ proginit.logger.debug("created revpimodio class")
return True
def setvalue(self, device, io, value):
@@ -171,9 +167,9 @@ class ProcimgServer():
def start(self):
"""Registriert XML Funktionen.
@return True, wenn erfolgreich"""
- self.logger.debug("enter ProcimgServer.start()")
- ec = False
+ proginit.logger.debug("enter ProcimgServer.start()")
+ ec = False
if self.rpi is not None:
# Registriere Funktionen
@@ -188,12 +184,12 @@ class ProcimgServer():
)
ec = True
- self.logger.debug("leave ProcimgServer.start()")
+ proginit.logger.debug("leave ProcimgServer.start()")
return ec
def stop(self):
"""Entfernt XML-Funktionen."""
- self.logger.debug("enter ProcimgServer.stop()")
+ proginit.logger.debug("enter ProcimgServer.stop()")
# Entferne Funktionen
for xmlfunc in self.xmlreadfuncs:
@@ -204,4 +200,4 @@ class ProcimgServer():
if xmlfunc in self.xmlsrv.funcs:
del self.xmlsrv.funcs[xmlfunc]
- self.logger.debug("leave ProcimgServer.stop()")
+ proginit.logger.debug("leave ProcimgServer.stop()")
diff --git a/revpipyload/proginit.py b/revpipyload/proginit.py
index 3aee849..0f737ab 100644
--- a/revpipyload/proginit.py
+++ b/revpipyload/proginit.py
@@ -1,17 +1,15 @@
+# -*- coding: utf-8 -*-
#
# RevPiPyLoad
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
-# -*- coding: utf-8 -*-
"""Main functions of our program."""
import logging
-import os.path
+import os
import sys
from argparse import ArgumentParser
-from os import fork as osfork
-
forked = False
globalconffile = None
@@ -19,21 +17,43 @@ logapp = "revpipyloadapp.log"
logplc = "revpipyload.log"
logger = None
pargs = None
+picontrolreset = "/opt/KUNBUS/piControlReset"
+rapcatalog = None
startdir = None
+def _zeroprocimg(self):
+ """Setzt Prozessabbild auf NULL."""
+ procimg = "/dev/piControl0" if pargs is None else pargs.procimg
+ if os.access(procimg, os.W_OK):
+ with open(procimg, "w+b", 0) as f:
+ f.write(bytes(4096))
+ else:
+ if logger is not None:
+ logger.error("zeroprocimg can not write to piControl device")
+
+
def cleanup():
"""Clean up program."""
+ # NOTE: Pidfile wirklich löschen?
+ if pargs is not None and pargs.daemon:
+ if os.path.exists("/var/run/revpipyload.pid"):
+ os.remove("/var/run/revpipyload.pid")
+
# Logging beenden
logging.shutdown()
+ # Dateihandler schließen
+ if pargs.daemon:
+ sys.stdout.close()
+
def configure():
"""Initialize general program functions."""
# Command arguments
parser = ArgumentParser(
- description="RevolutionPi Python3 Loader"
+ description="RevolutionPi Python Loader"
)
parser.add_argument(
"-d", "--daemon", action="store_true", dest="daemon",
@@ -50,6 +70,7 @@ def configure():
)
parser.add_argument(
"--procimg", dest="procimg",
+ default="/dev/piControl0",
help="Path to process image"
)
parser.add_argument(
@@ -63,15 +84,6 @@ 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.conffile)
- 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"
@@ -84,7 +96,7 @@ def configure():
)
# Zum daemon machen
- pid = osfork()
+ pid = os.fork()
if pid > 0:
with open(pidfile, "w") as f:
f.write(str(pid))
@@ -92,15 +104,58 @@ def configure():
else:
forked = True
+ # piCtory Konfiguration prüfen
+ if pargs.configrsc is None:
+ lst_rsc = ["/etc/revpi/config.rsc", "/opt/KUNBUS/config.rsc"]
+ for rscfile in lst_rsc:
+ if os.access(rscfile, os.F_OK | os.R_OK):
+ pargs.configrsc = rscfile
+ break
+ elif not os.access(pargs.configrsc, os.F_OK | os.R_OK):
+ pargs.configrsc = None
+ if pargs.configrsc is None:
+ raise RuntimeError(
+ "can not find known pictory configurations at {}"
+ "".format(", ".join(lst_rsc))
+ )
+
+ # piControlReset suchen
+ global picontrolreset
+ if not os.access(picontrolreset, os.F_OK | os.X_OK):
+ picontrolreset = "/usr/bin/piTest -x"
+
+ # rap Katalog an bekannten Stellen prüfen und laden
+ global rapcatalog
+ lst_rap = [
+ "/opt/KUNBUS/pictory/resources/data/rap",
+ "/var/www/pictory/resources/data/rap"
+ ]
+ for rapfolder in lst_rap:
+ if os.path.isdir(rapfolder):
+ rapcatalog = os.listdir(rapfolder)
+
+ # 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.conffile)
+ if pargs.logfile is not None and os.path.dirname(pargs.logfile) == "":
+ pargs.logfile = os.path.join(startdir, pargs.logfile)
+
global logapp
global logplc
if pargs.daemon:
+ # Ausgage vor Umhängen schließen
+ sys.stdout.close()
+
# 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
diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py
index ab722bf..d60b5ad 100755
--- a/revpipyload/revpipyload.py
+++ b/revpipyload/revpipyload.py
@@ -1,4 +1,5 @@
#!/usr/bin/python3
+# -*- coding: utf-8 -*-
#
# RevPiPyLoad
# Version: see global var pyloadverion
@@ -6,7 +7,6 @@
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
-# -*- coding: utf-8 -*-
"""Revolution Pi Python PLC Loader.
Stellt das RevPiPyLoad Programm bereit. Dieses Programm lauft als Daemon auf
@@ -31,11 +31,11 @@ begrenzt werden!
"""
import gzip
+import logsystem
+import plcsystem
import proginit
import os
-import shlex
import signal
-import subprocess
import tarfile
import zipfile
from concurrent import futures
@@ -43,394 +43,13 @@ 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 mkstemp
-from threading import Thread, Event, Lock
-from time import sleep, asctime
+from threading import Event
+from time import asctime
from xmlrpc.client import Binary
from xmlrpc.server import SimpleXMLRPCServer
-configrsc = None
-picontrolreset = "/opt/KUNBUS/piControlReset"
-procimg = "/dev/piControl0"
-pyloadverion = "0.4.2"
-rapcatalog = None
-
-
-class 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.
-
- """
-
- def __init__(self):
- """Instantiiert LogReader-Klasse."""
- self.fhapp = None
- self.fhapplk = Lock()
- self.fhplc = None
- self.fhplclk = Lock()
-
- def closeall(self):
- """Fuehrt close auf File Handler durch."""
- if self.fhapp is not None:
- self.fhapp.close()
- if self.fhplc is not None:
- self.fhplc.close()
-
- def load_applog(self, start, count):
- """Uebertraegt Logdaten des PLC Programms Binaer.
-
- @param start Startbyte
- @param count Max. Byteanzahl zum uebertragen
- @return Binary() der Logdatei
-
- """
- if not os.access(proginit.logapp, os.R_OK):
- return Binary(b'\x16') #
- elif start > os.path.getsize(proginit.logapp):
- return Binary(b'\x19') #
- else:
- with self.fhapplk:
- if self.fhapp is None or self.fhapp.closed:
- self.fhapp = open(proginit.logapp, "rb")
-
- self.fhapp.seek(start)
- return Binary(self.fhapp.read(count))
-
- def load_plclog(self, start, count):
- """Uebertraegt Logdaten des Loaders Binaer.
-
- @param start Startbyte
- @param count Max. Byteanzahl zum uebertragen
- @return Binary() der Logdatei
-
- """
- if not os.access(proginit.logplc, os.R_OK):
- return Binary(b'\x16') #
- elif start > os.path.getsize(proginit.logplc):
- return Binary(b'\x19') #
- else:
- with self.fhplclk:
- if self.fhplc is None or self.fhplc.closed:
- self.fhplc = open(proginit.logplc, "rb")
-
- self.fhplc.seek(start)
- return Binary(self.fhplc.read(count))
-
-
-class PipeLogwriter(Thread):
-
- """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 = 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):
- """Close file handler."""
- if self._fh is not None:
- self._fh.close()
-
- def _configurefh(self):
- """Konfiguriert den FileHandler fuer Ausgaben der PLCAPP.
- @return 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:
- 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):
- """Prueft auf neue Logzeilen und schreibt diese."""
- proginit.logger.debug("enter PipeLogwriter.run()")
-
- fhread = os.fdopen(self._fdr)
- 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 in 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):
- """Beendetden Thread und die FileHandler werden geschlossen."""
- proginit.logger.debug("enter PipeLogwriter.stop()")
- self._exit.set()
- 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):
-
- """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.
-
- """
-
- def __init__(self, program, arguments, pversion):
- """Instantiiert RevPiPlc-Klasse."""
- super().__init__()
- self.autoreload = False
- self._arguments = arguments
- self._evt_exit = Event()
- self.exitcode = None
- self.gid = 65534
- self._plw = self._configureplw()
- self._program = program
- self._procplc = None
- self._pversion = pversion
- self.uid = 65534
- self.zeroonerror = False
- self.zeroonexit = False
-
- def _configureplw(self):
- """Konfiguriert den PipeLogwriter fuer Ausgaben der PLCAPP.
- @return 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):
- logfile = proginit.logapp
- elif proginit.pargs.logfile is not None:
- logfile = proginit.pargs.logfile
-
- if logfile is not None:
- logfile = PipeLogwriter(logfile)
-
- proginit.logger.debug("leave RevPiPlc._configureplw()")
- return logfile
-
- def _setuppopen(self):
- """Setzt UID und GID fuer das PLC Programm."""
- proginit.logger.info(
- "set uid {} and gid {} for plc program".format(
- self.uid, self.gid)
- )
- os.setgid(self.gid)
- os.setuid(self.uid)
-
- def _spopen(self, lst_proc):
- """Startet das PLC Programm.
- @param lst_proc Prozessliste
- @return subprocess"""
- 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=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."""
- if os.path.exists("/dev/piControl0"):
- with open("/dev/piControl0", "w+b", 0) as f:
- f.write(bytes(4096))
-
- def newlogfile(self):
- """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()))
-
- 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
- ))
- else:
- lst_proc = shlex.split("/usr/bin/env python3 -u {} {}".format(
- self._program, self._arguments
- ))
-
- # Prozess erstellen
- proginit.logger.info("start plc program {}".format(self._program))
- 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():
-
- # Auswerten
- self.exitcode = self._procplc.poll()
-
- if self.exitcode is not None:
- if self.exitcode > 0:
- # PLC Python Programm abgestürzt
- proginit.logger.error(
- "plc program crashed - exitcode: {}".format(
- self.exitcode
- )
- )
- if self.zeroonerror:
- self._zeroprocimg()
- proginit.logger.warning(
- "set piControl0 to ZERO after PLC program error")
-
- else:
- # PLC Python Programm sauber beendet
- proginit.logger.info("plc program did a clean exit")
- if self.zeroonexit:
- self._zeroprocimg()
- proginit.logger.info(
- "set piControl0 to ZERO after PLC program returns "
- "clean exitcode")
-
- if not self._evt_exit.is_set() and self.autoreload:
- # Prozess neu starten
- self._procplc = self._spopen(lst_proc)
- if self.exitcode == 0:
- proginit.logger.warning(
- "restart plc program after clean exit"
- )
- else:
- proginit.logger.warning(
- "restart plc program after crash"
- )
- else:
- break
-
- self._evt_exit.wait(1)
-
- if self._plw is not None:
- self._plw.logline("-" * 55)
- self._plw.logline("plc: {} stopped: {}".format(
- os.path.basename(self._program), asctime()
- ))
-
- 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()
- self._plw.join()
- proginit.logger.debug("log pipes successfully closed")
-
- proginit.logger.debug("leave RevPiPlc.stop()")
- return
-
- # Prozess beenden
- count = 0
- proginit.logger.info("term plc program {}".format(self._program))
- self._procplc.terminate()
-
- while self._procplc.poll() is None and count < 10:
- count += 1
- proginit.logger.info(
- "wait term plc program {} seconds".format(count * 0.5)
- )
- sleep(0.5)
- if self._procplc.poll() is None:
- proginit.logger.warning(
- "can not term plc program {}".format(self._program)
- )
- self._procplc.kill()
- proginit.logger.warning("killed plc program")
-
- # Exitcode auswerten
- self.exitcode = self._procplc.poll()
- if self.zeroonexit and self.exitcode == 0 \
- or self.zeroonerror and self.exitcode != 0:
- self._zeroprocimg()
-
- if self._plw is not None:
- self._plw.stop()
- self._plw.join()
- proginit.logger.debug("log pipes successfully closed")
-
- proginit.logger.debug("leave RevPiPlc.stop()")
+pyloadverion = "0.4.3"
class RevPiPyLoad():
@@ -444,56 +63,21 @@ class RevPiPyLoad():
def __init__(self):
"""Instantiiert RevPiPyLoad-Klasse."""
- proginit.configure()
proginit.logger.debug("enter RevPiPyLoad.__init__()")
- # piCtory Konfiguration an bekannten Stellen prüfen
- global configrsc
- configrsc = proginit.pargs.configrsc
- lst_rsc = ["/etc/revpi/config.rsc", "/opt/KUNBUS/config.rsc"]
- for rscfile in lst_rsc:
- if os.access(rscfile, os.F_OK | os.R_OK):
- configrsc = rscfile
- break
- if configrsc is None:
- raise RuntimeError(
- "can not find known pictory configurations at {}"
- "".format(", ".join(lst_rsc))
- )
-
- # Alternatives Processabbild verwenden
- if proginit.pargs.procimg is not None:
- global procimg
- procimg = proginit.pargs.procimg
-
- # rap Katalog an bekannten Stellen prüfen und laden
- global rapcatalog
- lst_rap = [
- "/opt/KUNBUS/pictory/resources/data/rap",
- "/var/www/pictory/resources/data/rap"
- ]
- for rapfolder in lst_rap:
- if os.path.isdir(rapfolder):
- rapcatalog = os.listdir(rapfolder)
-
- # piControlReset suchen
- global picontrolreset
- if not os.access(picontrolreset, os.F_OK | os.X_OK):
- picontrolreset = "/usr/bin/piTest -x"
-
# Klassenattribute
self._exit = True
- self.pictorymtime = os.path.getmtime(configrsc)
+ self.pictorymtime = os.path.getmtime(proginit.pargs.configrsc)
self.evt_loadconfig = Event()
self.globalconfig = ConfigParser()
- self.logr = LogReader()
+ self.logr = logsystem.LogReader()
self.plc = None
self.tfile = {}
self.tpe = None
self.xsrv = None
self.xml_ps = None
- # Load config
+ # Konfiguration laden
self._loadconfig()
# Signal events
@@ -579,7 +163,7 @@ class RevPiPyLoad():
try:
import procimgserver
self.xml_ps = procimgserver.ProcimgServer(
- proginit.logger, self.xsrv, configrsc, procimg, self.xmlrpc
+ self.xsrv, self.xmlrpc
)
self.xsrv.register_function(self.xml_psstart, "psstart")
self.xsrv.register_function(self.xml_psstop, "psstop")
@@ -612,7 +196,8 @@ class RevPiPyLoad():
self.xsrv.register_function(
self.xml_plcuploadclean, "plcuploadclean")
self.xsrv.register_function(
- lambda: os.system(picontrolreset), "resetpicontrol")
+ lambda: os.system(proginit.picontrolreset),
+ "resetpicontrol")
self.xsrv.register_function(
self.xml_setconfig, "set_config")
self.xsrv.register_function(
@@ -643,7 +228,7 @@ class RevPiPyLoad():
return None
proginit.logger.debug("create PLC watcher")
- th_plc = RevPiPlc(
+ th_plc = plcsystem.RevPiPlc(
os.path.join(self.plcworkdir, self.plcprog),
self.plcarguments,
self.pythonver
@@ -660,11 +245,7 @@ class RevPiPyLoad():
def _sigexit(self, signum, frame):
"""Signal handler to clean and exit program."""
proginit.logger.debug("enter RevPiPyLoad._sigexit()")
-
- # Programm stoppen und aufräumen
self.stop()
- proginit.cleanup()
-
proginit.logger.debug("leave RevPiPyLoad._sigexit()")
def _sigloadconfig(self, signum, frame):
@@ -718,7 +299,9 @@ class RevPiPyLoad():
os.path.join(tup_dir[0], file), arcname=arcname
)
if pictory:
- fh_pack.write(configrsc, arcname="config.rsc")
+ fh_pack.write(
+ proginit.pargs.configrsc, arcname="config.rsc"
+ )
except:
filename = ""
finally:
@@ -730,7 +313,7 @@ class RevPiPyLoad():
try:
fh_pack.add(".", arcname=os.path.basename(self.plcworkdir))
if pictory:
- fh_pack.add(configrsc, arcname="config.rsc")
+ fh_pack.add(proginit.pargs.configrsc, arcname="config.rsc")
except:
filename = ""
finally:
@@ -760,9 +343,9 @@ class RevPiPyLoad():
and not self.evt_loadconfig.is_set():
# piCtory auf Veränderung prüfen
- if self.pictorymtime != os.path.getmtime(configrsc):
+ if self.pictorymtime != os.path.getmtime(proginit.pargs.configrsc):
proginit.logger.warning("piCtory configuration was changed")
- self.pictorymtime = os.path.getmtime(configrsc)
+ self.pictorymtime = os.path.getmtime(proginit.pargs.configrsc)
if self.xml_ps is not None:
self.xml_psstop()
@@ -831,7 +414,7 @@ class RevPiPyLoad():
"""Gibt die config.rsc Datei von piCotry zurueck.
@return xmlrpc.client.Binary()"""
proginit.logger.debug("xmlrpc call getpictoryrsc")
- with open(configrsc, "rb") as fh:
+ with open(proginit.pargs.configrsc, "rb") as fh:
buff = fh.read()
return Binary(buff)
@@ -839,7 +422,7 @@ class RevPiPyLoad():
"""Gibt die Rohdaten aus piControl0 zurueck.
@return xmlrpc.client.Binary()"""
proginit.logger.debug("xmlrpc call getprocimg")
- with open(procimg, "rb") as fh:
+ with open(proginit.pargs.procimg, "rb") as fh:
buff = fh.read()
return Binary(buff)
@@ -872,7 +455,7 @@ class RevPiPyLoad():
-3 Lief nie
"""
- proginit.logger.debug("xmlrpc call plcexitcode")
+ # NOTE: proginit.logger.debug("xmlrpc call plcexitcode")
if self.plc is None:
return -2
elif self.plc.is_alive():
@@ -1043,7 +626,7 @@ class RevPiPyLoad():
return -2
# Prüfen ob Modulkatalog vorhanden ist
- if rapcatalog is None:
+ if proginit.rapcatalog is None:
return -5
else:
@@ -1051,7 +634,7 @@ class RevPiPyLoad():
for picdev in jconfigrsc["Devices"]:
found = False
picdev = picdev["id"][7:-4]
- for rapdev in rapcatalog:
+ for rapdev in proginit.rapcatalog:
if rapdev.find(picdev) >= 0:
found = True
@@ -1060,13 +643,13 @@ class RevPiPyLoad():
return -4
try:
- with open(configrsc, "wb") as fh:
+ with open(proginit.pargs.configrsc, "wb") as fh:
fh.write(filebytes.data)
except:
return -3
else:
if reset:
- return os.system(picontrolreset)
+ return os.system(proginit.picontrolreset)
else:
return 0
@@ -1089,5 +672,12 @@ class RevPiPyLoad():
if __name__ == "__main__":
+ # Programmeinstellungen konfigurieren
+ proginit.configure()
+
+ # Programm starten
root = RevPiPyLoad()
root.start()
+
+ # Aufräumen
+ proginit.cleanup()
diff --git a/setup.py b/setup.py
index 64cce8f..1d194ca 100644
--- a/setup.py
+++ b/setup.py
@@ -27,7 +27,7 @@ setup(
license="LGPLv3",
name="revpipyload",
- version="0.4.2",
+ version="0.4.3",
scripts=["data/revpipyload"],