Mit default zusammenführen

This commit is contained in:
2018-09-03 07:55:54 +02:00
11 changed files with 629 additions and 45 deletions

View File

@@ -22,3 +22,14 @@ port = 55234
xmlrpc = 0 xmlrpc = 0
aclfile = /etc/revpipyload/aclxmlrpc.conf aclfile = /etc/revpipyload/aclxmlrpc.conf
bindip = * bindip = *
[MQTT]
mqtt = 0
basetopic = revpi/data
sendinterval = 10
host =
port = 1883
tls_set = 0
username =
password =
client_id =

View File

@@ -13,7 +13,7 @@ Packages</h3>
<table> <table>
<tr> <tr>
<td><a style="color:#0000FF" href="index-revpipyload.shared.html">shared</a></td> <td><a style="color:#0000FF" href="index-revpipyload.shared.html">shared</a></td>
<td>Shared modules.</td> <td></td>
</tr> </tr>
</table> </table>
@@ -27,6 +27,9 @@ Modules</h3>
<td><a style="color:#0000FF" href="logsystem.html">logsystem</a></td> <td><a style="color:#0000FF" href="logsystem.html">logsystem</a></td>
<td>Modul fuer die Verwaltung der Logdateien.</td> <td>Modul fuer die Verwaltung der Logdateien.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="mqttserver.html">mqttserver</a></td>
<td>Stellt die MQTT Uebertragung fuer IoT-Zwecke bereit.</td>
</tr><tr>
<td><a style="color:#0000FF" href="picontrolserver.html">picontrolserver</a></td> <td><a style="color:#0000FF" href="picontrolserver.html">picontrolserver</a></td>
<td>Modul fuer die Verwaltung der PLC-Slave Funktionen.</td> <td>Modul fuer die Verwaltung der PLC-Slave Funktionen.</td>
</tr><tr> </tr><tr>

177
doc/mqttserver.html Normal file
View File

