plcslave Thread startet automatisch, unabhängig vom plc Thread

ACL Liste für plcslave hinzugefügt
plcslaveport als Parameter übergeben
getconfig/setconfig auf neue Parameter angepasst
re.match auf re.fullmatch geändert
This commit is contained in:
2017-07-21 22:25:04 +02:00
parent 100e23aa26
commit bf75bba281
6 changed files with 235 additions and 52 deletions

View File

@@ -7,8 +7,11 @@ plcarguments=
plcuid=1000 plcuid=1000
plcgid=1000 plcgid=1000
plcslave=0 plcslave=0
plcslaveacl=
plcslaveport = 55234
pythonversion=3 pythonversion=3
xmlrpc=0 xmlrpc=0
xmlrpcacl =
xmlrpcport=55123 xmlrpcport=55123
zeroonerror=0 zeroonerror=0
zeroonexit=0 zeroonexit=0

View File

@@ -32,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>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>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>re_ipacl</td></tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3> Classes</h3>
@@ -61,6 +61,9 @@ Classes</h3>
Functions</h3> Functions</h3>
<table> <table>
<tr> <tr>
<td><a style="color:#0000FF" href="#_ipmatch">_ipmatch</a></td>
<td>Prueft IP gegen ACL List und gibt ACL aus.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#_zeroprocimg">_zeroprocimg</a></td> <td><a style="color:#0000FF" href="#_zeroprocimg">_zeroprocimg</a></td>
<td>Setzt Prozessabbild auf NULL.</td> <td>Setzt Prozessabbild auf NULL.</td>
</tr> </tr>
@@ -471,6 +474,12 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcrunning">xml_plcrunning</a></td> <td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcrunning">xml_plcrunning</a></td>
<td>Prueft ob das PLC Programm noch lauft.</td> <td>Prueft ob das PLC Programm noch lauft.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcslavestart">xml_plcslavestart</a></td>
<td>Startet den PLC Slave Server.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcslavestop">xml_plcslavestop</a></td>
<td>Stoppt den PLC Slave Server.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcstart">xml_plcstart</a></td> <td><a style="color:#0000FF" href="#RevPiPyLoad.xml_plcstart">xml_plcstart</a></td>
<td>Startet das PLC Programm.</td> <td>Startet das PLC Programm.</td>
</tr><tr> </tr><tr>
@@ -664,6 +673,31 @@ Prueft ob das PLC Programm noch lauft.
<dd> <dd>
True, wenn das PLC Programm noch lauft True, wenn das PLC Programm noch lauft
</dd> </dd>
</dl><a NAME="RevPiPyLoad.xml_plcslavestart" ID="RevPiPyLoad.xml_plcslavestart"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcslavestart</h3>
<b>xml_plcslavestart</b>(<i></i>)
<p>
Startet den PLC Slave Server.
</p><dl>
<dt>Returns:</dt>
<dd>
Statuscode:
0: erfolgreich gestartet
-1: Nicht aktiv in Konfiguration
-2: Laeuft bereits
</dd>
</dl><a NAME="RevPiPyLoad.xml_plcslavestop" ID="RevPiPyLoad.xml_plcslavestop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcslavestop</h3>
<b>xml_plcslavestop</b>(<i></i>)
<p>
Stoppt den PLC Slave Server.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn stop erfolgreich
</dd>
</dl><a NAME="RevPiPyLoad.xml_plcstart" ID="RevPiPyLoad.xml_plcstart"></a> </dl><a NAME="RevPiPyLoad.xml_plcstart" ID="RevPiPyLoad.xml_plcstart"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyLoad.xml_plcstart</h3> RevPiPyLoad.xml_plcstart</h3>
@@ -830,10 +864,18 @@ Static Methods</h3>
<a NAME="RevPiSlave.__init__" ID="RevPiSlave.__init__"></a> <a NAME="RevPiSlave.__init__" ID="RevPiSlave.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiSlave (Constructor)</h3> RevPiSlave (Constructor)</h3>
<b>RevPiSlave</b>(<i></i>) <b>RevPiSlave</b>(<i>acl, port=55234</i>)
<p> <p>
Instantiiert RevPiSlave-Klasse. Instantiiert RevPiSlave-Klasse.
</p><a NAME="RevPiSlave.newlogfile" ID="RevPiSlave.newlogfile"></a> </p><dl>
<dt><i>acl</i></dt>
<dd>
Stringliste mit Leerstellen getrennt
</dd><dt><i>port</i></dt>
<dd>
Listen Port fuer plc Slaveserver
</dd>
</dl><a NAME="RevPiSlave.newlogfile" ID="RevPiSlave.newlogfile"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiSlave.newlogfile</h3> RevPiSlave.newlogfile</h3>
<b>newlogfile</b>(<i></i>) <b>newlogfile</b>(<i></i>)
@@ -890,7 +932,7 @@ Static Methods</h3>
<a NAME="RevPiSlaveDev.__init__" ID="RevPiSlaveDev.__init__"></a> <a NAME="RevPiSlaveDev.__init__" ID="RevPiSlaveDev.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiSlaveDev (Constructor)</h3> RevPiSlaveDev (Constructor)</h3>
<b>RevPiSlaveDev</b>(<i>devcon, deadtime</i>) <b>RevPiSlaveDev</b>(<i>devcon, deadtime, acl</i>)
<a NAME="RevPiSlaveDev.run" ID="RevPiSlaveDev.run"></a> <a NAME="RevPiSlaveDev.run" ID="RevPiSlaveDev.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiSlaveDev.run</h3> RevPiSlaveDev.run</h3>
@@ -900,6 +942,27 @@ RevPiSlaveDev.run</h3>
RevPiSlaveDev.stop</h3> RevPiSlaveDev.stop</h3>
<b>stop</b>(<i></i>) <b>stop</b>(<i></i>)
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="_ipmatch" ID="_ipmatch"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">_ipmatch</h2>
<b>_ipmatch</b>(<i>ipaddress, dict_acl</i>)
<p>
Prueft IP gegen ACL List und gibt ACL aus.
</p><dl>
<dt><i>ipaddress</i></dt>
<dd>
zum pruefen
</dd><dt><i>dict_acl</i></dt>
<dd>
ACL Dict gegen die IP zu pruefen ist
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
int() ACL Wert oder -1 wenn nicht gefunden
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div> <div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr /> <hr /><hr />
<a NAME="_zeroprocimg" ID="_zeroprocimg"></a> <a NAME="_zeroprocimg" ID="_zeroprocimg"></a>

