mirror of
https://github.com/naruxde/revpipyload.git
synced 2025-11-08 23:23:52 +01:00
Verschmelzung mit default
This commit is contained in:
@@ -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-28, 10:07:15 -->
|
<!-- Saved: 2017-03-27, 10:26:18 -->
|
||||||
<!-- 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.11</Version>
|
<Version>0.3.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"/>
|
||||||
|
|||||||
@@ -35,8 +35,10 @@ import proginit
|
|||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import signal
|
import signal
|
||||||
|
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
|
||||||
@@ -47,13 +49,21 @@ from sys import stdout as sysstdout
|
|||||||
from tempfile import mktemp
|
from tempfile import mktemp
|
||||||
from threading import Thread, Event, Lock
|
from threading import Thread, Event, Lock
|
||||||
from time import sleep, asctime
|
from time import sleep, asctime
|
||||||
|
from timeit import default_timer
|
||||||
from xmlrpc.client import Binary
|
from xmlrpc.client import Binary
|
||||||
from xmlrpc.server import SimpleXMLRPCServer
|
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.11"
|
pyloadverion = "0.3.0"
|
||||||
|
|
||||||
|
|
||||||
|
def _zeroprocimg():
|
||||||
|
"""Setzt Prozessabbild auf NULL."""
|
||||||
|
if os.path.exists(procimg):
|
||||||
|
f = open(procimg, "w+b", 0)
|
||||||
|
f.write(bytes(4096))
|
||||||
|
|
||||||
|
|
||||||
class LogReader():
|
class LogReader():
|
||||||
@@ -304,7 +314,7 @@ class RevPiPlc(Thread):
|
|||||||
elif proginit.pargs.logfile is not None:
|
elif proginit.pargs.logfile is not None:
|
||||||
logfile = proginit.pargs.logfile
|
logfile = proginit.pargs.logfile
|
||||||
|
|
||||||
if not logfile is None:
|
if logfile is not None:
|
||||||
logfile = PipeLogwriter(logfile)
|
logfile = PipeLogwriter(logfile)
|
||||||
|
|
||||||
proginit.logger.debug("leave RevPiPlc._configureplw()")
|
proginit.logger.debug("leave RevPiPlc._configureplw()")
|
||||||
@@ -333,12 +343,6 @@ class RevPiPlc(Thread):
|
|||||||
proginit.logger.debug("leave RevPiPlc._spopen()")
|
proginit.logger.debug("leave RevPiPlc._spopen()")
|
||||||
return sp
|
return sp
|
||||||
|
|
||||||
def _zeroprocimg(self):
|
|
||||||
"""Setzt Prozessabbild auf NULL."""
|
|
||||||
if os.path.exists("/dev/piControl0"):
|
|
||||||
f = open("/dev/piControl0", "w+b", 0)
|
|
||||||
f.write(bytes(4096))
|
|
||||||
|
|
||||||
def newlogfile(self):
|
def newlogfile(self):
|
||||||
"""Konfiguriert die FileHandler auf neue Logdatei."""
|
"""Konfiguriert die FileHandler auf neue Logdatei."""
|
||||||
proginit.logger.debug("enter RevPiPlc.newlogfile()")
|
proginit.logger.debug("enter RevPiPlc.newlogfile()")
|
||||||
@@ -387,7 +391,7 @@ class RevPiPlc(Thread):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
if self.zeroonerror:
|
if self.zeroonerror:
|
||||||
self._zeroprocimg()
|
_zeroprocimg()
|
||||||
proginit.logger.warning(
|
proginit.logger.warning(
|
||||||
"set piControl0 to ZERO after PLC program error")
|
"set piControl0 to ZERO after PLC program error")
|
||||||
|
|
||||||
@@ -395,7 +399,7 @@ class RevPiPlc(Thread):
|
|||||||
# PLC Python Programm sauber beendet
|
# PLC Python Programm sauber beendet
|
||||||
proginit.logger.info("plc program did a clean exit")
|
proginit.logger.info("plc program did a clean exit")
|
||||||
if self.zeroonexit:
|
if self.zeroonexit:
|
||||||
self._zeroprocimg()
|
_zeroprocimg()
|
||||||
proginit.logger.info(
|
proginit.logger.info(
|
||||||
"set piControl0 to ZERO after PLC program returns "
|
"set piControl0 to ZERO after PLC program returns "
|
||||||
"clean exitcode")
|
"clean exitcode")
|
||||||
@@ -457,7 +461,7 @@ class RevPiPlc(Thread):
|
|||||||
self.exitcode = self._procplc.poll()
|
self.exitcode = self._procplc.poll()
|
||||||
if self.zeroonexit and self.exitcode == 0 \
|
if self.zeroonexit and self.exitcode == 0 \
|
||||||
or self.zeroonerror and self.exitcode != 0:
|
or self.zeroonerror and self.exitcode != 0:
|
||||||
self._zeroprocimg()
|
_zeroprocimg()
|
||||||
|
|
||||||
if self._plw is not None:
|
if self._plw is not None:
|
||||||
self._plw.stop()
|
self._plw.stop()
|
||||||
@@ -468,6 +472,132 @@ class RevPiPlc(Thread):
|
|||||||
proginit.logger.debug("leave RevPiPlc.stop()")
|
proginit.logger.debug("leave RevPiPlc.stop()")
|
||||||
|
|
||||||
|
|
||||||
|
class RevPiSlave(Thread):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""Instantiiert RevPiSlave-Klasse."""
|
||||||
|
super().__init__()
|
||||||
|
self.deadtime = 0.5
|
||||||
|
self._evt_exit = Event()
|
||||||
|
self.zeroonerror = False
|
||||||
|
self.zeroonexit = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
proginit.logger.debug("enter RevPiSlave.run()")
|
||||||
|
|
||||||
|
msgcli = [b'DATA', b'PICT', b'SEND']
|
||||||
|
|
||||||
|
# Socket öffnen und konfigurieren
|
||||||
|
self.so = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
while not self._evt_exit.is_set():
|
||||||
|
try:
|
||||||
|
self.so.bind(("", 55234))
|
||||||
|
except:
|
||||||
|
warnings.warn("can not bind socket - retry", Warning)
|
||||||
|
self._evt_exit.wait(1)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
self.so.listen(1)
|
||||||
|
|
||||||
|
self.rpi = None
|
||||||
|
while not self._evt_exit.is_set():
|
||||||
|
|
||||||
|
# Verbindung annehmen
|
||||||
|
proginit.logger.info("starte accept")
|
||||||
|
try:
|
||||||
|
self.rpi, addr = self.so.accept()
|
||||||
|
except:
|
||||||
|
proginit.logger.exception("after accept")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Prozessabbild öffnen
|
||||||
|
fh_proc = open(procimg, "r+b", 0)
|
||||||
|
|
||||||
|
# Erste Meldung erhalten
|
||||||
|
meldung = self.rpi.recv(12)
|
||||||
|
|
||||||
|
comtime = 0
|
||||||
|
while meldung[:4] in msgcli:
|
||||||
|
ot = default_timer()
|
||||||
|
|
||||||
|
# Meldung zerlegen
|
||||||
|
command = meldung[:4]
|
||||||
|
try:
|
||||||
|
startval = int(meldung[4:-4])
|
||||||
|
except:
|
||||||
|
startval = 0
|
||||||
|
try:
|
||||||
|
lenval = int(meldung[-4:])
|
||||||
|
except:
|
||||||
|
lenval = 0
|
||||||
|
|
||||||
|
if command == b'PICT':
|
||||||
|
# piCtory Konfiguration senden
|
||||||
|
proginit.logger.debug("transfair pictory configuration")
|
||||||
|
fh_pic = open(configrsc, "rb")
|
||||||
|
while True:
|
||||||
|
data = fh_pic.read(1024)
|
||||||
|
if data:
|
||||||
|
self.rpi.send(data)
|
||||||
|
else:
|
||||||
|
fh_pic.close()
|
||||||
|
break
|
||||||
|
|
||||||
|
# Abschlussmeldung
|
||||||
|
self.rpi.send(b'PICOK')
|
||||||
|
|
||||||
|
if command == b'DATA':
|
||||||
|
# Processabbild übertragen
|
||||||
|
bcount = 0
|
||||||
|
blength = lenval
|
||||||
|
fh_proc.seek(startval)
|
||||||
|
while bcount < blength:
|
||||||
|
self.rpi.send(fh_proc.read(1024))
|
||||||
|
bcount += 1024
|
||||||
|
|
||||||
|
if command == b'SEND':
|
||||||
|
# Ausgänge empfangen
|
||||||
|
block = self.rpi.recv(lenval)
|
||||||
|
fh_proc.seek(startval)
|
||||||
|
fh_proc.write(block)
|
||||||
|
|
||||||
|
# Nächste Meldung erhalten
|
||||||
|
meldung = self.rpi.recv(12)
|
||||||
|
|
||||||
|
# Verarbeitungszeit prüfen
|
||||||
|
comtime = default_timer() - ot
|
||||||
|
if comtime > self.deadtime:
|
||||||
|
proginit.logger.error(
|
||||||
|
"runtime more than {} ms: {}".format(
|
||||||
|
int(self.deadtime * 1000), int(comtime * 1000)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
|
fh_proc.close()
|
||||||
|
self.rpi.shutdown(socket.SHUT_RDWR)
|
||||||
|
self.rpi.close()
|
||||||
|
|
||||||
|
if self.zeroonexit or comtime > self.deadtime and self.zeroonerror:
|
||||||
|
_zeroprocimg()
|
||||||
|
|
||||||
|
# Socket schließen
|
||||||
|
self.so.close()
|
||||||
|
|
||||||
|
proginit.logger.debug("leave RevPiSlave.run()")
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""Beendet Slaveausfuehrung."""
|
||||||
|
proginit.logger.debug("enter RevPiSlave.stop()")
|
||||||
|
self._evt_exit.set()
|
||||||
|
|
||||||
|
if self.rpi is not None:
|
||||||
|
self.rpi.close()
|
||||||
|
self.so.shutdown(socket.SHUT_RDWR)
|
||||||
|
|
||||||
|
proginit.logger.debug("leave RevPiSlave.stop()")
|
||||||
|
|
||||||
|
|
||||||
class RevPiPyLoad():
|
class RevPiPyLoad():
|
||||||
|
|
||||||
"""Hauptklasse, die alle Funktionen zur Verfuegung stellt.
|
"""Hauptklasse, die alle Funktionen zur Verfuegung stellt.
|
||||||
@@ -606,7 +736,15 @@ class RevPiPyLoad():
|
|||||||
def _plcthread(self):
|
def _plcthread(self):
|
||||||
"""Konfiguriert den PLC-Thread fuer die Ausfuehrung.
|
"""Konfiguriert den PLC-Thread fuer die Ausfuehrung.
|
||||||
@returns: PLC-Thread Object or None"""
|
@returns: PLC-Thread Object or None"""
|
||||||
|
th_plc = None
|
||||||
|
|
||||||
|
if self.plcslave:
|
||||||
|
# Slaveausfuehrung übergeben
|
||||||
|
th_plc = RevPiSlave()
|
||||||
|
th_plc.zeroonerror = self.zerooneerror
|
||||||
|
th_plc.zeroonexit = self.zeroonexit
|
||||||
|
|
||||||
|
else:
|
||||||
# Prüfen ob Programm existiert
|
# Prüfen ob Programm existiert
|
||||||
if not os.path.exists(os.path.join(self.plcworkdir, self.plcprog)):
|
if not os.path.exists(os.path.join(self.plcworkdir, self.plcprog)):
|
||||||
proginit.logger.error("plc file does not exists {}".format(
|
proginit.logger.error("plc file does not exists {}".format(
|
||||||
@@ -626,6 +764,7 @@ class RevPiPyLoad():
|
|||||||
th_plc.zeroonerror = self.zeroonerror
|
th_plc.zeroonerror = self.zeroonerror
|
||||||
th_plc.zeroonexit = self.zeroonexit
|
th_plc.zeroonexit = self.zeroonexit
|
||||||
proginit.logger.debug("created PLC watcher")
|
proginit.logger.debug("created PLC watcher")
|
||||||
|
|
||||||
return th_plc
|
return th_plc
|
||||||
|
|
||||||
def _sigexit(self, signum, frame):
|
def _sigexit(self, signum, frame):
|
||||||
|
|||||||
Reference in New Issue
Block a user