@@ -0,0 +1,177 @@
<!DOCTYPE html>
<html><head>
<title>mqttserver</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">
mqttserver</h1>
<p>
Stellt die MQTT Uebertragung fuer IoT-Zwecke bereit.
</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="#MqttServer">MqttServer</a></td>
<td>Server fuer die Uebertragung des Prozessabbilds per MQTT.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="MqttServer" ID="MqttServer"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">MqttServer</h2>
<p>
Server fuer die Uebertragung des Prozessabbilds per MQTT.
</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="#MqttServer.__init__">MqttServer</a></td>
<td>Init MqttServer class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#MqttServer._get_procimglength">_get_procimglength</a></td>
<td>Ermittelt aus piCtory Konfiguration die laenge.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#MqttServer._on_connect">_on_connect</a></td>
<td>Verbindung zu MQTT Broker.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#MqttServer._on_disconnect">_on_disconnect</a></td>
<td>Wertet Verbindungsabbruch aus.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#MqttServer._on_message">_on_message</a></td>
<td>Sendet piCtory Konfiguration.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#MqttServer._send_pictory_conf">_send_pictory_conf</a></td>
<td>Sendet piCtory Konfiguration.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#MqttServer.newlogfile">newlogfile</a></td>
<td>Konfiguriert die FileHandler auf neue Logdatei.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#MqttServer.run">run</a></td>
<td>Startet die Uebertragung per MQTT.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#MqttServer.stop">stop</a></td>
<td>Stoppt die Uebertragung per MQTT.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="MqttServer.__init__" ID="MqttServer.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
MqttServer (Constructor)</h3>
<b>MqttServer</b>(<i>basetopic, sendinterval, host, port=1883, tls_set=False, username="", password=None, client_id=""</i>)
<p>
Init MqttServer class.
</p><dl>
<dt><i>basetopic</i></dt>
<dd>
Basis-Topic fuer Datenaustausch
</dd><dt><i>sendinterval</i></dt>
<dd>
Prozessabbild alle n Sekunden senden
</dd><dt><i>host</i></dt>
<dd>
Adresse <class 'str'> des MQTT-Servers
</dd><dt><i>port</i></dt>
<dd>
Portnummer <class 'int'> des MQTT-Servers
</dd><dt><i>keepalive</i></dt>
<dd>
MQTT Ping bei leerlauf
</dd><dt><i>tls_set</i></dt>
<dd>
TLS fuer Verbindung zum MQTT-Server verwenden
</dd><dt><i>username</i></dt>
<dd>
Optional Benutzername fuer MQTT-Server
</dd><dt><i>password</i></dt>
<dd>
Optional Password fuer MQTT-Server
</dd><dt><i>client_id</i></dt>
<dd>
MQTT ClientID, wenn leer automatisch random erzeugung
</dd>
</dl><a NAME="MqttServer._get_procimglength" ID="MqttServer._get_procimglength"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
MqttServer._get_procimglength</h3>
<b>_get_procimglength</b>(<i></i>)
<p>
Ermittelt aus piCtory Konfiguration die laenge.
</p><dl>
<dt>Returns:</dt>
<dd>
Laenge des Prozessabbilds <class 'int'>
</dd>
</dl><a NAME="MqttServer._on_connect" ID="MqttServer._on_connect"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
MqttServer._on_connect</h3>
<b>_on_connect</b>(<i>client, userdata, flags, rc</i>)
<p>
Verbindung zu MQTT Broker.
</p><a NAME="MqttServer._on_disconnect" ID="MqttServer._on_disconnect"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
MqttServer._on_disconnect</h3>
<b>_on_disconnect</b>(<i>client, userdata, rc</i>)
<p>
Wertet Verbindungsabbruch aus.
</p><a NAME="MqttServer._on_message" ID="MqttServer._on_message"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
MqttServer._on_message</h3>
<b>_on_message</b>(<i>client, userdata, msg</i>)
<p>
Sendet piCtory Konfiguration.
</p><a NAME="MqttServer._send_pictory_conf" ID="MqttServer._send_pictory_conf"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
MqttServer._send_pictory_conf</h3>
<b>_send_pictory_conf</b>(<i></i>)
<p>
Sendet piCtory Konfiguration.
</p><a NAME="MqttServer.newlogfile" ID="MqttServer.newlogfile"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
MqttServer.newlogfile</h3>
<b>newlogfile</b>(<i></i>)
<p>
Konfiguriert die FileHandler auf neue Logdatei.
</p><a NAME="MqttServer.run" ID="MqttServer.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
MqttServer.run</h3>
<b>run</b>(<i></i>)
<p>
Startet die Uebertragung per MQTT.
</p><a NAME="MqttServer.stop" ID="MqttServer.stop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
MqttServer.stop</h3>
<b>stop</b>(<i></i>)
<p>
Stoppt die Uebertragung per MQTT.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -9,8 +9,6 @@ revpipyload</h1>
<p> <p>
Revolution Pi Python PLC Loader. Revolution Pi Python PLC Loader.
</p><p> </p><p>
Webpage: https://revpimodio.org/revpipyplc/
</p><p>
Stellt das RevPiPyLoad Programm bereit. Dieses Programm lauft als Daemon auf Stellt das RevPiPyLoad Programm bereit. Dieses Programm lauft als Daemon auf
dem Revolution Pi. Es stellt Funktionen bereit, die es ermoeglichen ein Python dem Revolution Pi. Es stellt Funktionen bereit, die es ermoeglichen ein Python
Programm zu starten und fuehrt dessen Ausgaben in eine Logdatei. Die Logdaten Programm zu starten und fuehrt dessen Ausgaben in eine Logdatei. Die Logdaten
@@ -34,7 +32,7 @@ begrenzt werden!
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3> Global Attributes</h3>
<table> <table>
<tr><td>__author__</td></tr><tr><td>__copyright__</td></tr><tr><td>__license__</td></tr><tr><td>__version__</td></tr> <tr><td>pyloadversion</td></tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3> Classes</h3>
@@ -89,6 +87,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiPyLoad._loadconfig">_loadconfig</a></td> <td><a style="color:#0000FF" href="#RevPiPyLoad._loadconfig">_loadconfig</a></td>
<td>Load configuration file and setup modul.</td> <td>Load configuration file and setup modul.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad._plcmqtt">_plcmqtt</a></td>
<td>Konfiguriert den MQTT-Thread fuer die Ausfuehrung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad._plcslave">_plcslave</a></td> <td><a style="color:#0000FF" href="#RevPiPyLoad._plcslave">_plcslave</a></td>
<td>Erstellt den PlcSlave-Server Thread.</td> <td>Erstellt den PlcSlave-Server Thread.</td>
</tr><tr> </tr><tr>
@@ -113,6 +114,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiPyLoad.stop">stop</a></td> <td><a style="color:#0000FF" href="#RevPiPyLoad.stop">stop</a></td>
<td>Stop revpipyload.</td> <td>Stop revpipyload.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.stop_plcmqtt">stop_plcmqtt</a></td>
<td>Beendet MQTT Sender.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.stop_plcprogram">stop_plcprogram</a></td> <td><a style="color:#0000FF" href="#RevPiPyLoad.stop_plcprogram">stop_plcprogram</a></td>
<td>Beendet PLC Programm.</td> <td>Beendet PLC Programm.</td>
</tr><tr> </tr><tr>
@@ -134,6 +138,15 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_getprocimg">xml_getprocimg</a></td> <td><a style="color:#0000FF" href="#RevPiPyLoad.xml_getprocimg">xml_getprocimg</a></td>
<td>Gibt die Rohdaten aus piControl0 zurueck.</td> <td>Gibt die Rohdaten aus piControl0 zurueck.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_mqttrunning">xml_mqttrunning</a></td>
<td>Prueft ob MQTT Uebertragung noch lauft.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_mqttstart">xml_mqttstart</a></td>
<td>Startet die MQTT Uebertragung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_mqttstop">xml_mqttstop</a></td>
<td>Stoppt die MQTT Uebertragung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcdownload">xml_plcdownload</a></td> <td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcdownload">xml_plcdownload</a></td>
<td>Uebertraegt ein Archiv vom plcworkdir.</td> <td>Uebertraegt ein Archiv vom plcworkdir.</td>
</tr><tr> </tr><tr>
@@ -219,7 +232,18 @@ RevPiPyLoad._loadconfig</h3>
<b>_loadconfig</b>(<i></i>) <b>_loadconfig</b>(<i></i>)
<p> <p>
Load configuration file and setup modul. Load configuration file and setup modul.
</p><a NAME="RevPiPyLoad._plcslave" ID="RevPiPyLoad._plcslave"></a> </p><a NAME="RevPiPyLoad._plcmqtt" ID="RevPiPyLoad._plcmqtt"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad._plcmqtt</h3>
<b>_plcmqtt</b>(<i></i>)
<p>
Konfiguriert den MQTT-Thread fuer die Ausfuehrung.
</p><dl>
<dt>Returns:</dt>
<dd>
MQTT-Thread Object or None
</dd>
</dl><a NAME="RevPiPyLoad._plcslave" ID="RevPiPyLoad._plcslave"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad._plcslave</h3> RevPiPyLoad._plcslave</h3>
<b>_plcslave</b>(<i></i>) <b>_plcslave</b>(<i></i>)
@@ -290,6 +314,12 @@ RevPiPyLoad.stop</h3>
<b>stop</b>(<i></i>) <b>stop</b>(<i></i>)
<p> <p>
Stop revpipyload. Stop revpipyload.
</p><a NAME="RevPiPyLoad.stop_plcmqtt" ID="RevPiPyLoad.stop_plcmqtt"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.stop_plcmqtt</h3>
<b>stop_plcmqtt</b>(<i></i>)
<p>
Beendet MQTT Sender.
</p><a NAME="RevPiPyLoad.stop_plcprogram" ID="RevPiPyLoad.stop_plcprogram"></a> </p><a NAME="RevPiPyLoad.stop_plcprogram" ID="RevPiPyLoad.stop_plcprogram"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.stop_plcprogram</h3> RevPiPyLoad.stop_plcprogram</h3>
@@ -352,6 +382,42 @@ Gibt die Rohdaten aus piControl0 zurueck.
<dd> <dd>
xmlrpc.client.Binary() xmlrpc.client.Binary()
</dd> </dd>
</dl><a NAME="RevPiPyLoad.xml_mqttrunning" ID="RevPiPyLoad.xml_mqttrunning"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_mqttrunning</h3>
<b>xml_mqttrunning</b>(<i></i>)
<p>
Prueft ob MQTT Uebertragung noch lauft.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn MQTT Uebertragung noch lauft
</dd>
</dl><a NAME="RevPiPyLoad.xml_mqttstart" ID="RevPiPyLoad.xml_mqttstart"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_mqttstart</h3>
<b>xml_mqttstart</b>(<i></i>)
<p>
Startet die MQTT Uebertragung.
</p><dl>
<dt>Returns:</dt>
<dd>
Statuscode:
0: erfolgreich gestartet
-1: Nicht aktiv in Konfiguration
-2: Laeuft bereits
</dd>
</dl><a NAME="RevPiPyLoad.xml_mqttstop" ID="RevPiPyLoad.xml_mqttstop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_mqttstop</h3>
<b>xml_mqttstop</b>(<i></i>)
<p>
Stoppt die MQTT Uebertragung.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn stop erfolgreich
</dd>
</dl><a NAME="RevPiPyLoad.xml_plcdownload" ID="RevPiPyLoad.xml_plcdownload"></a> </dl><a NAME="RevPiPyLoad.xml_plcdownload" ID="RevPiPyLoad.xml_plcdownload"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcdownload</h3> RevPiPyLoad.xml_plcdownload</h3>

