signal für neue LogFiles erstellt. FileHandler werden umgehängt

logrotate ruft signal SIGUSR1 auf
Ausgaben des Python PLC Programms über eine PIPE führen um diese in neuen
Loghandler zu schreiben
proginit als globales Modul umgebaut (kein Vererbung mehr)
This commit is contained in:
2017-03-21 18:14:05 +01:00
parent 88ee0e4eae
commit b3c7544daa
7 changed files with 976 additions and 119 deletions

View File

@@ -1,12 +1,4 @@
/var/log/revpipyload /var/log/revpipyload
{
rotate 6
weekly
compress
delaycompress
missingok
notifempty
}
/var/log/revpipyloadapp /var/log/revpipyloadapp
{ {
rotate 6 rotate 6
@@ -15,4 +7,7 @@
delaycompress delaycompress
missingok missingok
notifempty notifempty
postrotate
kill -SIGUSR1 `cat /var/run/revpipyload.pid` > /dev/null 2>&1 || true
endscript
} }

50
doc/proginit.html Normal file
View File

@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html><head>
<title>proginit</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">
proginit</h1>
<p>
Main functions of our program.
</p>
<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>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#cleanup">cleanup</a></td>
<td>Clean up program.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#configure">configure</a></td>
<td>Initialize general program functions.</td>
</tr>
</table>
<hr /><hr />
<a NAME="cleanup" ID="cleanup"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">cleanup</h2>
<b>cleanup</b>(<i></i>)
<p>
Clean up program.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="configure" ID="configure"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">configure</h2>
<b>configure</b>(<i></i>)
<p>
Initialize general program functions.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

699
doc/revpipyload.html Normal file
View File

