Umstellung auf proginit als globale Datenquelle

Aufteilung der Funktionen in mehrere Module
FileHandler von stdout schließen
This commit is contained in:
2017-09-12 16:17:03 +02:00
parent 9da1651ec1
commit 3944ec2801
15 changed files with 973 additions and 866 deletions

View File

@@ -5,3 +5,4 @@ test/*
build/*
*.pyc
deb/*
demo/*

View File

@@ -13,6 +13,12 @@ Table of contents</h1>
Modules</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="logsystem.html">logsystem</a></td>
<td>Modul fuer die Verwaltung der Logdateien.</td>
</tr><tr>
<td><a style="color:#0000FF" href="plcsystem.html">plcsystem</a></td>
<td>Modul fuer die Verwaltung der PLC Funktionen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="procimgserver.html">procimgserver</a></td>
<td>Stellt Funktionen bereit um das Prozessabbild zu ueberwachen.</td>
</tr><tr>

248
doc/logsystem.html Normal file
View File

@@ -0,0 +1,248 @@
<!DOCTYPE html>
<html><head>
<title>logsystem</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
logsystem</h1>
<p>
Modul fuer die Verwaltung der Logdateien.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#LogReader">LogReader</a></td>
<td>Ermoeglicht den Zugriff auf die Logdateien.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter">PipeLogwriter</a></td>
<td>File PIPE fuer das Schreiben des APP Log.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="LogReader" ID="LogReader"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">LogReader</h2>
<p>
Ermoeglicht den Zugriff auf die Logdateien.
</p><p>
Beinhaltet Funktionen fuer den Abruf der gesamten Logdatei fuer das
RevPiPyLoad-System und die Logdatei der PLC-Anwendung.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
None
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#LogReader.__init__">LogReader</a></td>
<td>Instantiiert LogReader-Klasse.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#LogReader.closeall">closeall</a></td>
<td>Fuehrt close auf File Handler durch.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#LogReader.load_applog">load_applog</a></td>
<td>Uebertraegt Logdaten des PLC Programms Binaer.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#LogReader.load_plclog">load_plclog</a></td>
<td>Uebertraegt Logdaten des Loaders Binaer.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="LogReader.__init__" ID="LogReader.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader (Constructor)</h3>
<b>LogReader</b>(<i></i>)
<p>
Instantiiert LogReader-Klasse.
</p><a NAME="LogReader.closeall" ID="LogReader.closeall"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader.closeall</h3>
<b>closeall</b>(<i></i>)
<p>
Fuehrt close auf File Handler durch.
</p><a NAME="LogReader.load_applog" ID="LogReader.load_applog"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader.load_applog</h3>
<b>load_applog</b>(<i>start, count</i>)
<p>
Uebertraegt Logdaten des PLC Programms Binaer.
</p><dl>
<dt><i>start</i></dt>
<dd>
Startbyte
</dd><dt><i>count</i></dt>
<dd>
Max. Byteanzahl zum uebertragen
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Binary() der Logdatei
</dd>
</dl><a NAME="LogReader.load_plclog" ID="LogReader.load_plclog"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader.load_plclog</h3>
<b>load_plclog</b>(<i>start, count</i>)
<p>
Uebertraegt Logdaten des Loaders Binaer.
</p><dl>
<dt><i>start</i></dt>
<dd>
Startbyte
</dd><dt><i>count</i></dt>
<dd>
Max. Byteanzahl zum uebertragen
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Binary() der Logdatei
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="PipeLogwriter" ID="PipeLogwriter"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">PipeLogwriter</h2>
<p>
File PIPE fuer das Schreiben des APP Log.
</p><p>
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.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
Thread
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.__init__">PipeLogwriter</a></td>
<td>Instantiiert PipeLogwriter-Klasse.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.__del__">__del__</a></td>
<td>Close der FileHandler.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter._configurefh">_configurefh</a></td>
<td>Konfiguriert den FileHandler fuer Ausgaben der PLCAPP.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.logline">logline</a></td>
<td>Schreibt eine Zeile in die Logdatei oder stdout.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.newlogfile">newlogfile</a></td>
<td>Konfiguriert den FileHandler auf eine neue Logdatei.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.run">run</a></td>
<td>Prueft auf neue Logzeilen und schreibt diese.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.stop">stop</a></td>
<td>Beendetden Thread und die FileHandler werden geschlossen.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="PipeLogwriter.__init__" ID="PipeLogwriter.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter (Constructor)</h3>
<b>PipeLogwriter</b>(<i>logfilename</i>)
<p>
Instantiiert PipeLogwriter-Klasse.
</p><dl>
<dt><i>logfilename</i></dt>
<dd>
Dateiname fuer Logdatei
</dd>
</dl><a NAME="PipeLogwriter.__del__" ID="PipeLogwriter.__del__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.__del__</h3>
<b>__del__</b>(<i></i>)
<p>
Close der FileHandler.
</p><a NAME="PipeLogwriter._configurefh" ID="PipeLogwriter._configurefh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter._configurefh</h3>
<b>_configurefh</b>(<i></i>)
<p>
Konfiguriert den FileHandler fuer Ausgaben der PLCAPP.
</p><dl>
<dt>Returns:</dt>
<dd>
FileHandler-Objekt
</dd>
</dl><a NAME="PipeLogwriter.logline" ID="PipeLogwriter.logline"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.logline</h3>
<b>logline</b>(<i>message</i>)
<p>
Schreibt eine Zeile in die Logdatei oder stdout.
</p><dl>
<dt><i>message</i></dt>
<dd>
Logzeile zum Schreiben
</dd>
</dl><a NAME="PipeLogwriter.newlogfile" ID="PipeLogwriter.newlogfile"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.newlogfile</h3>
<b>newlogfile</b>(<i></i>)
<p>
Konfiguriert den FileHandler auf eine neue Logdatei.
</p><a NAME="PipeLogwriter.run" ID="PipeLogwriter.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.run</h3>
<b>run</b>(<i></i>)
<p>
Prueft auf neue Logzeilen und schreibt diese.
</p><a NAME="PipeLogwriter.stop" ID="PipeLogwriter.stop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.stop</h3>
<b>stop</b>(<i></i>)
<p>
Beendetden Thread und die FileHandler werden geschlossen.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

147
doc/plcsystem.html Normal file
View File

@@ -0,0 +1,147 @@
<!DOCTYPE html>
<html><head>
<title>plcsystem</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
plcsystem</h1>
<p>
Modul fuer die Verwaltung der PLC Funktionen.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiPlc">RevPiPlc</a></td>
<td>Verwaltet das PLC Python Programm.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="RevPiPlc" ID="RevPiPlc"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiPlc</h2>
<p>
Verwaltet das PLC Python Programm.
</p><p>
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.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
Thread
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiPlc.__init__">RevPiPlc</a></td>
<td>Instantiiert RevPiPlc-Klasse.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc._configureplw">_configureplw</a></td>
<td>Konfiguriert den PipeLogwriter fuer Ausgaben der PLCAPP.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc._setuppopen">_setuppopen</a></td>
<td>Setzt UID und GID fuer das PLC Programm.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc._spopen">_spopen</a></td>
<td>Startet das PLC Programm.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc.newlogfile">newlogfile</a></td>
<td>Konfiguriert die FileHandler auf neue Logdatei.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc.run">run</a></td>
<td>Fuehrt PLC-Programm aus und ueberwacht es.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc.stop">stop</a></td>
<td>Beendet PLC-Programm.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiPlc.__init__" ID="RevPiPlc.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc (Constructor)</h3>
<b>RevPiPlc</b>(<i>program, arguments, pversion</i>)
<p>
Instantiiert RevPiPlc-Klasse.
</p><a NAME="RevPiPlc._configureplw" ID="RevPiPlc._configureplw"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc._configureplw</h3>
<b>_configureplw</b>(<i></i>)
<p>
Konfiguriert den PipeLogwriter fuer Ausgaben der PLCAPP.
</p><dl>
<dt>Returns:</dt>
<dd>
PipeLogwriter()
</dd>
</dl><a NAME="RevPiPlc._setuppopen" ID="RevPiPlc._setuppopen"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc._setuppopen</h3>
<b>_setuppopen</b>(<i></i>)
<p>
Setzt UID und GID fuer das PLC Programm.
</p><a NAME="RevPiPlc._spopen" ID="RevPiPlc._spopen"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc._spopen</h3>
<b>_spopen</b>(<i>lst_proc</i>)
<p>
Startet das PLC Programm.
</p><dl>
<dt><i>lst_proc</i></dt>
<dd>
Prozessliste
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
subprocess
</dd>
</dl><a NAME="RevPiPlc.newlogfile" ID="RevPiPlc.newlogfile"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc.newlogfile</h3>
<b>newlogfile</b>(<i></i>)
<p>
Konfiguriert die FileHandler auf neue Logdatei.
</p><a NAME="RevPiPlc.run" ID="RevPiPlc.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc.run</h3>
<b>run</b>(<i></i>)
<p>
Fuehrt PLC-Programm aus und ueberwacht es.
</p><a NAME="RevPiPlc.stop" ID="RevPiPlc.stop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc.stop</h3>
<b>stop</b>(<i></i>)
<p>
Beendet PLC-Programm.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -93,22 +93,13 @@ Static Methods</h3>
<a NAME="ProcimgServer.__init__" ID="ProcimgServer.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgServer (Constructor)</h3>
<b>ProcimgServer</b>(<i>logger, xmlserver, configrsc, procimg, aclmode</i>)
<b>ProcimgServer</b>(<i>xmlserver, aclmode</i>)
<p>
Instantiiert RevPiCheckServer()-Klasse.
</p><dl>
<dt><i>xmlserver</i></dt>
<dd>
XML-RPC Server
</dd><dt><i>procimg</i></dt>
<dd>
Pfad zum Prozessabbild
</dd><dt><i>configrsc</i></dt>
<dd>
Pfad zur piCtory Konfigurationsdatei
</dd><dt><i>logger</i></dt>
<dd>
Loggerinstanz
</dd><dt><i>aclmode</i></dt>
<dd>
Zugriffsrechte

View File

@@ -12,7 +12,7 @@ Main functions of our program.
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>forked</td></tr><tr><td>globalconffile</td></tr><tr><td>logapp</td></tr><tr><td>logger</td></tr><tr><td>logplc</td></tr><tr><td>pargs</td></tr><tr><td>startdir</td></tr>
<tr><td>forked</td></tr><tr><td>globalconffile</td></tr><tr><td>logapp</td></tr><tr><td>logger</td></tr><tr><td>logplc</td></tr><tr><td>pargs</td></tr><tr><td>picontrolreset</td></tr><tr><td>rapcatalog</td></tr><tr><td>startdir</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
@@ -23,6 +23,9 @@ Classes</h3>
Functions</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#_zeroprocimg">_zeroprocimg</a></td>
<td>Setzt Prozessabbild auf NULL.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#cleanup">cleanup</a></td>
<td>Clean up program.</td>
</tr><tr>
@@ -31,6 +34,14 @@ Functions</h3>
</tr>
</table>
<hr /><hr />
<a NAME="_zeroprocimg" ID="_zeroprocimg"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">_zeroprocimg</h2>
<b>_zeroprocimg</b>(<i>self</i>)
<p>
Setzt Prozessabbild auf NULL.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="cleanup" ID="cleanup"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">cleanup</h2>
<b>cleanup</b>(<i></i>)

View File

@@ -32,21 +32,12 @@ begrenzt werden!
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>configrsc</td></tr><tr><td>picontrolreset</td></tr><tr><td>procimg</td></tr><tr><td>pyloadverion</td></tr><tr><td>rapcatalog</td></tr>
<tr><td>pyloadverion</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#LogReader">LogReader</a></td>
<td>Ermoeglicht den Zugriff auf die Logdateien.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter">PipeLogwriter</a></td>
<td>File PIPE fuer das Schreiben des APP Log.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc">RevPiPlc</a></td>
<td>Verwaltet das PLC Python Programm.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad">RevPiPyLoad</a></td>
<td>Hauptklasse, die alle Funktionen zur Verfuegung stellt.</td>
</tr>
@@ -57,345 +48,6 @@ Functions</h3>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="LogReader" ID="LogReader"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">LogReader</h2>
<p>
Ermoeglicht den Zugriff auf die Logdateien.
</p><p>
Beinhaltet Funktionen fuer den Abruf der gesamten Logdatei fuer das
RevPiPyLoad-System und die Logdatei der PLC-Anwendung.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
None
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#LogReader.__init__">LogReader</a></td>
<td>Instantiiert LogReader-Klasse.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#LogReader.closeall">closeall</a></td>
<td>Fuehrt close auf File Handler durch.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#LogReader.load_applog">load_applog</a></td>
<td>Uebertraegt Logdaten des PLC Programms Binaer.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#LogReader.load_plclog">load_plclog</a></td>
<td>Uebertraegt Logdaten des Loaders Binaer.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="LogReader.__init__" ID="LogReader.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader (Constructor)</h3>
<b>LogReader</b>(<i></i>)
<p>
Instantiiert LogReader-Klasse.
</p><a NAME="LogReader.closeall" ID="LogReader.closeall"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader.closeall</h3>
<b>closeall</b>(<i></i>)
<p>
Fuehrt close auf File Handler durch.
</p><a NAME="LogReader.load_applog" ID="LogReader.load_applog"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader.load_applog</h3>
<b>load_applog</b>(<i>start, count</i>)
<p>
Uebertraegt Logdaten des PLC Programms Binaer.
</p><dl>
<dt><i>start</i></dt>
<dd>
Startbyte
</dd><dt><i>count</i></dt>
<dd>
Max. Byteanzahl zum uebertragen
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Binary() der Logdatei
</dd>
</dl><a NAME="LogReader.load_plclog" ID="LogReader.load_plclog"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader.load_plclog</h3>
<b>load_plclog</b>(<i>start, count</i>)
<p>
Uebertraegt Logdaten des Loaders Binaer.
</p><dl>
<dt><i>start</i></dt>
<dd>
Startbyte
</dd><dt><i>count</i></dt>
<dd>
Max. Byteanzahl zum uebertragen
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Binary() der Logdatei
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="PipeLogwriter" ID="PipeLogwriter"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">PipeLogwriter</h2>
<p>
File PIPE fuer das Schreiben des APP Log.
</p><p>
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.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
Thread
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.__init__">PipeLogwriter</a></td>
<td>Instantiiert PipeLogwriter-Klasse.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.__del__">__del__</a></td>
<td>Close file handler.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter._configurefh">_configurefh</a></td>
<td>Konfiguriert den FileHandler fuer Ausgaben der PLCAPP.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.logline">logline</a></td>
<td>Schreibt eine Zeile in die Logdatei oder stdout.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.newlogfile">newlogfile</a></td>
<td>Konfiguriert den FileHandler auf eine neue Logdatei.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.run">run</a></td>
<td>Prueft auf neue Logzeilen und schreibt diese.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.stop">stop</a></td>
<td>Beendetden Thread und die FileHandler werden geschlossen.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="PipeLogwriter.__init__" ID="PipeLogwriter.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter (Constructor)</h3>
<b>PipeLogwriter</b>(<i>logfilename</i>)
<p>
Instantiiert PipeLogwriter-Klasse.
</p><dl>
<dt><i>logfilename</i></dt>
<dd>
Dateiname fuer Logdatei
</dd>
</dl><a NAME="PipeLogwriter.__del__" ID="PipeLogwriter.__del__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.__del__</h3>
<b>__del__</b>(<i></i>)
<p>
Close file handler.
</p><a NAME="PipeLogwriter._configurefh" ID="PipeLogwriter._configurefh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter._configurefh</h3>
<b>_configurefh</b>(<i></i>)
<p>
Konfiguriert den FileHandler fuer Ausgaben der PLCAPP.
</p><dl>
<dt>Returns:</dt>
<dd>
FileHandler-Objekt
</dd>
</dl><a NAME="PipeLogwriter.logline" ID="PipeLogwriter.logline"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.logline</h3>
<b>logline</b>(<i>message</i>)
<p>
Schreibt eine Zeile in die Logdatei oder stdout.
</p><dl>
<dt><i>message</i></dt>
<dd>
Logzeile zum Schreiben
</dd>
</dl><a NAME="PipeLogwriter.newlogfile" ID="PipeLogwriter.newlogfile"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.newlogfile</h3>
<b>newlogfile</b>(<i></i>)
<p>
Konfiguriert den FileHandler auf eine neue Logdatei.
</p><a NAME="PipeLogwriter.run" ID="PipeLogwriter.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.run</h3>
<b>run</b>(<i></i>)
<p>
Prueft auf neue Logzeilen und schreibt diese.
</p><a NAME="PipeLogwriter.stop" ID="PipeLogwriter.stop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.stop</h3>
<b>stop</b>(<i></i>)
<p>
Beendetden Thread und die FileHandler werden geschlossen.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="RevPiPlc" ID="RevPiPlc"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiPlc</h2>
<p>
Verwaltet das PLC Python Programm.
</p><p>
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.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
Thread
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiPlc.__init__">RevPiPlc</a></td>
<td>Instantiiert RevPiPlc-Klasse.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc._configureplw">_configureplw</a></td>
<td>Konfiguriert den PipeLogwriter fuer Ausgaben der PLCAPP.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc._setuppopen">_setuppopen</a></td>
<td>Setzt UID und GID fuer das PLC Programm.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc._spopen">_spopen</a></td>
<td>Startet das PLC Programm.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc._zeroprocimg">_zeroprocimg</a></td>
<td>Setzt Prozessabbild auf NULL.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc.newlogfile">newlogfile</a></td>
<td>Konfiguriert die FileHandler auf neue Logdatei.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc.run">run</a></td>
<td>Fuehrt PLC-Programm aus und ueberwacht es.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPlc.stop">stop</a></td>
<td>Beendet PLC-Programm.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiPlc.__init__" ID="RevPiPlc.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc (Constructor)</h3>
<b>RevPiPlc</b>(<i>program, arguments, pversion</i>)
<p>
Instantiiert RevPiPlc-Klasse.
</p><a NAME="RevPiPlc._configureplw" ID="RevPiPlc._configureplw"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc._configureplw</h3>
<b>_configureplw</b>(<i></i>)
<p>
Konfiguriert den PipeLogwriter fuer Ausgaben der PLCAPP.
</p><dl>
<dt>Returns:</dt>
<dd>
PipeLogwriter()
</dd>
</dl><a NAME="RevPiPlc._setuppopen" ID="RevPiPlc._setuppopen"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc._setuppopen</h3>
<b>_setuppopen</b>(<i></i>)
<p>
Setzt UID und GID fuer das PLC Programm.
</p><a NAME="RevPiPlc._spopen" ID="RevPiPlc._spopen"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc._spopen</h3>
<b>_spopen</b>(<i>lst_proc</i>)
<p>
Startet das PLC Programm.
</p><dl>
<dt><i>lst_proc</i></dt>
<dd>
Prozessliste
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
subprocess
</dd>
</dl><a NAME="RevPiPlc._zeroprocimg" ID="RevPiPlc._zeroprocimg"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc._zeroprocimg</h3>
<b>_zeroprocimg</b>(<i></i>)
<p>
Setzt Prozessabbild auf NULL.
</p><a NAME="RevPiPlc.newlogfile" ID="RevPiPlc.newlogfile"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc.newlogfile</h3>
<b>newlogfile</b>(<i></i>)
<p>
Konfiguriert die FileHandler auf neue Logdatei.
</p><a NAME="RevPiPlc.run" ID="RevPiPlc.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc.run</h3>
<b>run</b>(<i></i>)
<p>
Fuehrt PLC-Programm aus und ueberwacht es.
</p><a NAME="RevPiPlc.stop" ID="RevPiPlc.stop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc.stop</h3>
<b>stop</b>(<i></i>)
<p>
Beendet PLC-Programm.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="RevPiPyLoad" ID="RevPiPyLoad"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiPyLoad</h2>
<p>

View File

@@ -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

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpipyload -->
<!-- Saved: 2017-07-06, 12:34:30 -->
<!-- Saved: 2017-09-12, 10:20:24 -->
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
<Project version="5.1">
<Language>en_US</Language>
@@ -9,15 +9,17 @@
<ProgLanguage mixed="0">Python3</ProgLanguage>
<ProjectType>Console</ProjectType>
<Description>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.</Description>
<Version>0.4.2</Version>
<Version>0.4.3</Version>
<Author>Sven Sager</Author>
<Email>akira@narux.de</Email>
<Eol index="-1"/>
<Eol index="1"/>
<Sources>
<Source>revpipyload/proginit.py</Source>
<Source>setup.py</Source>
<Source>revpipyload/revpipyload.py</Source>
<Source>revpipyload/procimgserver.py</Source>
<Source>revpipyload/logsystem.py</Source>
<Source>revpipyload/plcsystem.py</Source>
</Sources>
<Forms/>
<Translations/>

186
revpipyload/logsystem.py Normal file
View File

@@ -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()")

224
revpipyload/plcsystem.py Normal file
View File

@@ -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()")

View File

@@ -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()")

View File

@@ -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

View File

@@ -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()

View File

@@ -27,7 +27,7 @@ setup(
license="LGPLv3",
name="revpipyload",
version="0.4.2",
version="0.4.3",
scripts=["data/revpipyload"],