View File

@@ -1,6 +1,3 @@
helper.__author__?9
helper.__copyright__?9
helper.__license__?9
helper._setuprt?5(pid, evt_exit) helper._setuprt?5(pid, evt_exit)
helper._zeroprocimg?5() helper._zeroprocimg?5()
helper.refullmatch?4(regex, string) helper.refullmatch?4(regex, string)
@@ -15,9 +12,15 @@ logsystem.PipeLogwriter.newlogfile?4()
logsystem.PipeLogwriter.run?4() logsystem.PipeLogwriter.run?4()
logsystem.PipeLogwriter.stop?4() logsystem.PipeLogwriter.stop?4()
logsystem.PipeLogwriter?1(logfilename) logsystem.PipeLogwriter?1(logfilename)
logsystem.__author__?9 mqttserver.MqttServer._get_procimglength?5()
logsystem.__copyright__?9 mqttserver.MqttServer._on_connect?5(client, userdata, flags, rc)
logsystem.__license__?9 mqttserver.MqttServer._on_disconnect?5(client, userdata, rc)
mqttserver.MqttServer._on_message?5(client, userdata, msg)
mqttserver.MqttServer._send_pictory_conf?5()
mqttserver.MqttServer.newlogfile?4()
mqttserver.MqttServer.run?4()
mqttserver.MqttServer.stop?4()
mqttserver.MqttServer?1(basetopic, sendinterval, host, port=1883, tls_set=False, username="", password=None, client_id="")
picontrolserver.RevPiSlave.check_connectedacl?4() picontrolserver.RevPiSlave.check_connectedacl?4()
picontrolserver.RevPiSlave.newlogfile?4() picontrolserver.RevPiSlave.newlogfile?4()
picontrolserver.RevPiSlave.run?4() picontrolserver.RevPiSlave.run?4()
@@ -26,9 +29,6 @@ picontrolserver.RevPiSlave?1(ipacl, port=55234)
picontrolserver.RevPiSlaveDev.run?4() picontrolserver.RevPiSlaveDev.run?4()
picontrolserver.RevPiSlaveDev.stop?4() picontrolserver.RevPiSlaveDev.stop?4()
picontrolserver.RevPiSlaveDev?1(devcon, acl) picontrolserver.RevPiSlaveDev?1(devcon, acl)
picontrolserver.__author__?9
picontrolserver.__copyright__?9
picontrolserver.__license__?9
plcsystem.RevPiPlc.__get_autoreloaddelay?6() plcsystem.RevPiPlc.__get_autoreloaddelay?6()
plcsystem.RevPiPlc.__set_autoreloaddelay?6(value) plcsystem.RevPiPlc.__set_autoreloaddelay?6(value)
plcsystem.RevPiPlc._configureplw?5() plcsystem.RevPiPlc._configureplw?5()
@@ -39,23 +39,14 @@ plcsystem.RevPiPlc.newlogfile?4()
plcsystem.RevPiPlc.run?4() plcsystem.RevPiPlc.run?4()
plcsystem.RevPiPlc.stop?4() plcsystem.RevPiPlc.stop?4()
plcsystem.RevPiPlc?1(program, arguments, pversion) plcsystem.RevPiPlc?1(program, arguments, pversion)
plcsystem.__author__?9
plcsystem.__copyright__?9
plcsystem.__license__?9
procimgserver.ProcimgServer.devices?4() procimgserver.ProcimgServer.devices?4()
procimgserver.ProcimgServer.ios?4(iotype) procimgserver.ProcimgServer.ios?4(type)
procimgserver.ProcimgServer.loadrevpimodio?4() procimgserver.ProcimgServer.loadrevpimodio?4()
procimgserver.ProcimgServer.setvalue?4(device, io, value) procimgserver.ProcimgServer.setvalue?4(device, io, value)
procimgserver.ProcimgServer.start?4() procimgserver.ProcimgServer.start?4()
procimgserver.ProcimgServer.stop?4() procimgserver.ProcimgServer.stop?4()
procimgserver.ProcimgServer.values?4() procimgserver.ProcimgServer.values?4()
procimgserver.ProcimgServer?1(xmlserver) procimgserver.ProcimgServer?1(xmlserver)
procimgserver.__author__?9
procimgserver.__copyright__?9
procimgserver.__license__?9
proginit.__author__?9
proginit.__copyright__?9
proginit.__license__?9
proginit.cleanup?4() proginit.cleanup?4()
proginit.configure?4() proginit.configure?4()
proginit.forked?7 proginit.forked?7
@@ -70,6 +61,7 @@ proginit.startdir?7
revpipyload.RevPiPyLoad._check_mustrestart_plcprogram?5() revpipyload.RevPiPyLoad._check_mustrestart_plcprogram?5()
revpipyload.RevPiPyLoad._check_mustrestart_plcslave?5() revpipyload.RevPiPyLoad._check_mustrestart_plcslave?5()
revpipyload.RevPiPyLoad._loadconfig?5() revpipyload.RevPiPyLoad._loadconfig?5()
revpipyload.RevPiPyLoad._plcmqtt?5()
revpipyload.RevPiPyLoad._plcslave?5() revpipyload.RevPiPyLoad._plcslave?5()
revpipyload.RevPiPyLoad._plcthread?5() revpipyload.RevPiPyLoad._plcthread?5()
revpipyload.RevPiPyLoad._sigexit?5(signum, frame) revpipyload.RevPiPyLoad._sigexit?5(signum, frame)
@@ -79,6 +71,7 @@ revpipyload.RevPiPyLoad.packapp?4(mode="tar", pictory=False)
revpipyload.RevPiPyLoad.root?7 revpipyload.RevPiPyLoad.root?7
revpipyload.RevPiPyLoad.start?4() revpipyload.RevPiPyLoad.start?4()
revpipyload.RevPiPyLoad.stop?4() revpipyload.RevPiPyLoad.stop?4()
revpipyload.RevPiPyLoad.stop_plcmqtt?4()
revpipyload.RevPiPyLoad.stop_plcprogram?4() revpipyload.RevPiPyLoad.stop_plcprogram?4()
revpipyload.RevPiPyLoad.stop_plcslave?4() revpipyload.RevPiPyLoad.stop_plcslave?4()
revpipyload.RevPiPyLoad.stop_xmlrpcserver?4() revpipyload.RevPiPyLoad.stop_xmlrpcserver?4()
@@ -86,6 +79,9 @@ revpipyload.RevPiPyLoad.xml_getconfig?4()
revpipyload.RevPiPyLoad.xml_getfilelist?4() revpipyload.RevPiPyLoad.xml_getfilelist?4()
revpipyload.RevPiPyLoad.xml_getpictoryrsc?4() revpipyload.RevPiPyLoad.xml_getpictoryrsc?4()
revpipyload.RevPiPyLoad.xml_getprocimg?4() revpipyload.RevPiPyLoad.xml_getprocimg?4()
revpipyload.RevPiPyLoad.xml_mqttrunning?4()
revpipyload.RevPiPyLoad.xml_mqttstart?4()
revpipyload.RevPiPyLoad.xml_mqttstop?4()
revpipyload.RevPiPyLoad.xml_plcdownload?4(mode="tar", pictory=False) revpipyload.RevPiPyLoad.xml_plcdownload?4(mode="tar", pictory=False)
revpipyload.RevPiPyLoad.xml_plcexitcode?4() revpipyload.RevPiPyLoad.xml_plcexitcode?4()
revpipyload.RevPiPyLoad.xml_plcrunning?4() revpipyload.RevPiPyLoad.xml_plcrunning?4()
@@ -102,13 +98,7 @@ revpipyload.RevPiPyLoad.xml_reload?4()
revpipyload.RevPiPyLoad.xml_setconfig?4(dc, loadnow=False) revpipyload.RevPiPyLoad.xml_setconfig?4(dc, loadnow=False)
revpipyload.RevPiPyLoad.xml_setpictoryrsc?4(filebytes, reset=False) revpipyload.RevPiPyLoad.xml_setpictoryrsc?4(filebytes, reset=False)
revpipyload.RevPiPyLoad?1() revpipyload.RevPiPyLoad?1()
revpipyload.__author__?9 revpipyload.pyloadversion?7
revpipyload.__copyright__?9
revpipyload.__license__?9
revpipyload.__version__?9
revpipyload.shared.__author__?9
revpipyload.shared.__copyright__?9
revpipyload.shared.__license__?9
revpipyload.shared.ipaclmanager.IpAclManager.__get_acl?6() revpipyload.shared.ipaclmanager.IpAclManager.__get_acl?6()
revpipyload.shared.ipaclmanager.IpAclManager.__get_filename?6() revpipyload.shared.ipaclmanager.IpAclManager.__get_filename?6()
revpipyload.shared.ipaclmanager.IpAclManager.__get_regex_acl?6() revpipyload.shared.ipaclmanager.IpAclManager.__get_regex_acl?6()
@@ -122,10 +112,6 @@ revpipyload.shared.ipaclmanager.IpAclManager.loadaclfile?4(filename)
revpipyload.shared.ipaclmanager.IpAclManager.regex_acl?7 revpipyload.shared.ipaclmanager.IpAclManager.regex_acl?7
revpipyload.shared.ipaclmanager.IpAclManager.writeaclfile?4(filename=None, aclname=None) revpipyload.shared.ipaclmanager.IpAclManager.writeaclfile?4(filename=None, aclname=None)
revpipyload.shared.ipaclmanager.IpAclManager?1(minlevel, maxlevel, acl=None) revpipyload.shared.ipaclmanager.IpAclManager?1(minlevel, maxlevel, acl=None)
revpipyload.shared.ipaclmanager.__author__?9
revpipyload.shared.ipaclmanager.__copyright__?9
revpipyload.shared.ipaclmanager.__license__?9
revpipyload.shared.ipaclmanager.__version__?9
revpipyload.shared.ipaclmanager.refullmatch?4(regex, string) revpipyload.shared.ipaclmanager.refullmatch?4(regex, string)
xrpcserver.SaveXMLRPCRequestHandler.parse_request?4() xrpcserver.SaveXMLRPCRequestHandler.parse_request?4()
xrpcserver.SaveXMLRPCServer._dispatch?5(method, params) xrpcserver.SaveXMLRPCServer._dispatch?5(method, params)
@@ -134,6 +120,3 @@ xrpcserver.SaveXMLRPCServer.register_function?4(acl_level, function, name=None)
xrpcserver.SaveXMLRPCServer.start?4() xrpcserver.SaveXMLRPCServer.start?4()
xrpcserver.SaveXMLRPCServer.stop?4() xrpcserver.SaveXMLRPCServer.stop?4()
xrpcserver.SaveXMLRPCServer?1(addr, logRequests=True, allow_none=False, ipacl=None) xrpcserver.SaveXMLRPCServer?1(addr, logRequests=True, allow_none=False, ipacl=None)
xrpcserver.__author__?9
xrpcserver.__copyright__?9
xrpcserver.__license__?9