@@ -0,0 +1,699 @@
<!DOCTYPE html>
<html><head>
<title>revpipyload</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">
revpipyload</h1>
<p>
Revolution Pi Python PLC Loader.
</p><p>
Stellt das RevPiPyLoad Programm bereit. Dieses Programm lauft als Daemon auf
dem Revolution Pi. Es stellt Funktionen bereit, die es ermoeglichen ein Python
Programm zu starten und fuehrt dessen Ausgaben in eine Logdatei. Die Logdaten
koennen am Pi selber oder ueber eine XML-RPC Schnittstelle ausgelesen werden.
</p><p>
Dieser Daemon prueft ob das Python Programm noch lauft und kann es im Fall
eines Absturzes neu starten.
</p><p>
Ueber diesen Daemon kann die gesamte piCtory Konfiguration exportiert oder
importiert, ein Dump vom Prozessabbild gezogen und das eigene Python
Programm hochgeladen werden.
</p><p>
Es kann von dem Python Programm auch eine Archivdatei herunterladen werden,
welche optional auch die piCtory Konfiguraiton beinhaltet. Damit kann man sehr
schnell auf einem Revolution Pi das Programm inkl. piCtory Konfiguration
austauschen.
</p><p>
Die Zugriffsmoeglichkeiten koennen ueber einen Konfigurationsparameter
begrenzt werden!
</p>
<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>
</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></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>
</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.
Ausserdem koennen nur neue Zeilen abgerufen werden, um eine dynamische
Logansicht zu ermoeglichen.
</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.get_applines">get_applines</a></td>
<td>Gibt neue Zeilen ab letzen Aufruf zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#LogReader.get_applog">get_applog</a></td>
<td>Gibt die gesamte Logdatei zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#LogReader.get_plclines">get_plclines</a></td>
<td>Gibt neue Zeilen ab letzen Aufruf zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#LogReader.get_plclog">get_plclog</a></td>
<td>Gibt die gesamte Logdatei zurueck.</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.get_applines" ID="LogReader.get_applines"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader.get_applines</h3>
<b>get_applines</b>(<i></i>)
<p>
Gibt neue Zeilen ab letzen Aufruf zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
list() mit neuen Zeilen
</dd>
</dl><a NAME="LogReader.get_applog" ID="LogReader.get_applog"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader.get_applog</h3>
<b>get_applog</b>(<i></i>)
<p>
Gibt die gesamte Logdatei zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
str() mit Logdaten
</dd>
</dl><a NAME="LogReader.get_plclines" ID="LogReader.get_plclines"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader.get_plclines</h3>
<b>get_plclines</b>(<i></i>)
<p>
Gibt neue Zeilen ab letzen Aufruf zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
list() mit neuen Zeilen
</dd>
</dl><a NAME="LogReader.get_plclog" ID="LogReader.get_plclog"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
LogReader.get_plclog</h3>
<b>get_plclog</b>(<i></i>)
<p>
Gibt die gesamte Logdatei zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
str() mit Logdaten
</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>
<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></td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.run">run</a></td>
<td></td>
</tr><tr>
<td><a style="color:#0000FF" href="#PipeLogwriter.stop">stop</a></td>
<td></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>fh</i>)
<a NAME="PipeLogwriter.run" ID="PipeLogwriter.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.run</h3>
<b>run</b>(<i></i>)
<a NAME="PipeLogwriter.stop" ID="PipeLogwriter.stop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
PipeLogwriter.stop</h3>
<b>stop</b>(<i></i>)
<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._configurefh">_configurefh</a></td>
<td></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></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._configurefh" ID="RevPiPlc._configurefh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPlc._configurefh</h3>
<b>_configurefh</b>(<i></i>)
<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, filenum=None</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>)
<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>
Hauptklasse, die alle Funktionen zur Verfuegung stellt.
</p><p>
Hier wird die gesamte Konfiguraiton eingelesen und der ggf. aktivierte
XML-RPC-Server gestartet.
</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>root</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="#RevPiPyLoad.__init__">RevPiPyLoad</a></td>
<td>Instantiiert RevPiPyLoad-Klasse.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad._loadconfig">_loadconfig</a></td>
<td>Load configuration file and setup modul.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad._plcthread">_plcthread</a></td>
<td>Konfiguriert den PLC-Thread fuer die Ausfuehrung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad._sigexit">_sigexit</a></td>
<td>Signal handler to clean and exit program.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad._sigloadconfig">_sigloadconfig</a></td>
<td>Signal handler to load configuration.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad._signewlogfile">_signewlogfile</a></td>
<td>Signal handler to start new logfile.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.packapp">packapp</a></td>
<td>Erzeugt aus dem PLC-Programm ein TAR-File.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.start">start</a></td>
<td>Start plcload and PLC python program.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.stop">stop</a></td>
<td>Stop PLC python program and plcload.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_getconfig">xml_getconfig</a></td>
<td>Uebertraegt die RevPiPyLoad Konfiguration.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_getfilelist">xml_getfilelist</a></td>
<td>Uebertraegt die Dateiliste vom plcworkdir.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_getpictoryrsc">xml_getpictoryrsc</a></td>
<td>Gibt die config.rsc Datei von piCotry zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_getprocimg">xml_getprocimg</a></td>
<td>Gibt die Rohdaten aus piControl0 zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcdownload">xml_plcdownload</a></td>
<td>Uebertraegt ein Archiv vom plcworkdir.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcexitcode">xml_plcexitcode</a></td>
<td>Gibt den aktuellen exitcode vom PLC Programm zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcrunning">xml_plcrunning</a></td>
<td>Prueft ob das PLC Programm noch lauft.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcstart">xml_plcstart</a></td>
<td>Startet das PLC Programm.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcstop">xml_plcstop</a></td>
<td>Stoppt das PLC Programm.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcupload">xml_plcupload</a></td>
<td>Empfaengt Dateien fuer das PLC Programm.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcuploadclean">xml_plcuploadclean</a></td>
<td>Loescht das gesamte plcworkdir Verzeichnis.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_reload">xml_reload</a></td>
<td>Startet RevPiPyLoad neu und verwendet neue Konfiguraiton.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_setconfig">xml_setconfig</a></td>
<td>Empfaengt die RevPiPyLoad Konfiguration.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_setpictoryrsc">xml_setpictoryrsc</a></td>
<td>Schreibt die config.rsc Datei von piCotry.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiPyLoad.__init__" ID="RevPiPyLoad.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad (Constructor)</h3>
<b>RevPiPyLoad</b>(<i></i>)
<p>
Instantiiert RevPiPyLoad-Klasse.
</p><a NAME="RevPiPyLoad._loadconfig" ID="RevPiPyLoad._loadconfig"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad._loadconfig</h3>
<b>_loadconfig</b>(<i></i>)
<p>
Load configuration file and setup modul.
</p><a NAME="RevPiPyLoad._plcthread" ID="RevPiPyLoad._plcthread"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad._plcthread</h3>
<b>_plcthread</b>(<i></i>)
<p>
Konfiguriert den PLC-Thread fuer die Ausfuehrung.
</p><dl>
<dt>Returns:</dt>
<dd>
PLC-Thread Object or None
</dd>
</dl><a NAME="RevPiPyLoad._sigexit" ID="RevPiPyLoad._sigexit"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad._sigexit</h3>
<b>_sigexit</b>(<i>signum, frame</i>)
<p>
Signal handler to clean and exit program.
</p><a NAME="RevPiPyLoad._sigloadconfig" ID="RevPiPyLoad._sigloadconfig"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad._sigloadconfig</h3>
<b>_sigloadconfig</b>(<i>signum, frame</i>)
<p>
Signal handler to load configuration.
</p><a NAME="RevPiPyLoad._signewlogfile" ID="RevPiPyLoad._signewlogfile"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad._signewlogfile</h3>
<b>_signewlogfile</b>(<i>signum, frame</i>)
<p>
Signal handler to start new logfile.
</p><a NAME="RevPiPyLoad.packapp" ID="RevPiPyLoad.packapp"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.packapp</h3>
<b>packapp</b>(<i>mode="tar", pictory=False</i>)
<p>
Erzeugt aus dem PLC-Programm ein TAR-File.
</p><dl>
<dt><i>mode:</i></dt>
<dd>
Packart 'tar' oder 'zip'
</dd><dt><i>pictory:</i></dt>
<dd>
piCtory Konfiguration mit einpacken
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Dateinamen des Archivs
</dd>
</dl><a NAME="RevPiPyLoad.start" ID="RevPiPyLoad.start"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.start</h3>
<b>start</b>(<i></i>)
<p>
Start plcload and PLC python program.
</p><a NAME="RevPiPyLoad.stop" ID="RevPiPyLoad.stop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.stop</h3>
<b>stop</b>(<i></i>)
<p>
Stop PLC python program and plcload.
</p><a NAME="RevPiPyLoad.xml_getconfig" ID="RevPiPyLoad.xml_getconfig"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_getconfig</h3>
<b>xml_getconfig</b>(<i></i>)
<p>
Uebertraegt die RevPiPyLoad Konfiguration.
</p><dl>
<dt>Returns:</dt>
<dd>
dict() der Konfiguration
</dd>
</dl><a NAME="RevPiPyLoad.xml_getfilelist" ID="RevPiPyLoad.xml_getfilelist"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_getfilelist</h3>
<b>xml_getfilelist</b>(<i></i>)
<p>
Uebertraegt die Dateiliste vom plcworkdir.
</p><dl>
<dt>Returns:</dt>
<dd>
list() mit Dateinamen
</dd>
</dl><a NAME="RevPiPyLoad.xml_getpictoryrsc" ID="RevPiPyLoad.xml_getpictoryrsc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_getpictoryrsc</h3>
<b>xml_getpictoryrsc</b>(<i></i>)
<p>
Gibt die config.rsc Datei von piCotry zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
xmlrpc.client.Binary()
</dd>
</dl><a NAME="RevPiPyLoad.xml_getprocimg" ID="RevPiPyLoad.xml_getprocimg"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_getprocimg</h3>
<b>xml_getprocimg</b>(<i></i>)
<p>
Gibt die Rohdaten aus piControl0 zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
xmlrpc.client.Binary()
</dd>
</dl><a NAME="RevPiPyLoad.xml_plcdownload" ID="RevPiPyLoad.xml_plcdownload"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcdownload</h3>
<b>xml_plcdownload</b>(<i>mode="tar", pictory=False</i>)
<p>
Uebertraegt ein Archiv vom plcworkdir.
</p><dl>
<dt><i>mode:</i></dt>
<dd>
Archivart 'tar' 'zip'
</dd><dt><i>pictory:</i></dt>
<dd>
piCtory Konfiguraiton mit einpacken
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Binary() mit Archivdatei
</dd>
</dl><a NAME="RevPiPyLoad.xml_plcexitcode" ID="RevPiPyLoad.xml_plcexitcode"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcexitcode</h3>
<b>xml_plcexitcode</b>(<i></i>)
<p>
Gibt den aktuellen exitcode vom PLC Programm zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
int() exitcode oder:
-1 laeuft noch
-2 Datei nicht gefunden
-3 Lief nie
</dd>
</dl><a NAME="RevPiPyLoad.xml_plcrunning" ID="RevPiPyLoad.xml_plcrunning"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcrunning</h3>
<b>xml_plcrunning</b>(<i></i>)
<p>
Prueft ob das PLC Programm noch lauft.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn das PLC Programm noch lauft
</dd>
</dl><a NAME="RevPiPyLoad.xml_plcstart" ID="RevPiPyLoad.xml_plcstart"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcstart</h3>
<b>xml_plcstart</b>(<i></i>)
<p>
Startet das PLC Programm.
</p><dl>
<dt>Returns:</dt>
<dd>
int() Status:
-1 Programm lauft noch
-2 Datei nicht gefunden
</dd>
</dl><a NAME="RevPiPyLoad.xml_plcstop" ID="RevPiPyLoad.xml_plcstop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcstop</h3>
<b>xml_plcstop</b>(<i></i>)
<p>
Stoppt das PLC Programm.
</p><dl>
<dt>Returns:</dt>
<dd>
int() Exitcode vom PLC Programm
-1 PLC Programm lief nicht
</dd>
</dl><a NAME="RevPiPyLoad.xml_plcupload" ID="RevPiPyLoad.xml_plcupload"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcupload</h3>
<b>xml_plcupload</b>(<i>filedata, filename</i>)
<p>
Empfaengt Dateien fuer das PLC Programm.
</p><dl>
<dt><i>filedata:</i></dt>
<dd>
GZIP Binary data der datei
</dd><dt><i>filename:</i></dt>
<dd>
Name inkl. Unterverzeichnis der Datei
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Ture, wenn Datei erfolgreich gespeichert wurde
</dd>
</dl><a NAME="RevPiPyLoad.xml_plcuploadclean" ID="RevPiPyLoad.xml_plcuploadclean"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcuploadclean</h3>
<b>xml_plcuploadclean</b>(<i></i>)
<p>
Loescht das gesamte plcworkdir Verzeichnis.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn erfolgreich
</dd>
</dl><a NAME="RevPiPyLoad.xml_reload" ID="RevPiPyLoad.xml_reload"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_reload</h3>
<b>xml_reload</b>(<i></i>)
<p>
Startet RevPiPyLoad neu und verwendet neue Konfiguraiton.
</p><a NAME="RevPiPyLoad.xml_setconfig" ID="RevPiPyLoad.xml_setconfig"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_setconfig</h3>
<b>xml_setconfig</b>(<i>dc, loadnow=False</i>)
<p>
Empfaengt die RevPiPyLoad Konfiguration.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn erfolgreich angewendet
</dd>
</dl><a NAME="RevPiPyLoad.xml_setpictoryrsc" ID="RevPiPyLoad.xml_setpictoryrsc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_setpictoryrsc</h3>
<b>xml_setpictoryrsc</b>(<i>filebytes, reset=False</i>)
<p>
Schreibt die config.rsc Datei von piCotry.
</p><dl>
<dt><i>filebytes:</i></dt>
<dd>
xmlrpc.client.Binary()-Objekt
</dd><dt><i>reset:</i></dt>
<dd>
Reset piControl Device
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Statuscode:
0 Alles erfolgreich
-1 Kann JSON-Datei nicht laden
-2 piCtory Elemente in JSON-Datei nicht gefunden
-3 Konnte Konfiguraiton nicht schreiben
Positive Zahl ist exitcode von piControlReset
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd"> <!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpipyload --> <!-- eric project file for project revpipyload -->
<!-- Saved: 2017-03-20, 15:24:14 --> <!-- Saved: 2017-03-21, 18:11:09 -->
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de --> <!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
<Project version="5.1"> <Project version="5.1">
<Language>en_US</Language> <Language>en_US</Language>
@@ -9,7 +9,7 @@
<ProgLanguage mixed="0">Python3</ProgLanguage> <ProgLanguage mixed="0">Python3</ProgLanguage>
<ProjectType>Console</ProjectType> <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> <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.2.9</Version> <Version>0.2.10</Version>
<Author>Sven Sager</Author> <Author>Sven Sager</Author>
<Email>akira@narux.de</Email> <Email>akira@narux.de</Email>
<Eol index="-1"/> <Eol index="-1"/>