View File

@@ -49,6 +49,8 @@ revpipyload.RevPiPyLoad.xml_getprocimg?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()
revpipyload.RevPiPyLoad.xml_plcslavestart?4()
revpipyload.RevPiPyLoad.xml_plcslavestop?4()
revpipyload.RevPiPyLoad.xml_plcstart?4() revpipyload.RevPiPyLoad.xml_plcstart?4()
revpipyload.RevPiPyLoad.xml_plcstop?4() revpipyload.RevPiPyLoad.xml_plcstop?4()
revpipyload.RevPiPyLoad.xml_plcupload?4(filedata, filename) revpipyload.RevPiPyLoad.xml_plcupload?4(filedata, filename)
@@ -62,13 +64,15 @@ revpipyload.RevPiPyLoad?1()
revpipyload.RevPiSlave.newlogfile?4() revpipyload.RevPiSlave.newlogfile?4()
revpipyload.RevPiSlave.run?4() revpipyload.RevPiSlave.run?4()
revpipyload.RevPiSlave.stop?4() revpipyload.RevPiSlave.stop?4()
revpipyload.RevPiSlave?1() revpipyload.RevPiSlave?1(acl, port=55234)
revpipyload.RevPiSlaveDev.run?4() revpipyload.RevPiSlaveDev.run?4()
revpipyload.RevPiSlaveDev.stop?4() revpipyload.RevPiSlaveDev.stop?4()
revpipyload.RevPiSlaveDev?1(devcon, deadtime) revpipyload.RevPiSlaveDev?1(devcon, deadtime, acl)
revpipyload._ipmatch?5(ipaddress, dict_acl)
revpipyload._zeroprocimg?5() revpipyload._zeroprocimg?5()
revpipyload.configrsc?7 revpipyload.configrsc?7
revpipyload.picontrolreset?7 revpipyload.picontrolreset?7
revpipyload.procimg?7 revpipyload.procimg?7
revpipyload.pyloadverion?7 revpipyload.pyloadverion?7
revpipyload.rapcatalog?7 revpipyload.rapcatalog?7
revpipyload.re_ipacl?7

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-07-06, 12:34:30 --> <!-- Saved: 2017-07-21, 22:24:05 -->
<!-- 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.4.2</Version> <Version>0.5.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"/>