View File

@@ -1,3 +1,4 @@
MqttServer Thread
PipeLogwriter Thread PipeLogwriter Thread
RevPiPlc Thread RevPiPlc Thread
RevPiSlave Thread RevPiSlave Thread

View File

@@ -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.6.8</Version> <Version>0.7.0</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"/>
@@ -22,7 +22,7 @@
<Source>revpipyload/proginit.py</Source> <Source>revpipyload/proginit.py</Source>
<Source>revpipyload/revpipyload.py</Source> <Source>revpipyload/revpipyload.py</Source>
<Source>revpipyload/shared/__init__.py</Source> <Source>revpipyload/shared/__init__.py</Source>
<Source>revpipyload/shared/ipaclmanager.py</Source> <Source>revpipyload/mqttserver.py</Source>
<Source>revpipyload/xrpcserver.py</Source> <Source>revpipyload/xrpcserver.py</Source>
<Source>setup.py</Source> <Source>setup.py</Source>
</Sources> </Sources>

199
revpipyload/mqttserver.py Normal file
View File

@@ -0,0 +1,199 @@
# -*- coding: utf-8 -*-
#
# RevPiPyLoad
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
"""Stellt die MQTT Uebertragung fuer IoT-Zwecke bereit."""
import proginit
from json import load as jload
from ssl import CERT_NONE
from paho.mqtt.client import Client
from threading import Thread, Event
class MqttServer(Thread):
"""Server fuer die Uebertragung des Prozessabbilds per MQTT."""
def __init__(
self, basetopic, sendinterval, host, port=1883,
tls_set=False, username="", password=None, client_id=""):
"""Init MqttServer class.
@param basetopic Basis-Topic fuer Datenaustausch
@param sendinterval Prozessabbild alle n Sekunden senden
@param host Adresse <class 'str'> des MQTT-Servers
@param port Portnummer <class 'int'> des MQTT-Servers
@param keepalive MQTT Ping bei leerlauf
@param tls_set TLS fuer Verbindung zum MQTT-Server verwenden
@param username Optional Benutzername fuer MQTT-Server
@param password Optional Password fuer MQTT-Server
@param client_id MQTT ClientID, wenn leer automatisch random erzeugung
"""
# TODO: Parameterprüfung
super().__init__()
# Klassenvariablen
self.__exit = False
self._evt_data = Event()
self._host = host
self._procimglength = self._get_procimglength()
self._port = port
self._sendinterval = sendinterval
# Topics konfigurieren
self._mqtt_picontrol = "{}/picontrol".format(basetopic)
self._mqtt_pictory = "{}/pictory".format(basetopic)
self._mqtt_sendpictory = "{}/needpictory".format(basetopic)
self._mq = Client(client_id)
if username != "":
self._mq.username_pw_set(username, password)
if tls_set:
self._mq.tls_set(cert_reqs=CERT_NONE)
self._mq.tls_insecure_set(True)
# Handler konfigurieren
self._mq.on_connect = self._on_connect
self._mq.on_message = self._on_message
def _get_procimglength(self):
"""Ermittelt aus piCtory Konfiguration die laenge.
@return Laenge des Prozessabbilds <class 'int'>"""
try:
with open(proginit.pargs.configrsc, "r") as fh:
rsc = jload(fh)
except:
return 4096
length = 0
# piCtory Config prüfen
if "Devices" not in rsc:
return 0
# Letzes piCtory Device laden
last_dev = rsc["Devices"].pop()
length += last_dev["offset"]
# bei mem beginnen, weil nur der höchste IO benötigt wird
for type_iom in ["mem", "out", "inp"]:
lst_iom = sorted(
last_dev[type_iom],
key=lambda x: int(x),
reverse=True
)
if len(lst_iom) > 0:
# Daten des letzen IOM auswerten
last_iom = last_dev[type_iom][str(lst_iom[0])]
bitlength = int(last_iom[2])
length += int(last_iom[3])
length += 1 if bitlength == 1 else int(bitlength / 8)
break
return length
def _on_connect(self, client, userdata, flags, rc):
"""Verbindung zu MQTT Broker."""
if rc > 0:
proginit.warning("can not connect to mqtt broker - will retry")
else:
# piCtory übertragen um alle RevPiMqttIO zu benachrichtigen
self._send_pictory_conf()
# Subscribe piCtory Anforderung
client.subscribe(self._mqtt_sendpictory)
def _on_disconnect(self, client, userdata, rc):
"""Wertet Verbindungsabbruch aus."""
if rc != 0:
proginit.warning(
"unexpected disconnection from mqtt broker - "
"will try to reconnect"
)
def _on_message(self, client, userdata, msg):
"""Sendet piCtory Konfiguration."""
# piCtory Konfiguration senden
self._send_pictory_conf()
# Prozessabbild senden
self._evt_data.set()
def _send_pictory_conf(self):
"""Sendet piCtory Konfiguration."""
with open(proginit.pargs.configrsc, "rb") as fh:
self._mq.publish(self._mqtt_pictory, fh.read())
def newlogfile(self):
"""Konfiguriert die FileHandler auf neue Logdatei."""
pass
def run(self):
"""Startet die Uebertragung per MQTT."""
proginit.logger.debug("enter MqttServer.start()")
# Prozessabbild öffnen
try:
fh_proc = open(proginit.pargs.procimg, "r+b", 0)
except:
fh_proc = None
self.__exit = True
proginit.logger.error(
"can not open process image {}".format(proginit.pargs.procimg)
)
# MQTT verbinden
self._mq.connect_async(self._host, self._port, keepalive=60)
self._mq.loop_start()
# mainloop
buff = b''
err_count = 0
while not self.__exit:
self._evt_data.clear()
# Prozessabbild lesen
try:
fh_proc.seek(0)
buff = fh_proc.read(self._procimglength)
if err_count > 0:
proginit.warning(
"resume mqtt publishing after {} errors on "
"processimage".format(err_count)
)
err_count = 0
except IOError:
if err_count == 0:
proginit.logger.error(
"could not read process image for mqtt publishing"
)
err_count += 1
else:
# Prozessabbild übertragen
self._mq.publish(self._mqtt_picontrol, buff)
self._evt_data.wait(self._sendinterval)
# MQTT trennen
self._mq.loop_stop()
self._mq.disconnect()
# FileHandler schließen
if fh_proc is not None:
fh_proc.close()
proginit.logger.debug("leave MqttServer.start()")
def stop(self):
"""Stoppt die Uebertragung per MQTT."""
proginit.logger.debug("enter MqttServer.stop()")
self.__exit = True
self._evt_data.set()
proginit.logger.debug("leave MqttServer.stop()")

