mirror of
https://github.com/naruxde/revpipyload.git
synced 2025-11-08 15:13:52 +01:00
globalisierung von pargs und logger
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
[DEFAULT]
|
||||
autoreload=1
|
||||
autostart=1
|
||||
plcprogram=test.py
|
||||
plcprogram=program.py
|
||||
plcslave=0
|
||||
xmlrpc=1
|
||||
xmlrpcport=55123
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Project SYSTEM "Project-5.1.dtd">
|
||||
<!-- eric project file for project revpipyload -->
|
||||
<!-- Saved: 2017-02-26, 18:35:15 -->
|
||||
<!-- Saved: 2017-03-03, 11:10:33 -->
|
||||
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
|
||||
<Project version="5.1">
|
||||
<Language>en_US</Language>
|
||||
@@ -9,7 +9,7 @@
|
||||
<ProgLanguage mixed="0">Python3</ProgLanguage>
|
||||
<ProjectType>Console</ProjectType>
|
||||
<Description>Dieser Loader wird über das Init-System geladen und führt das angegebene Pythonprogramm aus. Es ist für den RevolutionPi gedacht um automatisch das SPS-Programm zu starten.</Description>
|
||||
<Version>0.2.0</Version>
|
||||
<Version>0.2.1</Version>
|
||||
<Author>Sven Sager</Author>
|
||||
<Email>akira@narux.de</Email>
|
||||
<Eol index="-1"/>
|
||||
|
||||
@@ -8,6 +8,11 @@ from os import fork as osfork
|
||||
from os.path import exists as ospexists
|
||||
|
||||
|
||||
logapp = "revpipyloadapp.log"
|
||||
logplc = "revpipyload.log"
|
||||
logger = None
|
||||
pargs = None
|
||||
|
||||
class ProgInit():
|
||||
|
||||
"""Programmfunktionen fuer Parameter und Logger."""
|
||||
@@ -30,7 +35,7 @@ class ProgInit():
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c", "--conffile", dest="conffile",
|
||||
default="/etc/revpipyload/revpipyload.conf",
|
||||
default="revpipyload.conf",
|
||||
help="Application configuration file"
|
||||
)
|
||||
parser.add_argument(
|
||||
@@ -41,12 +46,13 @@ class ProgInit():
|
||||
"-v", "--verbose", action="count", dest="verbose",
|
||||
help="Switch on verbose logging"
|
||||
)
|
||||
self.pargs = parser.parse_args()
|
||||
global pargs
|
||||
pargs = parser.parse_args()
|
||||
|
||||
# Prüfen ob als Daemon ausgeführt werden soll
|
||||
self.pidfile = "/var/run/revpipyload.pid"
|
||||
self.pid = 0
|
||||
if self.pargs.daemon:
|
||||
if pargs.daemon:
|
||||
# Prüfen ob daemon schon läuft
|
||||
if ospexists(self.pidfile):
|
||||
raise SystemError(
|
||||
@@ -54,41 +60,48 @@ class ProgInit():
|
||||
self.pidfile
|
||||
)
|
||||
)
|
||||
else:
|
||||
|
||||
self.pid = osfork()
|
||||
if self.pid > 0:
|
||||
with open(self.pidfile, "w") as f:
|
||||
f.write(str(self.pid))
|
||||
exit(0)
|
||||
|
||||
global logapp
|
||||
global logplc
|
||||
|
||||
# Ausgaben umhängen in Logfile
|
||||
sys.stdout = open("/var/log/revpipyload", "a")
|
||||
logapp = "/var/log/revpipyloadapp"
|
||||
logplc = "/var/log/revpipyload"
|
||||
pargs.conffile = "/etc/revpipyload/revpipyload.conf"
|
||||
sys.stdout = open(logplc, "a")
|
||||
sys.stderr = sys.stdout
|
||||
|
||||
# Initialize configparser globalconfig
|
||||
self.globalconffile = self.pargs.conffile
|
||||
self.globalconffile = pargs.conffile
|
||||
self.globalconfig = ConfigParser()
|
||||
self.globalconfig.read(self.pargs.conffile)
|
||||
self.globalconfig.read(pargs.conffile)
|
||||
|
||||
# Program logger
|
||||
self.logger = logging.getLogger()
|
||||
global logger
|
||||
logger = logging.getLogger()
|
||||
logformat = logging.Formatter(
|
||||
"{asctime} [{levelname:8}] {message}",
|
||||
datefmt="%Y-%m-%d %H:%M:%S", style="{"
|
||||
)
|
||||
lhandler = logging.StreamHandler(sys.stdout)
|
||||
lhandler.setFormatter(logformat)
|
||||
self.logger.addHandler(lhandler)
|
||||
if self.pargs.logfile is not None:
|
||||
lhandler = logging.FileHandler(filename=self.pargs.logfile)
|
||||
logger.addHandler(lhandler)
|
||||
if pargs.logfile is not None:
|
||||
lhandler = logging.FileHandler(filename=pargs.logfile)
|
||||
lhandler.setFormatter(logformat)
|
||||
self.logger.addHandler(lhandler)
|
||||
logger.addHandler(lhandler)
|
||||
|
||||
# Loglevel auswerten
|
||||
if self.pargs.verbose is None:
|
||||
if pargs.verbose is None:
|
||||
loglevel = logging.WARNING
|
||||
elif self.pargs.verbose == 1:
|
||||
elif pargs.verbose == 1:
|
||||
loglevel = logging.INFO
|
||||
elif self.pargs.verbose > 1:
|
||||
elif pargs.verbose > 1:
|
||||
loglevel = logging.DEBUG
|
||||
self.logger.setLevel(loglevel)
|
||||
logger.setLevel(loglevel)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# RevPiPyLoad
|
||||
# Version: 0.2.0
|
||||
# Version: 0.2.1
|
||||
#
|
||||
# Webpage: https://revpimodio.org/
|
||||
# (c) Sven Sager, License: LGPLv3
|
||||
@@ -22,18 +22,16 @@ class LogReader():
|
||||
|
||||
def __init__(self):
|
||||
self.fhapp = None
|
||||
self.logapp = "/var/log/revpipyloadapp"
|
||||
self.posapp = 0
|
||||
self.fhplc = None
|
||||
self.logplc = "/var/log/revpipyload"
|
||||
self.posplc = 0
|
||||
|
||||
def get_applines(self):
|
||||
if not os.access(self.logapp, os.R_OK):
|
||||
if not os.access(proginit.logapp, os.R_OK):
|
||||
return None
|
||||
else:
|
||||
if self.fhapp is None or self.fhapp.closed:
|
||||
self.fhapp = open(self.logapp)
|
||||
self.fhapp = open(proginit.logapp)
|
||||
|
||||
lst_new = []
|
||||
while True:
|
||||
@@ -47,20 +45,20 @@ class LogReader():
|
||||
return lst_new
|
||||
|
||||
def get_applog(self):
|
||||
if not os.access(self.logapp, os.R_OK):
|
||||
if not os.access(proginit.logapp, os.R_OK):
|
||||
return None
|
||||
else:
|
||||
if self.fhapp is None or self.fhapp.closed:
|
||||
self.fhapp = open(self.logapp)
|
||||
self.fhapp = open(proginit.logapp)
|
||||
self.fhapp.seek(0)
|
||||
return self.fhapp.read()
|
||||
|
||||
def get_plclines(self):
|
||||
if not os.access(self.logplc, os.R_OK):
|
||||
if not os.access(proginit.logplc, os.R_OK):
|
||||
return None
|
||||
else:
|
||||
if self.fhplc is None or self.fhplc.closed:
|
||||
self.fhplc = open(self.logplc)
|
||||
self.fhplc = open(proginit.logplc)
|
||||
|
||||
lst_new = []
|
||||
while True:
|
||||
@@ -74,41 +72,40 @@ class LogReader():
|
||||
return lst_new
|
||||
|
||||
def get_plclog(self):
|
||||
if not os.access(self.logplc, os.R_OK):
|
||||
if not os.access(proginit.logplc, os.R_OK):
|
||||
return None
|
||||
else:
|
||||
if self.fhplc is None or self.fhplc.closed:
|
||||
self.fhplc = open(self.logplc)
|
||||
self.fhplc = open(proginit.logplc)
|
||||
self.fhplc.seek(0)
|
||||
return self.fhplc.read()
|
||||
|
||||
|
||||
class RevPiPlc(Thread):
|
||||
|
||||
def __init__(self, pargs, logger, program):
|
||||
def __init__(self, program):
|
||||
super().__init__()
|
||||
self.autoreload = False
|
||||
self._evt_exit = Event()
|
||||
self.exitcode = 0
|
||||
self._lst_proc = shlex.split("/usr/bin/env python3 -u " + program)
|
||||
self._logger = logger
|
||||
self._pargs = pargs
|
||||
self._procplc = None
|
||||
self.zeroonexit = False
|
||||
|
||||
def run(self):
|
||||
# Prozess starten
|
||||
self._logger.info("start plc program")
|
||||
proginit.logger.info("start plc program")
|
||||
fh = None
|
||||
if self._pargs.daemon:
|
||||
if os.access("/var/log", os.R_OK | os.W_OK):
|
||||
fh = "/var/log/revpipyloadapp"
|
||||
elif self._pargs.logfile is not None:
|
||||
fh = self._pargs.logfile
|
||||
if proginit.pargs.daemon:
|
||||
if os.access(os.path.dirname(proginit.logapp), os.R_OK | os.W_OK):
|
||||
fh = proginit.logapp
|
||||
elif proginit.pargs.logfile is not None:
|
||||
fh = proginit.pargs.logfile
|
||||
|
||||
if fh is not None:
|
||||
fh = open(fh, "a")
|
||||
fh.write("started {}\n".format(asctime()))
|
||||
fh.write("-" * 40)
|
||||
fh.write("\nplc app started: {}\n".format(asctime()))
|
||||
fh.flush()
|
||||
|
||||
# Prozess erstellen
|
||||
@@ -125,21 +122,21 @@ class RevPiPlc(Thread):
|
||||
|
||||
if self.exitcode > 0:
|
||||
# PLC Python Programm abgestürzt
|
||||
self._logger.error(
|
||||
proginit.logger.error(
|
||||
"plc program chrashed - exitcode: {}".format(
|
||||
self.exitcode
|
||||
)
|
||||
)
|
||||
|
||||
if self.zeroonexit:
|
||||
if self.zeroonexit and os.exists("/dev/piControl0"):
|
||||
# piControl0 auf NULL setzen
|
||||
f = open("/dev/piControl0", "w+b", 0)
|
||||
f.write(bytes(4096))
|
||||
self._logger.warning("set piControl0 to ZERO")
|
||||
proginit.logger.warning("set piControl0 to ZERO")
|
||||
|
||||
else:
|
||||
# PLC Python Programm sauber beendet
|
||||
self._logger.info("plc program did a clean exit")
|
||||
proginit.logger.info("plc program did a clean exit")
|
||||
|
||||
if not self._evt_exit.is_set() and self.autoreload:
|
||||
# Prozess neu starten
|
||||
@@ -148,11 +145,11 @@ class RevPiPlc(Thread):
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
if self.exitcode == 0:
|
||||
self._logger.warning(
|
||||
proginit.logger.warning(
|
||||
"restart plc program after clean exit"
|
||||
)
|
||||
else:
|
||||
self._logger.warning("restart plc program after crash")
|
||||
proginit.logger.warning("restart plc program after crash")
|
||||
else:
|
||||
break
|
||||
|
||||
@@ -160,18 +157,18 @@ class RevPiPlc(Thread):
|
||||
|
||||
# Prozess beenden
|
||||
count = 0
|
||||
self._logger.info("term plc program")
|
||||
proginit.logger.info("term plc program")
|
||||
self._procplc.terminate()
|
||||
while self._procplc.poll() is None and count < 10:
|
||||
count += 1
|
||||
self._logger.debug(
|
||||
proginit.logger.debug(
|
||||
"wait term plc program {} seconds".format(count * 0.5)
|
||||
)
|
||||
sleep(0.5)
|
||||
if self._procplc.poll() is None:
|
||||
self._logger.warning("can not term plc program")
|
||||
proginit.logger.warning("can not term plc program")
|
||||
self._procplc.kill()
|
||||
self._logger.warning("killed plc program")
|
||||
proginit.logger.warning("killed plc program")
|
||||
|
||||
self.exitcode = self._procplc.poll()
|
||||
|
||||
@@ -208,14 +205,14 @@ class RevPiPyLoad(proginit.ProgInit):
|
||||
self.evt_loadconfig.clear()
|
||||
pauseproc = False
|
||||
if not self._exit:
|
||||
self.logger.info(
|
||||
proginit.logger.info(
|
||||
"shutdown python plc program while getting new config"
|
||||
)
|
||||
self.stop()
|
||||
pauseproc = True
|
||||
|
||||
# Konfigurationsdatei laden
|
||||
self.logger.info(
|
||||
proginit.logger.info(
|
||||
"loading config file: {}".format(self.globalconffile)
|
||||
)
|
||||
self.globalconfig.read(self.globalconffile)
|
||||
@@ -229,11 +226,11 @@ class RevPiPyLoad(proginit.ProgInit):
|
||||
self.zeroonexit = int(self.globalconfig["DEFAULT"].get("zeroonexit", 1))
|
||||
|
||||
# PLC Thread konfigurieren
|
||||
self.plc = self.plcthread()
|
||||
self.plc = self._plcthread()
|
||||
|
||||
# XMLRPC-Server Instantiieren und konfigurieren
|
||||
if self.xmlrpc:
|
||||
self.logger.debug("create xmlrpc server")
|
||||
proginit.logger.debug("create xmlrpc server")
|
||||
self.xsrv = SimpleXMLRPCServer(
|
||||
(
|
||||
"",
|
||||
@@ -255,46 +252,46 @@ class RevPiPyLoad(proginit.ProgInit):
|
||||
self.xsrv.register_function(self.xml_plcstop, "plcstop")
|
||||
self.xsrv.register_function(self.xml_plcupload, "plcupload")
|
||||
self.xsrv.register_function(self.xml_reload, "reload")
|
||||
self.logger.debug("created xmlrpc server")
|
||||
proginit.logger.debug("created xmlrpc server")
|
||||
|
||||
if pauseproc:
|
||||
self.logger.info(
|
||||
proginit.logger.info(
|
||||
"start python plc program after getting new config"
|
||||
)
|
||||
self.start()
|
||||
|
||||
def _plcthread(self):
|
||||
"""Konfiguriert den PLC-Thread fuer die Ausfuehrung.
|
||||
@returns: PLC-Thread Object"""
|
||||
proginit.logger.debug("create PLC watcher")
|
||||
th_plc = RevPiPlc(self.plcprog)
|
||||
th_plc.autoreload = self.autoreload
|
||||
th_plc.zeroonexit = self.zeroonexit
|
||||
proginit.logger.debug("created PLC watcher")
|
||||
return th_plc
|
||||
|
||||
def _sigexit(self, signum, frame):
|
||||
"""Signal handler to clean an exit program."""
|
||||
self.logger.debug("got exit signal")
|
||||
proginit.logger.debug("got exit signal")
|
||||
self.stop()
|
||||
|
||||
def _sigloadconfig(self, signum, frame):
|
||||
"""Signal handler to load configuration."""
|
||||
self.logger.debug("got reload config signal")
|
||||
proginit.logger.debug("got reload config signal")
|
||||
self.evt_loadconfig.set()
|
||||
|
||||
def plcthread(self):
|
||||
"""Konfiguriert den PLC-Thread fuer die Ausfuehrung.
|
||||
@returns: PLC-Thread Object"""
|
||||
self.logger.debug("create PLC watcher")
|
||||
th_plc = RevPiPlc(self.pargs, self.logger, self.plcprog)
|
||||
th_plc.autoreload = self.autoreload
|
||||
th_plc.zeroonexit = self.zeroonexit
|
||||
self.logger.debug("created PLC watcher")
|
||||
return th_plc
|
||||
|
||||
def start(self):
|
||||
"""Start plcload and PLC python program."""
|
||||
self.logger.info("starting revpipyload")
|
||||
proginit.logger.info("starting revpipyload")
|
||||
self._exit = False
|
||||
|
||||
if self.xmlrpc:
|
||||
self.logger.info("start xmlrpc-server")
|
||||
proginit.logger.info("start xmlrpc-server")
|
||||
self.tpe = futures.ThreadPoolExecutor(max_workers=1)
|
||||
self.tpe.submit(self.xsrv.serve_forever)
|
||||
|
||||
if self.autostart:
|
||||
self.logger.info("starting plc program {}".format(self.plcprog))
|
||||
proginit.logger.info("starting plc program {}".format(self.plcprog))
|
||||
self.plc.start()
|
||||
|
||||
while not self._exit \
|
||||
@@ -302,20 +299,20 @@ class RevPiPyLoad(proginit.ProgInit):
|
||||
self.evt_loadconfig.wait(1)
|
||||
|
||||
if not self._exit:
|
||||
self.logger.info("exit python plc program to reload config")
|
||||
proginit.logger.info("exit python plc program to reload config")
|
||||
self._loadconfig()
|
||||
|
||||
def stop(self):
|
||||
"""Stop PLC python program and plcload."""
|
||||
self.logger.info("stopping revpipyload")
|
||||
proginit.logger.info("stopping revpipyload")
|
||||
self._exit = True
|
||||
|
||||
self.logger.info("stopping plc program {}".format(self.plcprog))
|
||||
proginit.logger.info("stopping plc program {}".format(self.plcprog))
|
||||
self.plc.stop()
|
||||
self.plc.join()
|
||||
|
||||
if self.xmlrpc:
|
||||
self.logger.info("shutting down xmlrpc-server")
|
||||
proginit.logger.info("shutting down xmlrpc-server")
|
||||
self.xsrv.shutdown()
|
||||
self.tpe.shutdown()
|
||||
self.xsrv.server_close()
|
||||
@@ -324,24 +321,24 @@ class RevPiPyLoad(proginit.ProgInit):
|
||||
pass
|
||||
|
||||
def xml_plcexitcode(self):
|
||||
self.logger.debug("xmlrpc call plcexitcode")
|
||||
proginit.logger.debug("xmlrpc call plcexitcode")
|
||||
return -1 if self.plc.is_alive() else self.plc.exitcode
|
||||
|
||||
def xml_plcrunning(self):
|
||||
self.logger.debug("xmlrpc call plcrunning")
|
||||
proginit.logger.debug("xmlrpc call plcrunning")
|
||||
return self.plc.is_alive()
|
||||
|
||||
def xml_plcstart(self):
|
||||
self.logger.debug("xmlrpc call plcstart")
|
||||
proginit.logger.debug("xmlrpc call plcstart")
|
||||
if self.plc.is_alive():
|
||||
return -1
|
||||
else:
|
||||
self.plc = self.plcthread()
|
||||
self.plc = self._plcthread()
|
||||
self.plc.start()
|
||||
return self.plc.exitcode
|
||||
|
||||
def xml_plcstop(self):
|
||||
self.logger.debug("xmlrpc call plcstop")
|
||||
proginit.logger.debug("xmlrpc call plcstop")
|
||||
self.plc.stop()
|
||||
self.plc.join()
|
||||
return self.plc.exitcode
|
||||
@@ -350,7 +347,7 @@ class RevPiPyLoad(proginit.ProgInit):
|
||||
pass
|
||||
|
||||
def xml_reload(self):
|
||||
self.logger.debug("xmlrpc call reload")
|
||||
proginit.logger.debug("xmlrpc call reload")
|
||||
self.evt_loadconfig.set()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user