View File

@@ -38,12 +38,11 @@ import signal
import socket import socket
import subprocess import subprocess
import tarfile import tarfile
import warnings
import zipfile import zipfile
from concurrent import futures from concurrent import futures
from configparser import ConfigParser 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 fullmatch as refullmatch
from shutil import rmtree from shutil import rmtree
from sys import stdout as sysstdout from sys import stdout as sysstdout
from tempfile import mkstemp from tempfile import mkstemp
@@ -56,9 +55,26 @@ from xmlrpc.server import SimpleXMLRPCServer
configrsc = None configrsc = None
picontrolreset = "/opt/KUNBUS/piControlReset" picontrolreset = "/opt/KUNBUS/piControlReset"
procimg = "/dev/piControl0" procimg = "/dev/piControl0"
pyloadverion = "0.4.2" pyloadverion = "0.5.0"
rapcatalog = None rapcatalog = None
re_ipacl = "(([\\d\\*]{1,3}\\.){3}[\\d\\*]{1,3},[0-1] ?)+"
def _ipmatch(ipaddress, dict_acl):
"""Prueft IP gegen ACL List und gibt ACL aus.
@param ipaddress zum pruefen
@param dict_acl ACL Dict gegen die IP zu pruefen ist
@return int() ACL Wert oder -1 wenn nicht gefunden
"""
for aclip in sorted(dict_acl, reverse=True):
regex = aclip.replace(".", "\\.").replace("*", "\\d{1,3}")
if refullmatch(regex, ipaddress) is not None:
return str(dict_acl[aclip])
return "-1"
def _zeroprocimg(): def _zeroprocimg():
"""Setzt Prozessabbild auf NULL.""" """Setzt Prozessabbild auf NULL."""
@@ -439,16 +455,26 @@ class RevPiPlc(Thread):
class RevPiSlave(Thread): class RevPiSlave(Thread):
def __init__(self): def __init__(self, acl, port=55234):
"""Instantiiert RevPiSlave-Klasse.""" """Instantiiert RevPiSlave-Klasse.
@param acl Stringliste mit Leerstellen getrennt
@param port Listen Port fuer plc Slaveserver"""
super().__init__() super().__init__()
self.deadtime = 0.5 self.deadtime = 0.5
self._evt_exit = Event() self._evt_exit = Event()
self.exitcode = None self.exitcode = None
self.th_dev = [] self._port = port
self._th_dev = []
self.zeroonerror = False self.zeroonerror = False
self.zeroonexit = False self.zeroonexit = False
# ACLs aufbereiten
self.dict_acl = {}
for host in acl.split():
aclsplit = host.split(",")
self.dict_acl[aclsplit[0]] = \
"0" if len(aclsplit) == 1 else aclsplit[1]
def newlogfile(self): def newlogfile(self):
"""Konfiguriert die FileHandler auf neue Logdatei.""" """Konfiguriert die FileHandler auf neue Logdatei."""
pass pass
@@ -460,9 +486,8 @@ class RevPiSlave(Thread):
self.so = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.so = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while not self._evt_exit.is_set(): while not self._evt_exit.is_set():
try: try:
self.so.bind(("", 55234)) self.so.bind(("", self._port))
except: except:
warnings.warn("can not bind socket - retry", Warning)
proginit.logger.warning("can not bind socket - retry") proginit.logger.warning("can not bind socket - retry")
self._evt_exit.wait(1) self._evt_exit.wait(1)
else: else:
@@ -480,20 +505,30 @@ class RevPiSlave(Thread):
proginit.logger.exception("after accept") proginit.logger.exception("after accept")
continue continue
# Thread starten # ACL prüfen
th = RevPiSlaveDev(tup_sock, self.deadtime) aclstatus = _ipmatch(tup_sock[1][0], self.dict_acl)
th.start() if aclstatus == "-1":
self.th_dev.append(th) tup_sock[0].close()
proginit.logger.warning(
"host ip '{}' does not match revpiacl - disconnect"
"".format(tup_sock[1][0])
)
else:
# Thread starten
th = RevPiSlaveDev(tup_sock, self.deadtime, aclstatus)
th.start()
self._th_dev.append(th)
# TODO: tote Threads entfernen
# Alle Threads beenden # Alle Threads beenden
for th in self.th_dev: for th in self._th_dev:
th.stop() th.stop()
# Socket schließen # Socket schließen
self.so.close() self.so.close()
self.exitcode = 0 self.exitcode = 0
warnings.resetwarnings()
proginit.logger.debug("leave RevPiSlave.run()") proginit.logger.debug("leave RevPiSlave.run()")
def stop(self): def stop(self):
@@ -508,8 +543,9 @@ class RevPiSlave(Thread):
class RevPiSlaveDev(Thread): class RevPiSlaveDev(Thread):
def __init__(self, devcon, deadtime): def __init__(self, devcon, deadtime, acl):
super().__init__() super().__init__()
self._acl = acl
self.daemon = True self.daemon = True
self._deadtime = deadtime self._deadtime = deadtime
self._devcon, self._addr = devcon self._devcon, self._addr = devcon
@@ -522,8 +558,15 @@ class RevPiSlaveDev(Thread):
def run(self): def run(self):
proginit.logger.debug("enter RevPiSlaveDev.run()") proginit.logger.debug("enter RevPiSlaveDev.run()")
msgcli = [b'DATA', b'PICT', b'SEND'] proginit.logger.info(
proginit.logger.info("connected from {}".format(self._addr)) "got new connection from host {} with acl {}".format(
self._addr, self._acl)
)
# CMDs anhand ACL aufbauen
msgcli = [b'DATA', b'PICT']
if self._acl == "1":
msgcli.append(b'SEND')
# Prozessabbild öffnen # Prozessabbild öffnen
fh_proc = open(procimg, "r+b", 0) fh_proc = open(procimg, "r+b", 0)
@@ -717,10 +760,33 @@ class RevPiPyLoad():
self.globalconfig["DEFAULT"].get("plcworkdir", ".") self.globalconfig["DEFAULT"].get("plcworkdir", ".")
self.plcslave = \ self.plcslave = \
int(self.globalconfig["DEFAULT"].get("plcslave", 0)) int(self.globalconfig["DEFAULT"].get("plcslave", 0))
# PLC Slave ACL laden und prüfen
plcslaveacl = \
self.globalconfig["DEFAULT"].get("plcslaveacl", "")
if len(plcslaveacl) > 0 and refullmatch(re_ipacl, plcslaveacl) is None:
self.plcslaveacl = ""
proginit.logger.warning("can not load plcslaveacl - wrong format")
else:
self.plcslaveacl = plcslaveacl
self.plcslaveport = \
int(self.globalconfig["DEFAULT"].get("plcslaveport", 55234))
self.pythonver = \ self.pythonver = \
int(self.globalconfig["DEFAULT"].get("pythonversion", 3)) int(self.globalconfig["DEFAULT"].get("pythonversion", 3))
self.xmlrpc = \ self.xmlrpc = \
int(self.globalconfig["DEFAULT"].get("xmlrpc", 0)) int(self.globalconfig["DEFAULT"].get("xmlrpc", 0))
# XML ACL laden und prüfen
# TODO: xmlrpcacl auswerten
xmlrpcacl = \
self.globalconfig["DEFAULT"].get("xmlrpcacl", "")
if len(xmlrpcacl) > 0 and refullmatch(re_ipacl, xmlrpcacl) is None:
self.xmlrpcacl = ""
proginit.logger.warning("can not load xmlrpcacl - wrong format")
else:
self.xmlrpcacl = xmlrpcacl
self.zeroonerror = \ self.zeroonerror = \
int(self.globalconfig["DEFAULT"].get("zeroonerror", 1)) int(self.globalconfig["DEFAULT"].get("zeroonerror", 1))
self.zeroonexit = \ self.zeroonexit = \
@@ -731,6 +797,10 @@ class RevPiPyLoad():
# PLC Thread konfigurieren # PLC Thread konfigurieren
self.plc = self._plcthread() self.plc = self._plcthread()
if self.plcslave:
self.th_plcslave = RevPiSlave(self.plcslaveacl, self.plcslaveport)
else:
self.th_plcslave = None
# XMLRPC-Server Instantiieren und konfigurieren # XMLRPC-Server Instantiieren und konfigurieren
if self.xmlrpc >= 1: if self.xmlrpc >= 1:
@@ -791,6 +861,10 @@ class RevPiPyLoad():
self.xml_plcupload, "plcupload") self.xml_plcupload, "plcupload")
self.xsrv.register_function( self.xsrv.register_function(
self.xml_plcuploadclean, "plcuploadclean") self.xml_plcuploadclean, "plcuploadclean")
self.xsrv.register_function(
self.xml_plcslavestart, "plcslavestart")
self.xsrv.register_function(
self.xml_plcslavestop, "plcslavestop")
self.xsrv.register_function( self.xsrv.register_function(
lambda: os.system(picontrolreset), "resetpicontrol") lambda: os.system(picontrolreset), "resetpicontrol")
self.xsrv.register_function( self.xsrv.register_function(
@@ -816,31 +890,24 @@ class RevPiPyLoad():
proginit.logger.debug("enter RevPiPyLoad._plcthread()") proginit.logger.debug("enter RevPiPyLoad._plcthread()")
th_plc = None th_plc = None
if self.plcslave: # Prüfen ob Programm existiert
# Slaveausfuehrung übergeben if not os.path.exists(os.path.join(self.plcworkdir, self.plcprog)):
th_plc = RevPiSlave() proginit.logger.error("plc file does not exists {}".format(
th_plc.zeroonerror = self.zeroonerror os.path.join(self.plcworkdir, self.plcprog)
th_plc.zeroonexit = self.zeroonexit ))
return None
else: proginit.logger.debug("create PLC watcher")
# Prüfen ob Programm existiert th_plc = RevPiPlc(
if not os.path.exists(os.path.join(self.plcworkdir, self.plcprog)): os.path.join(self.plcworkdir, self.plcprog),
proginit.logger.error("plc file does not exists {}".format( self.plcarguments,
os.path.join(self.plcworkdir, self.plcprog) self.pythonver
)) )
return None th_plc.autoreload = self.autoreload
th_plc.gid = int(self.globalconfig["DEFAULT"].get("plcgid", 65534))
proginit.logger.debug("create PLC watcher") th_plc.uid = int(self.globalconfig["DEFAULT"].get("plcuid", 65534))
th_plc = RevPiPlc( th_plc.zeroonerror = self.zeroonerror
os.path.join(self.plcworkdir, self.plcprog), th_plc.zeroonexit = self.zeroonexit
self.plcarguments,
self.pythonver
)
th_plc.autoreload = self.autoreload
th_plc.gid = int(self.globalconfig["DEFAULT"].get("plcgid", 65534))
th_plc.uid = int(self.globalconfig["DEFAULT"].get("plcuid", 65534))
th_plc.zeroonerror = self.zeroonerror
th_plc.zeroonexit = self.zeroonexit
proginit.logger.debug("leave RevPiPyLoad._plcthread()") proginit.logger.debug("leave RevPiPyLoad._plcthread()")
return th_plc return th_plc
@@ -939,6 +1006,10 @@ class RevPiPyLoad():
self.tpe = futures.ThreadPoolExecutor(max_workers=1) self.tpe = futures.ThreadPoolExecutor(max_workers=1)
self.tpe.submit(self.xsrv.serve_forever) self.tpe.submit(self.xsrv.serve_forever)
if self.plcslave:
# Slaveausfuehrung übergeben
self.th_plcslave.start()
if self.autostart: if self.autostart:
proginit.logger.debug("starting revpiplc-thread") proginit.logger.debug("starting revpiplc-thread")
if self.plc is not None: if self.plc is not None:
@@ -971,8 +1042,14 @@ class RevPiPyLoad():
proginit.logger.info("stopping revpipyload") proginit.logger.info("stopping revpipyload")
self._exit = True self._exit = True
if self.th_plcslave is not None and self.th_plcslave.is_alive():
proginit.logger.debug("stopping revpi slave thread")
self.th_plcslave.stop()
self.th_plcslave.join()
proginit.logger.debug("revpi slave thread successfully closed")
if self.plc is not None and self.plc.is_alive(): if self.plc is not None and self.plc.is_alive():
proginit.logger.debug("stopping revpiplc-thread") proginit.logger.debug("stopping revpiplc thread")
self.plc.stop() self.plc.stop()
self.plc.join() self.plc.join()
proginit.logger.debug("revpiplc thread successfully closed") proginit.logger.debug("revpiplc thread successfully closed")
@@ -996,8 +1073,11 @@ class RevPiPyLoad():
dc["plcprogram"] = self.plcprog dc["plcprogram"] = self.plcprog
dc["plcarguments"] = self.plcarguments dc["plcarguments"] = self.plcarguments
dc["plcslave"] = self.plcslave dc["plcslave"] = self.plcslave
dc["plcslaveacl"] = self.plcslaveacl
dc["plcslaveport"] = self.plcslaveport
dc["pythonversion"] = self.pythonver dc["pythonversion"] = self.pythonver
dc["xmlrpc"] = self.xmlrpc dc["xmlrpc"] = self.xmlrpc
dc["xmlrpcacl"] = self.xmlrpcacl
dc["xmlrpcport"] = \ dc["xmlrpcport"] = \
self.globalconfig["DEFAULT"].get("xmlrpcport", 55123) self.globalconfig["DEFAULT"].get("xmlrpcport", 55123)
dc["zeroonerror"] = self.zeroonerror dc["zeroonerror"] = self.zeroonerror
@@ -1170,8 +1250,11 @@ class RevPiPyLoad():
"plcprogram": ".+", "plcprogram": ".+",
"plcarguments": ".*", "plcarguments": ".*",
"plcslave": "[01]", "plcslave": "[01]",
"plcslaveacl": re_ipacl,
"plcslaveport": "[0-9]{,5}",
"pythonversion": "[23]", "pythonversion": "[23]",
"xmlrpc": "[0-3]", "xmlrpc": "[0-3]",
"xmlrpcacl": re_ipacl,
"xmlrpcport": "[0-9]{,5}", "xmlrpcport": "[0-9]{,5}",
"zeroonerror": "[01]", "zeroonerror": "[01]",
"zeroonexit": "[01]" "zeroonexit": "[01]"
@@ -1180,7 +1263,7 @@ class RevPiPyLoad():
# Werte übernehmen # Werte übernehmen
for key in keys: for key in keys:
if key in dc: if key in dc:
if rematch(keys[key], str(dc[key])) is None: if refullmatch(keys[key], str(dc[key])) is None:
proginit.logger.error( proginit.logger.error(
"got wrong setting '{}' with value '{}'".format( "got wrong setting '{}' with value '{}'".format(
key, dc[key] key, dc[key]
@@ -1276,6 +1359,36 @@ class RevPiPyLoad():
else: else:
return False return False
def xml_plcslavestart(self):
"""Startet den PLC Slave Server.
@return Statuscode:
0: erfolgreich gestartet
-1: Nicht aktiv in Konfiguration
-2: Laeuft bereits
"""
if self.plcslave:
if self.th_plcslave is not None and self.th_plcslave.is_alive():
return -2
else:
self.th_plcslave = RevPiSlave(
self.plcslaveacl, self.plcslaveport
)
self.th_plcslave.start()
return 0
else:
return -1
def xml_plcslavestop(self):
"""Stoppt den PLC Slave Server.
@return True, wenn stop erfolgreich"""
if self.th_plcslave is not None:
self.th_plcslave.stop()
return True
else:
return False
if __name__ == "__main__": if __name__ == "__main__":
root = RevPiPyLoad() root = RevPiPyLoad()

View File

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