View File

@@ -221,7 +221,12 @@ class RevPiPlc(Thread):
# Prozess beenden # Prozess beenden
count = 0 count = 0
proginit.logger.info("term plc program {0}".format(self._program)) proginit.logger.info("term plc program {0}".format(self._program))
self._procplc.terminate() try:
self._procplc.terminate()
except ProcessLookupError:
proginit.logger.error("plc program was terminated unexpectedly")
proginit.logger.debug("leave RevPiPlc.stop()")
return
while self._procplc.poll() is None and count < 10: while self._procplc.poll() is None and count < 10:
count += 1 count += 1

View File

@@ -78,6 +78,7 @@ class RevPiPyLoad():
self.xmlrpcacl = IpAclManager(minlevel=0, maxlevel=4) self.xmlrpcacl = IpAclManager(minlevel=0, maxlevel=4)
# Threads/Prozesse # Threads/Prozesse
self.th_mqtt = None
self.th_plcslave = None self.th_plcslave = None
self.plc = None self.plc = None
@@ -144,6 +145,7 @@ class RevPiPyLoad():
proginit.logger.debug("enter RevPiPyLoad._loadconfig()") proginit.logger.debug("enter RevPiPyLoad._loadconfig()")
# Subsysteme herunterfahren # Subsysteme herunterfahren
self.stop_plcmqtt()
self.stop_xmlrpcserver() self.stop_xmlrpcserver()
# Konfigurationsdatei laden # Konfigurationsdatei laden
@@ -182,6 +184,28 @@ class RevPiPyLoad():
self.zeroonexit = \ self.zeroonexit = \
self.globalconfig["DEFAULT"].getboolean("zeroonexit", True) self.globalconfig["DEFAULT"].getboolean("zeroonexit", True)
# Konfiguration verarbeiten [MQTT]
self.mqtt = 0
if "MQTT" in self.globalconfig:
self.mqtt = \
int(self.globalconfig["MQTT"].get("mqtt", 0))
self.mqttbasetopic = \
self.globalconfig["MQTT"].get("basetopic", "")
self.mqttsendinterval = \
int(self.globalconfig["MQTT"].get("sendinterval", 15))
self.mqtthost = \
self.globalconfig["MQTT"].get("host", "")
self.mqttport = \
int(self.globalconfig["MQTT"].get("port", 1883))
self.mqtttls_set = \
int(self.globalconfig["MQTT"].get("tls_set", 0))
self.mqttusername = \
self.globalconfig["MQTT"].get("username", "")
self.mqttpassword = \
self.globalconfig["MQTT"].get("password", "")
self.mqttclient_id = \
self.globalconfig["MQTT"].get("client_id", "")
# Konfiguration verarbeiten [PLCSLAVE] # Konfiguration verarbeiten [PLCSLAVE]
self.plcslave = False self.plcslave = False
if "PLCSLAVE" in self.globalconfig: if "PLCSLAVE" in self.globalconfig:
@@ -238,6 +262,12 @@ class RevPiPyLoad():
) )
os.chdir(self.plcworkdir) os.chdir(self.plcworkdir)
# MQTT konfigurieren
self.th_mqtt = self._plcmqtt()
if self.th_mqtt is not None and not self._exit:
proginit.logger.info("start mqtt publisher")
self.th_mqtt.start()
# PLC Programm konfigurieren # PLC Programm konfigurieren
if restart_plcprogram: if restart_plcprogram:
self.stop_plcprogram() self.stop_plcprogram()
@@ -303,6 +333,8 @@ class RevPiPyLoad():
0, self.xml_plcstop, "plcstop") 0, self.xml_plcstop, "plcstop")
self.xsrv.register_function( self.xsrv.register_function(
0, self.xml_reload, "reload") 0, self.xml_reload, "reload")
self.xsrv.register_function(
0, self.xml_mqttrunning, "mqttrunning")
self.xsrv.register_function( self.xsrv.register_function(
0, self.xml_plcslaverunning, "plcslaverunning") 0, self.xml_plcslaverunning, "plcslaverunning")
@@ -343,6 +375,10 @@ class RevPiPyLoad():
lambda: os.system(proginit.picontrolreset), lambda: os.system(proginit.picontrolreset),
"resetpicontrol" "resetpicontrol"
) )
self.xsrv.register_function(
3, self.xml_mqttstart, "mqttstart")
self.xsrv.register_function(
3, self.xml_mqttstop, "mqttstop")
self.xsrv.register_function( self.xsrv.register_function(
3, self.xml_plcslavestart, "plcslavestart") 3, self.xml_plcslavestart, "plcslavestart")
self.xsrv.register_function( self.xsrv.register_function(
@@ -366,6 +402,32 @@ class RevPiPyLoad():
proginit.logger.debug("leave RevPiPyLoad._loadconfig()") proginit.logger.debug("leave RevPiPyLoad._loadconfig()")
def _plcmqtt(self):
"""Konfiguriert den MQTT-Thread fuer die Ausfuehrung.
@return MQTT-Thread Object or None"""
proginit.logger.debug("enter RevPiPyLoad._plcmqtt()")
th_plc = None
if self.mqtt:
try:
from mqttserver import MqttServer
th_plc = MqttServer(
self.mqttbasetopic,
self.mqttsendinterval,
self.mqtthost,
self.mqttport,
self.mqtttls_set,
self.mqttusername,
self.mqttpassword,
self.mqttclient_id
)
except:
# TODO: Fehlermeldung ausgeben bezüglich paho.mqtt
pass
proginit.logger.debug("leave RevPiPyLoad._plcmqtt()")
return th_plc
def _plcthread(self): def _plcthread(self):
"""Konfiguriert den PLC-Thread fuer die Ausfuehrung. """Konfiguriert den PLC-Thread fuer die Ausfuehrung.
@return PLC-Thread Object or None""" @return PLC-Thread Object or None"""
@@ -501,8 +563,12 @@ class RevPiPyLoad():
proginit.logger.info("start xmlrpc-server") proginit.logger.info("start xmlrpc-server")
self.xsrv.start() self.xsrv.start()
if self.plcslave: # MQTT Uebertragung starten
# Slaveausfuehrung übergeben if self.th_mqtt is not None:
self.th_mqtt.start()
# Slaveausfuehrung übergeben
if self.th_plcslave is not None:
self.th_plcslave.start() self.th_plcslave.start()
# PLC Programm automatisch starten # PLC Programm automatisch starten
@@ -517,6 +583,8 @@ class RevPiPyLoad():
proginit.logger.info("got reqeust to reload config") proginit.logger.info("got reqeust to reload config")
self._loadconfig() self._loadconfig()
# TODO: MQTT prüfen und neu starten
# PLC Server Thread prüfen # PLC Server Thread prüfen
if self.plcslave and self.th_plcslave is not None \ if self.plcslave and self.th_plcslave is not None \
and not self.th_plcslave.is_alive(): and not self.th_plcslave.is_alive():
@@ -541,8 +609,9 @@ class RevPiPyLoad():
proginit.logger.info("stopping revpipyload") proginit.logger.info("stopping revpipyload")
# Alle Sub-Systeme beenden # Alle Sub-Systeme beenden
self.stop_plcslave()
self.stop_plcprogram() self.stop_plcprogram()
self.stop_plcmqtt()
self.stop_plcslave()
self.stop_xmlrpcserver() self.stop_xmlrpcserver()
# Logreader schließen # Logreader schließen
@@ -556,6 +625,18 @@ class RevPiPyLoad():
self._exit = True self._exit = True
proginit.logger.debug("leave RevPiPyLoad.stop()") proginit.logger.debug("leave RevPiPyLoad.stop()")
def stop_plcmqtt(self):
"""Beendet MQTT Sender."""
proginit.logger.debug("enter RevPiPyLoad.stop_plcmqtt()")
if self.th_mqtt is not None and self.th_mqtt.is_alive():
proginit.logger.info("stopping mqtt thread")
self.th_mqtt.stop()
self.th_mqtt.join()
proginit.logger.debug("mqtt thread successfully closed")
proginit.logger.debug("leave RevPiPyLoad.stop_plcmqtt()")
def stop_plcprogram(self): def stop_plcprogram(self):
"""Beendet PLC Programm.""" """Beendet PLC Programm."""
proginit.logger.debug("enter RevPiPyLoad.stop_plcprogram()") proginit.logger.debug("enter RevPiPyLoad.stop_plcprogram()")
@@ -610,6 +691,17 @@ class RevPiPyLoad():
dc["zeroonerror"] = self.zeroonerror dc["zeroonerror"] = self.zeroonerror
dc["zeroonexit"] = self.zeroonexit dc["zeroonexit"] = self.zeroonexit
# MQTT Sektion
dc["mqtt"] = self.mqtt
dc["basetopic"] = self.mqttbasetopic
dc["sendinterval"] = self.mqttsendinterval
dc["host"] = self.mqtthost
dc["port"] = self.mqttport
dc["tls_set"] = self.mqtttls_set
dc["username"] = self.mqttusername
dc["password"] = self.mqttpassword
dc["client_id"] = self.mqttclient_id
# PLCSLAVE Sektion # PLCSLAVE Sektion
dc["plcslave"] = self.plcslave dc["plcslave"] = self.plcslave
dc["plcslaveacl"] = self.plcslaveacl.acl dc["plcslaveacl"] = self.plcslaveacl.acl
@@ -650,6 +742,42 @@ class RevPiPyLoad():
buff = fh.read() buff = fh.read()
return Binary(buff) return Binary(buff)
def xml_mqttrunning(self):
"""Prueft ob MQTT Uebertragung noch lauft.
@return True, wenn MQTT Uebertragung noch lauft"""
proginit.logger.debug("xmlrpc call mqttrunning")
return False if self.th_mqtt is None \
else self.th_mqtt.is_alive()
def xml_mqttstart(self):
"""Startet die MQTT Uebertragung.
@return Statuscode:
0: erfolgreich gestartet
-1: Nicht aktiv in Konfiguration
-2: Laeuft bereits
"""
if self.th_mqtt is not None and self.th_mqtt.is_alive():
return -2
else:
self.th_mqtt = self._plcmqtt()
if self.th_mqtt is None:
return -1
else:
self.th_mqtt.start()
return 0
def xml_mqttstop(self):
"""Stoppt die MQTT Uebertragung.
@return True, wenn stop erfolgreich"""
if self.th_mqtt is not None:
self.stop_plcmqtt()
self.th_mqtt = None
return True
else:
return False
def xml_plcdownload(self, mode="tar", pictory=False): def xml_plcdownload(self, mode="tar", pictory=False):
"""Uebertraegt ein Archiv vom plcworkdir. """Uebertraegt ein Archiv vom plcworkdir.
@@ -796,6 +924,17 @@ class RevPiPyLoad():
"zeroonerror": "[01]", "zeroonerror": "[01]",
"zeroonexit": "[01]", "zeroonexit": "[01]",
}, },
"MQTT": {
"mqtt": "[01]",
"mqttbasetopic": ".*",
"mqttsendinterval": "[0-9]+",
"mqtthost": ".+",
"mqttport": "[0-9]+",
"mqtttls_set": "[01]",
"mqttusername": ".*",
"mqttpassword": ".*",
"mqttclient_id": ".+",
},
"PLCSLAVE": { "PLCSLAVE": {
"plcslave": "[01]", "plcslave": "[01]",
"plcslaveacl": self.plcslaveacl.regex_acl, "plcslaveacl": self.plcslaveacl.regex_acl,

View File

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