View File

@@ -1,108 +1,121 @@
#
# RevPiPyLoad
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Main functions of our program.""" """Main functions of our program."""
import logging import logging
import sys import sys
from argparse import ArgumentParser from argparse import ArgumentParser
from configparser import ConfigParser
from os import fork as osfork from os import fork as osfork
from os.path import exists as ospexists from os.path import exists as ospexists
forked = False
globalconffile = None
logapp = "revpipyloadapp.log" logapp = "revpipyloadapp.log"
logplc = "revpipyload.log" logplc = "revpipyload.log"
logger = None logger = None
pargs = None pargs = None
class ProgInit(): def cleanup():
"""Clean up program."""
# Logging beenden
logging.shutdown()
"""Programmfunktionen fuer Parameter und Logger."""
def __del__(self): def configure():
"""Clean up program.""" """Initialize general program functions."""
# Logging beenden
logging.shutdown()
def __init__(self): # Command arguments
"""Initialize general program functions.""" parser = ArgumentParser(
description="RevolutionPi Python3 Loader"
)
parser.add_argument(
"-d", "--daemon", action="store_true", dest="daemon",
help="Run program as a daemon in background"
)
parser.add_argument(
"-c", "--conffile", dest="conffile",
default="revpipyload.conf",
help="Application configuration file"
)
parser.add_argument(
"-f", "--logfile", dest="logfile",
help="Save log entries to this file"
)
parser.add_argument(
"-v", "--verbose", action="count", dest="verbose",
help="Switch on verbose logging"
)
global pargs
pargs = parser.parse_args()
# Command arguments # Prüfen ob als Daemon ausgeführt werden soll
parser = ArgumentParser( global forked
description="RevolutionPi Python3 Loader" pidfile = "/var/run/revpipyload.pid"
) pid = 0
parser.add_argument( if pargs.daemon and not forked:
"-d", "--daemon", action="store_true", dest="daemon", # Prüfen ob daemon schon läuft
help="Run program as a daemon in background" if ospexists(pidfile):
) raise SystemError(
parser.add_argument( "program already running as daemon. check {}".format(pidfile)
"-c", "--conffile", dest="conffile", )
default="revpipyload.conf",
help="Application configuration file"
)
parser.add_argument(
"-f", "--logfile", dest="logfile",
help="Save log entries to this file"
)
parser.add_argument(
"-v", "--verbose", action="count", dest="verbose",
help="Switch on verbose logging"
)
global pargs
pargs = parser.parse_args()
# Prüfen ob als Daemon ausgeführt werden soll # Zum daemon machen
self.pidfile = "/var/run/revpipyload.pid" pid = osfork()
self.pid = 0 if pid > 0:
if pargs.daemon: with open(pidfile, "w") as f:
# Prüfen ob daemon schon läuft f.write(str(pid))
if ospexists(self.pidfile): sys.exit(0)
raise SystemError( else:
"program already running as daemon. check {}".format( forked = True
self.pidfile
)
)
self.pid = osfork() if pargs.daemon:
if self.pid > 0: global logapp
with open(self.pidfile, "w") as f: global logplc
f.write(str(self.pid))
sys.exit(0)
global logapp # Ausgaben umhängen in Logfile
global logplc logapp = "/var/log/revpipyloadapp"
logplc = "/var/log/revpipyload"
pargs.conffile = "/etc/revpipyload/revpipyload.conf"
sys.stdout = open(logplc, "a")
sys.stderr = sys.stdout
# Ausgaben umhängen in Logfile # Initialize configparser globalconfig
logapp = "/var/log/revpipyloadapp" global globalconffile
logplc = "/var/log/revpipyload" globalconffile = pargs.conffile
pargs.conffile = "/etc/revpipyload/revpipyload.conf"
sys.stdout = open(logplc, "a")
sys.stderr = sys.stdout
# Initialize configparser globalconfig # Program logger
self.globalconffile = pargs.conffile global logger
self.globalconfig = ConfigParser() logger = logging.getLogger()
self.globalconfig.read(pargs.conffile)
# Program logger # Alle handler entfernen
global logger for lhandler in logger.handlers:
logger = logging.getLogger() logger.removeHandler(lhandler)
logformat = logging.Formatter(
"{asctime} [{levelname:8}] {message}", # Neue Handler bauen
datefmt="%Y-%m-%d %H:%M:%S", style="{" logformat = logging.Formatter(
) "{asctime} [{levelname:8}] {message}",
lhandler = logging.StreamHandler(sys.stdout) datefmt="%Y-%m-%d %H:%M:%S", style="{"
)
lhandler = logging.StreamHandler(sys.stdout)
lhandler.setFormatter(logformat)
logger.addHandler(lhandler)
if pargs.logfile is not None:
lhandler = logging.FileHandler(filename=pargs.logfile)
lhandler.setFormatter(logformat) lhandler.setFormatter(logformat)
logger.addHandler(lhandler) logger.addHandler(lhandler)
if pargs.logfile is not None:
lhandler = logging.FileHandler(filename=pargs.logfile)
lhandler.setFormatter(logformat)
logger.addHandler(lhandler)
# Loglevel auswerten # Loglevel auswerten
if pargs.verbose is None: if pargs.verbose is None:
loglevel = logging.WARNING loglevel = logging.WARNING
elif pargs.verbose == 1: elif pargs.verbose == 1:
loglevel = logging.INFO loglevel = logging.INFO
elif pargs.verbose > 1: elif pargs.verbose > 1:
loglevel = logging.DEBUG loglevel = logging.DEBUG
logger.setLevel(loglevel) logger.setLevel(loglevel)

View File

@@ -39,6 +39,7 @@ import subprocess
import tarfile import tarfile
import zipfile import zipfile
from concurrent import futures from concurrent import futures
from configparser import ConfigParser
from json import loads as jloads from json import loads as jloads
from re import match as rematch from re import match as rematch
from shutil import rmtree from shutil import rmtree
@@ -51,7 +52,7 @@ from xmlrpc.server import SimpleXMLRPCServer
configrsc = "/opt/KUNBUS/config.rsc" configrsc = "/opt/KUNBUS/config.rsc"
picontrolreset = "/opt/KUNBUS/piControlReset" picontrolreset = "/opt/KUNBUS/piControlReset"
procimg = "/dev/piControl0" procimg = "/dev/piControl0"
pyloadverion = "0.2.9" pyloadverion = "0.2.10"
class LogReader(): class LogReader():
@@ -72,6 +73,13 @@ class LogReader():
self.fhplc = None self.fhplc = None
self.posplc = 0 self.posplc = 0
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 get_applines(self): def get_applines(self):
"""Gibt neue Zeilen ab letzen Aufruf zurueck. """Gibt neue Zeilen ab letzen Aufruf zurueck.
@returns: list() mit neuen Zeilen""" @returns: list() mit neuen Zeilen"""
@@ -152,6 +160,39 @@ class LogReader():
return self.fhplc.read() return self.fhplc.read()
class PipeLogwriter(Thread):
def __init__(self, fh):
super().__init__()
self._exit = Event()
self.fh = fh
if fh is None:
self.pipeout = None
else:
self._pipein, self.pipeout = os.pipe()
def run(self):
if self.fh is not None:
fhread = os.fdopen(self._pipein)
proginit.logger.debug("enter logreader pipe")
while not self._exit.is_set():
line = fhread.readline()
try:
self.fh.write(line)
self.fh.flush()
except:
pass
proginit.logger.debug("leave logreader pipe")
def stop(self):
proginit.logger.debug("quit pipe logreader")
self._exit.set()
if self.pipeout is not None:
os.write(self.pipeout, b"\n")
os.close(self.pipeout)
os.close(self._pipein)
class RevPiPlc(Thread): class RevPiPlc(Thread):
"""Verwaltet das PLC Python Programm. """Verwaltet das PLC Python Programm.
@@ -170,8 +211,9 @@ class RevPiPlc(Thread):
self._arguments = arguments self._arguments = arguments
self._evt_exit = Event() self._evt_exit = Event()
self.exitcode = None self.exitcode = None
self._fh = None self._fh = self._configurefh()
self.gid = 65534 self.gid = 65534
self.plw = None
self._program = program self._program = program
self._procplc = None self._procplc = None
self._pversion = pversion self._pversion = pversion
@@ -179,21 +221,39 @@ class RevPiPlc(Thread):
self.zeroonerror = False self.zeroonerror = False
self.zeroonexit = False self.zeroonexit = False
def _configurefh(self):
# Ausgaben konfigurieren und ggf. umleiten
proginit.logger.debug("configure fh applog")
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:
return open(logfile, "a")
else:
return None
def _setuppopen(self): def _setuppopen(self):
"""Setzt UID und GID fuer das PLC Programm.""" """Setzt UID und GID fuer das PLC Programm."""
proginit.logger.debug(
"set uid {} and gid {}".format(self.uid, self.gid))
os.setgid(self.gid) os.setgid(self.gid)
os.setuid(self.uid) os.setuid(self.uid)
def _spopen(self, lst_proc): def _spopen(self, lst_proc, filenum=None):
"""Startet das PLC Programm. """Startet das PLC Programm.
@param lst_proc: Prozessliste @param lst_proc: Prozessliste
@returns: subprocess""" @returns: subprocess"""
proginit.logger.debug("configure subprocess")
return subprocess.Popen( return subprocess.Popen(
lst_proc, lst_proc,
preexec_fn=self._setuppopen, preexec_fn=self._setuppopen,
cwd=os.path.dirname(self._program), cwd=os.path.dirname(self._program),
bufsize=1, bufsize=1,
stdout=subprocess.STDOUT if self._fh is None else self._fh, stdout=subprocess.STDOUT if filenum is None else filenum,
stderr=subprocess.STDOUT stderr=subprocess.STDOUT
) )
@@ -203,6 +263,20 @@ class RevPiPlc(Thread):
f = open("/dev/piControl0", "w+b", 0) f = open("/dev/piControl0", "w+b", 0)
f.write(bytes(4096)) f.write(bytes(4096))
def newlogfile(self):
if self._fh is not None:
self._fh.close()
self._fh = self._configurefh()
if self.plw is not None:
self.plw.fh = self._fh
self._fh.write("-" * 55)
self._fh.write("\nstart new logfile: {}\n".format(asctime()))
self._fh.flush()
proginit.logger.info("new plc logfile")
def run(self): def run(self):
"""Fuehrt PLC-Programm aus und ueberwacht es.""" """Fuehrt PLC-Programm aus und ueberwacht es."""
if self._pversion == 2: if self._pversion == 2:
@@ -214,25 +288,21 @@ class RevPiPlc(Thread):
self._program, self._arguments self._program, self._arguments
)) ))
# Ausgaben konfigurieren und ggf. umleiten # Logausgabe
logfile = None if self._fh is not 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:
self._fh = open(logfile, "a")
self._fh.write("-" * 55) self._fh.write("-" * 55)
self._fh.write("\nplc: {} started: {}\n".format( self._fh.write("\nplc: {} started: {}\n".format(
os.path.basename(self._program), asctime() os.path.basename(self._program), asctime()
)) ))
self._fh.flush() self._fh.flush()
# LogWriter
self.plw = PipeLogwriter(self._fh)
self.plw.start()
# Prozess erstellen # Prozess erstellen
proginit.logger.info("start plc program {}".format(self._program)) proginit.logger.info("start plc program {}".format(self._program))
self._procplc = self._spopen(lst_proc) self._procplc = self._spopen(lst_proc, self.plw.pipeout)
while not self._evt_exit.is_set(): while not self._evt_exit.is_set():
@@ -263,7 +333,7 @@ class RevPiPlc(Thread):
if not self._evt_exit.is_set() and self.autoreload: if not self._evt_exit.is_set() and self.autoreload:
# Prozess neu starten # Prozess neu starten
self._procplc = self._spopen(lst_proc) self._procplc = self._spopen(lst_proc, self.plw.pipeout)
if self.exitcode == 0: if self.exitcode == 0:
proginit.logger.warning( proginit.logger.warning(
"restart plc program after clean exit" "restart plc program after clean exit"
@@ -277,8 +347,15 @@ class RevPiPlc(Thread):
self._evt_exit.wait(1) self._evt_exit.wait(1)
def stop(self):
"""Beendet PLC-Programm."""
proginit.logger.info("stop revpiplc thread")
self._evt_exit.set()
# Prüfen ob es einen subprocess gibt # Prüfen ob es einen subprocess gibt
if self._procplc is None: if self._procplc is None:
if self.plw is not None:
self.plw.stop()
return return
# Prozess beenden # Prozess beenden
@@ -305,12 +382,11 @@ class RevPiPlc(Thread):
or self.zeroonerror and self.exitcode != 0: or self.zeroonerror and self.exitcode != 0:
self._zeroprocimg() self._zeroprocimg()
def stop(self): if self.plw is not None:
"""Beendet PLC-Programm.""" self.plw.stop()
self._evt_exit.set()
class RevPiPyLoad(proginit.ProgInit): class RevPiPyLoad():
"""Hauptklasse, die alle Funktionen zur Verfuegung stellt. """Hauptklasse, die alle Funktionen zur Verfuegung stellt.
@@ -321,10 +397,11 @@ class RevPiPyLoad(proginit.ProgInit):
def __init__(self): def __init__(self):
"""Instantiiert RevPiPyLoad-Klasse.""" """Instantiiert RevPiPyLoad-Klasse."""
super().__init__() proginit.configure()
self._exit = True self._exit = True
self.evt_loadconfig = Event() self.evt_loadconfig = Event()
self.globalconfig = ConfigParser()
self.logr = LogReader() self.logr = LogReader()
self.plc = None self.plc = None
self.tfile = {} self.tfile = {}
@@ -338,6 +415,7 @@ class RevPiPyLoad(proginit.ProgInit):
signal.signal(signal.SIGINT, self._sigexit) signal.signal(signal.SIGINT, self._sigexit)
signal.signal(signal.SIGTERM, self._sigexit) signal.signal(signal.SIGTERM, self._sigexit)
signal.signal(signal.SIGHUP, self._sigloadconfig) signal.signal(signal.SIGHUP, self._sigloadconfig)
signal.signal(signal.SIGUSR1, self._signewlogfile)
def _loadconfig(self): def _loadconfig(self):
"""Load configuration file and setup modul.""" """Load configuration file and setup modul."""
@@ -353,9 +431,9 @@ class RevPiPyLoad(proginit.ProgInit):
# Konfigurationsdatei laden # Konfigurationsdatei laden
proginit.logger.info( proginit.logger.info(
"loading config file: {}".format(self.globalconffile) "loading config file: {}".format(proginit.globalconffile)
) )
self.globalconfig.read(self.globalconffile) self.globalconfig.read(proginit.globalconffile)
# Konfiguration verarbeiten # Konfiguration verarbeiten
self.autoreload = \ self.autoreload = \
@@ -473,11 +551,29 @@ class RevPiPyLoad(proginit.ProgInit):
proginit.logger.debug("got exit signal") proginit.logger.debug("got exit signal")
self.stop() self.stop()
# Programm aufräumen
proginit.cleanup()
def _sigloadconfig(self, signum, frame): def _sigloadconfig(self, signum, frame):
"""Signal handler to load configuration.""" """Signal handler to load configuration."""
proginit.logger.debug("got reload config signal") proginit.logger.debug("got reload config signal")
self.evt_loadconfig.set() self.evt_loadconfig.set()
def _signewlogfile(self, signum, frame):
"""Signal handler to start new logfile."""
proginit.logger.debug("got new logfile signal")
# Logger neu konfigurieren
proginit.configure()
proginit.logger.info("start new logfile: {}".format(asctime()))
# stdout für revpipyplc
if self.plc is not None:
self.plc.newlogfile()
# Logreader schließen
self.logr.closeall()
def packapp(self, mode="tar", pictory=False): def packapp(self, mode="tar", pictory=False):
"""Erzeugt aus dem PLC-Programm ein TAR-File. """Erzeugt aus dem PLC-Programm ein TAR-File.
@@ -673,9 +769,13 @@ class RevPiPyLoad(proginit.ProgInit):
def xml_plcstop(self): def xml_plcstop(self):
"""Stoppt das PLC Programm. """Stoppt das PLC Programm.
@returns: int() Exitcode vom PLC Programm"""
@returns: int() Exitcode vom PLC Programm
-1 PLC Programm lief nicht
"""
proginit.logger.debug("xmlrpc call plcstop") proginit.logger.debug("xmlrpc call plcstop")
if self.plc is not None: if self.plc is not None and self.plc.is_alive():
self.plc.stop() self.plc.stop()
self.plc.join() self.plc.join()
return self.plc.exitcode return self.plc.exitcode
@@ -760,10 +860,10 @@ class RevPiPyLoad(proginit.ProgInit):
self.globalconfig.set("DEFAULT", key, str(dc[key])) self.globalconfig.set("DEFAULT", key, str(dc[key]))
# conf-Datei schreiben # conf-Datei schreiben
fh = open(self.globalconffile, "w") fh = open(proginit.globalconffile, "w")
self.globalconfig.write(fh) self.globalconfig.write(fh)
proginit.logger.info( proginit.logger.info(
"got new config and wrote it to {}".format(self.globalconffile) "got new config and wrote it to {}".format(proginit.globalconffile)
) )
if loadnow: if loadnow:

View File

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