mirror of
https://github.com/naruxde/revpipyload.git
synced 2025-11-08 15:13:52 +01:00
first checkin
This commit is contained in:
3
MANIFEST.in
Normal file
3
MANIFEST.in
Normal file
@@ -0,0 +1,3 @@
|
||||
recursive-include data *
|
||||
recursive-include revpipyload *
|
||||
global-exclude *.pyc
|
||||
7
data/etc/default/revpipyload
Normal file
7
data/etc/default/revpipyload
Normal file
@@ -0,0 +1,7 @@
|
||||
# RevPiPyLoader
|
||||
#
|
||||
# Verbose logging add a -v or -vv
|
||||
DAEMON_ARGS="-d"
|
||||
|
||||
# Codepage of files
|
||||
export LANG=C.UTF-8
|
||||
128
data/etc/init.d/revpipyload
Executable file
128
data/etc/init.d/revpipyload
Executable file
@@ -0,0 +1,128 @@
|
||||
#! /bin/bash
|
||||
### BEGIN INIT INFO
|
||||
# Provides: revpipyload
|
||||
# Required-Start: $remote_fs $syslog $piControl
|
||||
# Required-Stop: $remote_fs $syslog $piControl
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start RevPiPyLoad to execute python plc program
|
||||
# Description: This file starts the RevPiPyLoad on system
|
||||
# boot. The Loader starts your python plc program and
|
||||
# check whether it is running.
|
||||
### END INIT INFO
|
||||
|
||||
# Author: Akira Naru Takizawa <akira@narux.de>
|
||||
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="RevPiPyLoad to run plc program"
|
||||
NAME=revpipyload
|
||||
DAEMON=/usr/local/share/revpipyload/revpipyload.py
|
||||
DAEMON_ARGS="-d"
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||
# and status_of_proc is working.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
||||
|| return 1
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
||||
$DAEMON_ARGS \
|
||||
|| return 2
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME.py
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME.py
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
reload)
|
||||
log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
do_reload
|
||||
log_end_msg $?
|
||||
;;
|
||||
restart)
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
8
data/etc/logrotate.d/revpipyload
Normal file
8
data/etc/logrotate.d/revpipyload
Normal file
@@ -0,0 +1,8 @@
|
||||
/var/log/revpipyload
|
||||
{
|
||||
rotate 6
|
||||
monthly
|
||||
compress
|
||||
missingok
|
||||
notifempty
|
||||
}
|
||||
7
data/etc/revpipyload/revpipyload.conf
Normal file
7
data/etc/revpipyload/revpipyload.conf
Normal file
@@ -0,0 +1,7 @@
|
||||
[DEFAULT]
|
||||
autoreload=1
|
||||
autostart=1
|
||||
plcprogram=test.py
|
||||
xmlrpc=1
|
||||
xmlrpcport=55123
|
||||
zeroonexit=1
|
||||
3
data/revpipyload
Executable file
3
data/revpipyload
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec "/usr/local/share/revpipyload/revpipyload.py" "$@"
|
||||
119
revpipyload.e4p
Normal file
119
revpipyload.e4p
Normal file
@@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Project SYSTEM "Project-5.1.dtd">
|
||||
<!-- eric project file for project revpipyload -->
|
||||
<!-- Saved: 2017-02-16, 07:47:17 -->
|
||||
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
|
||||
<Project version="5.1">
|
||||
<Language>en_US</Language>
|
||||
<Hash>89ddb4e70b339f832ee277085202b38acc6a125c</Hash>
|
||||
<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.1.0</Version>
|
||||
<Author>Sven Sager</Author>
|
||||
<Email>akira@narux.de</Email>
|
||||
<Eol index="-1"/>
|
||||
<Sources>
|
||||
<Source>revpipyload/__init__.py</Source>
|
||||
<Source>revpipyload/proginit.py</Source>
|
||||
<Source>setup.py</Source>
|
||||
<Source>revpipyload/revpipyload.py</Source>
|
||||
</Sources>
|
||||
<Forms/>
|
||||
<Translations/>
|
||||
<Resources/>
|
||||
<Interfaces/>
|
||||
<Others>
|
||||
<Other>data</Other>
|
||||
<Other>MANIFEST.in</Other>
|
||||
</Others>
|
||||
<Vcs>
|
||||
<VcsType>None</VcsType>
|
||||
</Vcs>
|
||||
<FiletypeAssociations>
|
||||
<FiletypeAssociation pattern="*.idl" type="INTERFACES"/>
|
||||
<FiletypeAssociation pattern="*.py" type="SOURCES"/>
|
||||
<FiletypeAssociation pattern="*.py3" type="SOURCES"/>
|
||||
<FiletypeAssociation pattern="*.pyw" type="SOURCES"/>
|
||||
<FiletypeAssociation pattern="*.pyw3" type="SOURCES"/>
|
||||
</FiletypeAssociations>
|
||||
<Checkers>
|
||||
<CheckersParams>
|
||||
<dict>
|
||||
<key>
|
||||
<string>Pep8Checker</string>
|
||||
</key>
|
||||
<value>
|
||||
<dict>
|
||||
<key>
|
||||
<string>DocstringType</string>
|
||||
</key>
|
||||
<value>
|
||||
<string>pep257</string>
|
||||
</value>
|
||||
<key>
|
||||
<string>ExcludeFiles</string>
|
||||
</key>
|
||||
<value>
|
||||
<string></string>
|
||||
</value>
|
||||
<key>
|
||||
<string>ExcludeMessages</string>
|
||||
</key>
|
||||
<value>
|
||||
<string>E123,E226,E24</string>
|
||||
</value>
|
||||
<key>
|
||||
<string>FixCodes</string>
|
||||
</key>
|
||||
<value>
|
||||
<string></string>
|
||||
</value>
|
||||
<key>
|
||||
<string>FixIssues</string>
|
||||
</key>
|
||||
<value>
|
||||
<bool>False</bool>
|
||||
</value>
|
||||
<key>
|
||||
<string>HangClosing</string>
|
||||
</key>
|
||||
<value>
|
||||
<bool>False</bool>
|
||||
</value>
|
||||
<key>
|
||||
<string>IncludeMessages</string>
|
||||
</key>
|
||||
<value>
|
||||
<string></string>
|
||||
</value>
|
||||
<key>
|
||||
<string>MaxLineLength</string>
|
||||
</key>
|
||||
<value>
|
||||
<int>80</int>
|
||||
</value>
|
||||
<key>
|
||||
<string>NoFixCodes</string>
|
||||
</key>
|
||||
<value>
|
||||
<string>E501</string>
|
||||
</value>
|
||||
<key>
|
||||
<string>RepeatMessages</string>
|
||||
</key>
|
||||
<value>
|
||||
<bool>True</bool>
|
||||
</value>
|
||||
<key>
|
||||
<string>ShowIgnored</string>
|
||||
</key>
|
||||
<value>
|
||||
<bool>False</bool>
|
||||
</value>
|
||||
</dict>
|
||||
</value>
|
||||
</dict>
|
||||
</CheckersParams>
|
||||
</Checkers>
|
||||
</Project>
|
||||
1
revpipyload/__init__.py
Normal file
1
revpipyload/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""just init file."""
|
||||
94
revpipyload/proginit.py
Normal file
94
revpipyload/proginit.py
Normal file
@@ -0,0 +1,94 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Main functions of our program."""
|
||||
import logging
|
||||
import sys
|
||||
from argparse import ArgumentParser
|
||||
from configparser import ConfigParser
|
||||
from os import fork as osfork
|
||||
from os.path import exists as ospexists
|
||||
|
||||
|
||||
class ProgInit():
|
||||
|
||||
"""Programmfunktionen fuer Parameter und Logger."""
|
||||
|
||||
def __del__(self):
|
||||
"""Clean up program."""
|
||||
# Logging beenden
|
||||
logging.shutdown()
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize general program functions."""
|
||||
|
||||
# Command arguments
|
||||
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="/etc/revpipyload/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"
|
||||
)
|
||||
self.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:
|
||||
# Prüfen ob daemon schon läuft
|
||||
if ospexists(self.pidfile):
|
||||
raise SystemError(
|
||||
"program already running as daemon. check {}".format(
|
||||
self.pidfile
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.pid = osfork()
|
||||
if self.pid > 0:
|
||||
with open(self.pidfile, "w") as f:
|
||||
f.write(str(self.pid))
|
||||
exit(0)
|
||||
|
||||
# Ausgaben umhängen in Logfile
|
||||
sys.stdout = open("/var/log/revpipyload", "a")
|
||||
sys.stderr = sys.stdout
|
||||
|
||||
# Initialize configparser globalconfig
|
||||
self.globalconffile = self.pargs.conffile
|
||||
self.globalconfig = ConfigParser()
|
||||
self.globalconfig.read(self.pargs.conffile)
|
||||
|
||||
# Program logger
|
||||
self.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)
|
||||
lhandler.setFormatter(logformat)
|
||||
self.logger.addHandler(lhandler)
|
||||
|
||||
# Loglevel auswerten
|
||||
if self.pargs.verbose is None:
|
||||
loglevel = logging.WARNING
|
||||
elif self.pargs.verbose == 1:
|
||||
loglevel = logging.INFO
|
||||
elif self.pargs.verbose > 1:
|
||||
loglevel = logging.DEBUG
|
||||
self.logger.setLevel(loglevel)
|
||||
263
revpipyload/revpipyload.py
Executable file
263
revpipyload/revpipyload.py
Executable file
@@ -0,0 +1,263 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# (c) Sven Sager, License: GPLv3
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
import proginit
|
||||
import shlex
|
||||
import signal
|
||||
import subprocess
|
||||
from concurrent import futures
|
||||
from threading import Thread, Event
|
||||
from time import sleep
|
||||
from xmlrpc.server import SimpleXMLRPCServer
|
||||
|
||||
|
||||
class RevPiPlc(Thread):
|
||||
|
||||
def __init__(self, logger, lst_proc):
|
||||
super().__init__()
|
||||
self.autoreload = False
|
||||
self._evt_exit = Event()
|
||||
self.exitcode = 0
|
||||
self._lst_proc = lst_proc
|
||||
self._logger = logger
|
||||
self._procplc = None
|
||||
self.zeroonexit = False
|
||||
|
||||
def run(self):
|
||||
# Prozess starten
|
||||
self._logger.info("start plc program")
|
||||
self._procplc = subprocess.Popen(self._lst_proc)
|
||||
|
||||
while not self._evt_exit.is_set():
|
||||
|
||||
# Auswerten
|
||||
self.exitcode = self._procplc.poll()
|
||||
|
||||
if self.exitcode is not None:
|
||||
|
||||
if self.exitcode > 0:
|
||||
self._logger.error(
|
||||
"plc program chrashed - exitcode: {}".format(
|
||||
self.exitcode
|
||||
)
|
||||
)
|
||||
if self.zeroonexit:
|
||||
f = open("/dev/piControl0", "w+b", 0)
|
||||
f.write(bytes(4096))
|
||||
self._logger.warning("set piControl0 to ZERO")
|
||||
else:
|
||||
self._logger.info("plc program did a clean exit")
|
||||
|
||||
if self.autoreload:
|
||||
# Prozess neu starten
|
||||
self._procplc = subprocess.Popen(self._lst_proc)
|
||||
if self.exitcode == 0:
|
||||
self._logger.warning(
|
||||
"restart plc program after clean exit"
|
||||
)
|
||||
else:
|
||||
self._logger.warning("restart plc program after crash")
|
||||
else:
|
||||
break
|
||||
|
||||
self._evt_exit.wait(1)
|
||||
|
||||
# Prozess beenden
|
||||
count = 0
|
||||
self._logger.info("term plc program")
|
||||
self._procplc.terminate()
|
||||
while self._procplc.poll() is None and count < 10:
|
||||
count += 1
|
||||
self._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")
|
||||
self._procplc.kill()
|
||||
self._logger.warning("killed plc program")
|
||||
|
||||
self.exitcode = self._procplc.poll()
|
||||
|
||||
def stop(self):
|
||||
self.evt_exit.set()
|
||||
|
||||
|
||||
class RevPiPyLoad(proginit.ProgInit):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._exit = True
|
||||
self.evt_loadconfig = Event()
|
||||
|
||||
self.autoreload = None
|
||||
self.plc = None
|
||||
self.plcprog = None
|
||||
self.tpe = None
|
||||
self.xmlrpc = None
|
||||
self.xsrv = None
|
||||
|
||||
# Load config
|
||||
self._loadconfig()
|
||||
|
||||
# Signal events
|
||||
signal.signal(signal.SIGINT, self._sigexit)
|
||||
signal.signal(signal.SIGTERM, self._sigexit)
|
||||
signal.signal(signal.SIGHUP, self._sigloadconfig)
|
||||
|
||||
def _loadconfig(self):
|
||||
"""Load configuration file and setup modul."""
|
||||
self.evt_loadconfig.clear()
|
||||
pauseproc = False
|
||||
if not self._exit:
|
||||
self.logger.info(
|
||||
"shutdown python plc program while getting new config"
|
||||
)
|
||||
self.stop()
|
||||
pauseproc = True
|
||||
|
||||
# Konfigurationsdatei laden
|
||||
self.logger.info(
|
||||
"loading config file: {}".format(self.globalconffile)
|
||||
)
|
||||
self.globalconfig.read(self.globalconffile)
|
||||
|
||||
# Konfiguration verarbeiten
|
||||
self.autoreload = int(self.globalconfig["DEFAULT"].get("autoreload", 1))
|
||||
self.autostart = int(self.globalconfig["DEFAULT"].get("autostart", 0))
|
||||
self.plcprog = self.globalconfig["DEFAULT"].get("plcprogram", None)
|
||||
self.xmlrpc = int(self.globalconfig["DEFAULT"].get("xmlrpc", 1))
|
||||
self.zeroonexit = int(self.globalconfig["DEFAULT"].get("zeroonexit", 1))
|
||||
|
||||
# PLC Thread konfigurieren
|
||||
self.logger.debug("create PLC watcher")
|
||||
self.plc = RevPiPlc(
|
||||
self.logger, shlex.split("/usr/bin/env python3 " + self.plcprog)
|
||||
)
|
||||
self.plc.autoreload = self.autoreload
|
||||
self.plc.zeroonexit = self.zeroonexit
|
||||
self.logger.debug("created PLC watcher")
|
||||
|
||||
# XMLRPC-Server Instantiieren und konfigurieren
|
||||
if self.xmlrpc:
|
||||
self.logger.debug("create xmlrpc server")
|
||||
self.xsrv = SimpleXMLRPCServer(
|
||||
(
|
||||
"",
|
||||
int(self.globalconfig["DEFAULT"].get("xmlrpcport", 55123))
|
||||
),
|
||||
logRequests=False,
|
||||
allow_none=True
|
||||
)
|
||||
self.xsrv.register_introspection_functions()
|
||||
|
||||
self.xsrv.register_function(self.xml_plcexitcode, "plcexitcode")
|
||||
self.xsrv.register_function(self.xml_plcrestart, "plcrestart")
|
||||
self.xsrv.register_function(self.xml_plcrunning, "plcrunning")
|
||||
self.xsrv.register_function(self.xml_plcstart, "plcstart")
|
||||
self.xsrv.register_function(self.xml_plcstop, "plcstop")
|
||||
self.xsrv.register_function(self.xml_reload, "reload")
|
||||
self.logger.debug("created xmlrpc server")
|
||||
|
||||
if pauseproc:
|
||||
self.logger.info(
|
||||
"start python plc program after getting new config"
|
||||
)
|
||||
self.start()
|
||||
|
||||
def _sigexit(self, signum, frame):
|
||||
"""Signal handler to clean an exit program."""
|
||||
self.logger.info("got exit signal")
|
||||
self.stop()
|
||||
|
||||
def _sigloadconfig(self, signum, frame):
|
||||
self.logger.info("got reload config signal")
|
||||
self.evt_loadconfig.set()
|
||||
|
||||
def start(self):
|
||||
"""Start python program and watching it."""
|
||||
self.logger.info("starting revpipyload")
|
||||
self._exit = False
|
||||
|
||||
if self.xmlrpc:
|
||||
self.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))
|
||||
self.plc.start()
|
||||
|
||||
while not self._exit \
|
||||
and not self.evt_loadconfig.is_set() \
|
||||
and self.plc.is_alive():
|
||||
self.evt_loadconfig.wait(1)
|
||||
|
||||
if not self._exit:
|
||||
self.logger.info("exit python plc program to reload config")
|
||||
self._loadconfig()
|
||||
|
||||
def stop(self):
|
||||
"""Stop python program."""
|
||||
self.logger.info("stopping revpipyload")
|
||||
self._exit = True
|
||||
|
||||
self.logger.info("stopping plc program {}".format(self.plcprog))
|
||||
self.plc.stop()
|
||||
self.plc.join()
|
||||
|
||||
if self.xmlrpc:
|
||||
self.logger.info("shutting down xmlrpc-server")
|
||||
self.xsrv.shutdown()
|
||||
self.tpe.shutdown()
|
||||
self.xsrv.server_close()
|
||||
|
||||
def xml_plcexitcode(self):
|
||||
self.logger.debug("xmlrpc get plcexitcode")
|
||||
return -1 if self.plc.is_alive() else self.plc.exitcode
|
||||
|
||||
def xml_plcrestart(self):
|
||||
self.logger.debug("xmlrpc get plcrestart")
|
||||
self.plc.stop()
|
||||
self.plc.join()
|
||||
exitcode = self.plc.exitcode
|
||||
self.plc = RevPiPlc(
|
||||
self.logger, shlex.split("/usr/bin/env python3 " + self.plcprog)
|
||||
)
|
||||
self.plc.autoreload = self.autoreload
|
||||
self.plc.zeroonexit = self.zeroonexit
|
||||
self.plc.start()
|
||||
return (exitcode, self.plc.exitcode)
|
||||
|
||||
def xml_plcrunning(self):
|
||||
self.logger.debug("xmlrpc get plcrunning")
|
||||
return self.plc.is_alive()
|
||||
|
||||
def xml_plcstart(self):
|
||||
if self.plc.is_alive():
|
||||
return -1
|
||||
else:
|
||||
self.plc = RevPiPlc(
|
||||
self.logger, shlex.split("/usr/bin/env python3 " + self.plcprog)
|
||||
)
|
||||
self.plc.autoreload = self.autoreload
|
||||
self.plc.zeroonexit = self.zeroonexit
|
||||
self.plc.start()
|
||||
return self.plc.exitcode
|
||||
|
||||
def xml_plcstop(self):
|
||||
self.logger.debug("xmlrpc get plcstop")
|
||||
self.plc.stop()
|
||||
self.plc.join()
|
||||
return self.plc.exitcode
|
||||
|
||||
def xml_reload(self):
|
||||
self.logger.info("xmlrpc reload configuration")
|
||||
self.evt_loadconfig.set()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = RevPiPyLoad()
|
||||
root.start()
|
||||
56
setup.py
Normal file
56
setup.py
Normal file
@@ -0,0 +1,56 @@
|
||||
#! /usr/bin/env python3
|
||||
#
|
||||
# (c) Sven Sager, License: LGPLv3
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Setupscript fuer RevPiPyLoad."""
|
||||
import distutils.command.install_egg_info
|
||||
from distutils.core import setup
|
||||
from glob import glob
|
||||
|
||||
|
||||
class MyEggInfo(distutils.command.install_egg_info.install_egg_info):
|
||||
|
||||
u"""Disable egg_info installation, seems pointless for a non-library."""
|
||||
|
||||
def run(self):
|
||||
u"""just pass egg_info."""
|
||||
pass
|
||||
|
||||
|
||||
setup(
|
||||
author="Sven Sager",
|
||||
author_email="akira@narux.de",
|
||||
url="https://revpimodio.org",
|
||||
maintainer="Sven Sager",
|
||||
maintainer_email="akira@revpimodio.org",
|
||||
|
||||
license="LGPLv3",
|
||||
name="revpipyload",
|
||||
version="0.1.0",
|
||||
|
||||
scripts=["data/revpipyload"],
|
||||
|
||||
data_files=[
|
||||
("/etc/default", ["data/etc/default/revpipyload"]),
|
||||
("/etc/init.d", ["data/etc/init.d/revpipyload"]),
|
||||
("/etc/logrotate.d", ["data/etc/logrotate.d/revpipyload"]),
|
||||
("/etc/revpipyload", ["data/etc/revpipyload/revpipyload.conf"]),
|
||||
("share/revpipyload", glob("revpipyload/*.*")),
|
||||
],
|
||||
|
||||
description="PLC Loader für Python-Projekte auf den RevolutionPi",
|
||||
long_description=""
|
||||
"Dieses Programm startet beim Systemstart ein angegebenes Python PLC\n"
|
||||
"Programm. Es überwacht das Programm und startet es im Fehlerfall neu.\n"
|
||||
"Bei Abstruz kann das gesamte /dev/piControl0 auf 0x00 gesettz werden.\n"
|
||||
"Außerdem stellt es einen XML-RPC Server bereit, über den die Software\n"
|
||||
"auf den RevPi geladen werden kann. Das Prozessabbild kann über ein Tool\n"
|
||||
"zur Laufzeit überwacht werden.",
|
||||
|
||||
classifiers=[
|
||||
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
|
||||
"Operating System :: POSIX :: Linux",
|
||||
],
|
||||
cmdclass={"install_egg_info": MyEggInfo},
|
||||
)
|
||||
Reference in New Issue
Block a user