diff --git a/.idea/revpimodio2.iml b/.idea/revpimodio2.iml index 3d9fcd9..0ebe805 100644 --- a/.idea/revpimodio2.iml +++ b/.idea/revpimodio2.iml @@ -1,10 +1,15 @@ - + + + + + diff --git a/MANIFEST.in b/MANIFEST.in index 241fa68..7190361 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,5 @@ -global-exclude test/* -global-exclude *.pyc +recursive-include src/revpimodio *.py include LICENSE.txt +include MANIFEST.in include README.md +include setup.py diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c22a76c --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +SHELL := bash +MAKEFLAGS = --no-print-directory --no-builtin-rules +.DEFAULT_GOAL = all + +# Variables +PACKAGE = revpimodio2 + +# If virtualenv exists, use it. If not, use PATH to find, except python3 +SYSTEM_PYTHON = /usr/bin/python3 +PYTHON = $(or $(wildcard venv/bin/python), $(SYSTEM_PYTHON)) + +all: build + +.PHONY: all + +## Environment +venv: + $(SYSTEM_PYTHON) -m venv venv + source venv/bin/activate && \ + python3 -m pip install --upgrade pip && \ + python3 -m pip install -r requirements.txt + exit 0 + +.PHONY: venv + +## Build, install +build: + $(PYTHON) -m setup sdist + $(PYTHON) -m setup bdist_wheel + +install: + $(PYTHON) -m pip install dist/$(PACKAGE)-*.whl + +.PHONY: build install + +## Clean +clean: + rm -rf build dist src/*.egg-info *.spec + +clean-all: clean + rm -R venv + +.PHONY: clean clean-all diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d0ae7a7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +setuptools>=65.6.3 +wheel diff --git a/setup.py b/setup.py index 6059839..0edde13 100644 --- a/setup.py +++ b/setup.py @@ -1,40 +1,43 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- -"""Setupscript fuer python3-revpimodio.""" +"""Setupscript for revpimodio.""" __author__ = "Sven Sager" -__copyright__ = "Copyright (C) 2020 Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" __license__ = "LGPLv3" -from distutils.core import setup +from setuptools import setup, find_namespace_packages setup( + name="revpimodio2", + version="2.6.0rc2", + + packages=find_namespace_packages("src"), + package_dir={'': 'src'}, + include_package_data=True, + + python_requires="~=3.2", + install_requires=[], + entry_points={}, + + platforms=["all"], + + url="https://revpimodio.org/", + license="LGPLv3", author="Sven Sager", author_email="akira@narux.de", - url="https://revpimodio.org/", - download_url="https://revpimodio.org/quellen/", maintainer="Sven Sager", maintainer_email="akira@revpimodio.org", - - license="LGPLv3", - name="revpimodio2", - version="2.6.0a0", - - packages=["revpimodio2"], - python_requires="~=3.2", - keywords="revolutionpi plc automation", - description="Python3 programming for RevolutionPi of Kunbus GmbH", - long_description="" - "Das Modul stellt alle Devices und IOs aus der piCtory Konfiguration \n" - "in Python3 zur Verfügung. Es ermöglicht den direkten Zugriff auf die \n" - "Werte über deren vergebenen Namen. Lese- und Schreibaktionen mit dem \n" - "Prozessabbild werden von dem Modul selbst verwaltet, ohne dass sich \n" - "der Programmierer um Offsets und Adressen kümmern muss. Für die \n" - "Gatewaymodule wie ModbusTCP oder Profinet sind eigene 'Inputs' und \n" - "'Outputs' über einen bestimmten Adressbereich definierbar. Auf \n" - "diese IOs kann mit Python3 über den Namen direkt auf die Werte \n" - "zugegriffen werden.", - + long_description="Das Modul stellt alle Devices und IOs aus der piCtory Konfiguration \n" + "in Python3 zur Verfügung. Es ermöglicht den direkten Zugriff auf die \n" + "Werte über deren vergebenen Namen. Lese- und Schreibaktionen mit dem \n" + "Prozessabbild werden von dem Modul selbst verwaltet, ohne dass sich \n" + "der Programmierer um Offsets und Adressen kümmern muss. Für die \n" + "Gatewaymodule wie ModbusTCP oder Profinet sind eigene 'Inputs' und \n" + "'Outputs' über einen bestimmten Adressbereich definierbar. Auf \n" + "diese IOs kann mit Python3 über den Namen direkt auf die Werte \n" + "zugegriffen werden.", + keywords=["revpi", "revolution pi", "revpimodio", "plc", "automation"], classifiers=[ "Development Status :: 5 - Production/Stable", "Environment :: Console", diff --git a/src/revpimodio2/__init__.py b/src/revpimodio2/__init__.py new file mode 100644 index 0000000..6f7742c --- /dev/null +++ b/src/revpimodio2/__init__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +""" +Stellt alle Klassen fuer den RevolutionPi zur Verfuegung. + +Webpage: https://revpimodio.org/ + +Stellt Klassen fuer die einfache Verwendung des Revolution Pis der +Kunbus GmbH (https://revolution.kunbus.de/) zur Verfuegung. Alle I/Os werden +aus der piCtory Konfiguration eingelesen und mit deren Namen direkt zugreifbar +gemacht. Fuer Gateways sind eigene IOs ueber mehrere Bytes konfigurierbar +Mit den definierten Namen greift man direkt auf die gewuenschten Daten zu. +Auf alle IOs kann der Benutzer Funktionen als Events registrieren. Diese +fuehrt das Modul bei Datenaenderung aus. +""" +__all__ = [ + "IOEvent", + "RevPiModIO", "RevPiModIODriver", "RevPiModIOSelected", "run_plc", + "RevPiNetIO", "RevPiNetIODriver", "RevPiNetIOSelected", + "Cycletools", "EventCallback", + "ProductType", "AIO", "COMPACT", "DI", "DO", "DIO", "FLAT", "MIO", +] +__author__ = "Sven Sager " +__copyright__ = "Copyright (C) 2023 Sven Sager" +__license__ = "LGPLv3" +__name__ = "revpimodio2" +__version__ = "2.6.0rc2" + +from ._internal import * +from .helper import Cycletools, EventCallback +from .io import IOEvent +from .modio import RevPiModIO, RevPiModIODriver, RevPiModIOSelected, run_plc +from .netio import RevPiNetIO, RevPiNetIODriver, RevPiNetIOSelected +from .pictory import ProductType, AIO, COMPACT, DI, DO, DIO, FLAT, MIO diff --git a/revpimodio2/__init__.py b/src/revpimodio2/_internal.py similarity index 51% rename from revpimodio2/__init__.py rename to src/revpimodio2/_internal.py index 59cf2f0..b802da9 100644 --- a/revpimodio2/__init__.py +++ b/src/revpimodio2/_internal.py @@ -1,28 +1,8 @@ # -*- coding: utf-8 -*- -""" -Stellt alle Klassen fuer den RevolutionPi zur Verfuegung. - -Webpage: https://revpimodio.org/ - -Stellt Klassen fuer die einfache Verwendung des Revolution Pis der -Kunbus GmbH (https://revolution.kunbus.de/) zur Verfuegung. Alle I/Os werden -aus der piCtory Konfiguration eingelesen und mit deren Namen direkt zugreifbar -gemacht. Fuer Gateways sind eigene IOs ueber mehrere Bytes konfigurierbar -Mit den definierten Namen greift man direkt auf die gewuenschten Daten zu. -Auf alle IOs kann der Benutzer Funktionen als Events registrieren. Diese -fuehrt das Modul bei Datenaenderung aus. -""" -__all__ = [ - "RevPiModIO", "RevPiModIODriver", "RevPiModIOSelected", "run_plc", - "RevPiNetIO", "RevPiNetIODriver", "RevPiNetIOSelected", - "Cycletools", "EventCallback", - "ProductType", "AIO", "COMPACT", "DI", "DO", "DIO", "FLAT", "MIO", -] -__author__ = "Sven Sager " -__copyright__ = "Copyright (C) 2020 Sven Sager" -__license__ = "LGPLv3" -__name__ = "revpimodio2" -__version__ = "2.6.0rc1" +"""Internal functions and values for this package.""" +__author__ = "Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" +__license__ = "GPLv3" # Global package values OFF = 0 @@ -37,12 +17,6 @@ MEM = 302 PROCESS_IMAGE_SIZE = 4096 -class DeviceNotFoundError(Exception): - """Fehler wenn ein Device nicht gefunden wird.""" - - pass - - def acheck(check_type, **kwargs) -> None: """ Check type of given arguments. @@ -93,10 +67,3 @@ def consttostr(value) -> str: return "MEM" else: return "" - - -# Benötigte Klassen importieren -from .pictory import ProductType, AIO, COMPACT, DI, DO, DIO, FLAT, MIO -from .helper import Cycletools, EventCallback -from .modio import RevPiModIO, RevPiModIODriver, RevPiModIOSelected, run_plc -from .netio import RevPiNetIO, RevPiNetIODriver, RevPiNetIOSelected diff --git a/revpimodio2/app.py b/src/revpimodio2/app.py similarity index 95% rename from revpimodio2/app.py rename to src/revpimodio2/app.py index 8df82db..075bf18 100644 --- a/revpimodio2/app.py +++ b/src/revpimodio2/app.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- """Bildet die App Sektion von piCtory ab.""" -from time import strptime - __author__ = "Sven Sager" -__copyright__ = "Copyright (C) 2020 Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" __license__ = "LGPLv3" +from time import strptime + class App(object): """Bildet die App Sektion der config.rsc ab.""" diff --git a/revpimodio2/device.py b/src/revpimodio2/device.py similarity index 97% rename from revpimodio2/device.py rename to src/revpimodio2/device.py index 3c35ebe..f3a60e7 100644 --- a/revpimodio2/device.py +++ b/src/revpimodio2/device.py @@ -1,13 +1,15 @@ # -*- coding: utf-8 -*- """Modul fuer die Verwaltung der Devices.""" __author__ = "Sven Sager" -__copyright__ = "Copyright (C) 2021 Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" __license__ = "LGPLv3" import warnings from threading import Event, Lock, Thread +from ._internal import INP, OUT, MEM, PROCESS_IMAGE_SIZE from .helper import ProcimgWriter +from .io import IOBase, IntIO, IntIOCounter, IntIOReplaceable, MemIO from .pictory import ProductType @@ -127,13 +129,13 @@ class Device(object): """ __slots__ = "__my_io_list", "_ba_devdata", "_ba_datacp", \ - "_dict_events", "_filelock", "_modio", "_name", \ - "_offset", "_position", "_producttype", "_selfupdate", \ - "_slc_devoff", "_slc_inp", "_slc_inpoff", "_slc_mem", \ - "_slc_memoff", "_slc_out", "_slc_outoff", "_shared_procimg", \ - "_shared_write", \ - "bmk", "catalognr", "comment", "extend", \ - "guid", "id", "inpvariant", "outvariant", "type" + "_dict_events", "_filelock", "_modio", "_name", \ + "_offset", "_position", "_producttype", "_selfupdate", \ + "_slc_devoff", "_slc_inp", "_slc_inpoff", "_slc_mem", \ + "_slc_memoff", "_slc_out", "_slc_outoff", "_shared_procimg", \ + "_shared_write", \ + "bmk", "catalognr", "comment", "extend", \ + "guid", "id", "inpvariant", "outvariant", "type" def __init__(self, parentmodio, dict_device, simulator=False): """ @@ -244,7 +246,7 @@ class Device(object): return False else: return key in self._modio.io \ - and getattr(self._modio.io, key)._parentdevice == self + and getattr(self._modio.io, key)._parentdevice == self def __getitem__(self, key): """ @@ -574,9 +576,9 @@ class Core(Base): """ __slots__ = "_slc_cycle", "_slc_errorcnt", "_slc_statusbyte", \ - "_slc_temperature", "_slc_errorlimit1", "_slc_errorlimit2", \ - "_slc_frequency", "_slc_led", "a1green", "a1red", \ - "a2green", "a2red", "wd" + "_slc_temperature", "_slc_errorlimit1", "_slc_errorlimit2", \ + "_slc_frequency", "_slc_led", "a1green", "a1red", \ + "a2green", "a2red", "wd" def __setattr__(self, key, value): """Verhindert Ueberschreibung der LEDs.""" @@ -899,7 +901,7 @@ class Connect(Core): """ __slots__ = "__evt_wdtoggle", "__th_wdtoggle", "a3green", "a3red", \ - "x2in", "x2out" + "x2in", "x2out" def __setattr__(self, key, value): """Verhindert Ueberschreibung der speziellen IOs.""" @@ -1039,7 +1041,7 @@ class Compact(Base): """ __slots__ = "_slc_temperature", "_slc_frequency", "_slc_led", \ - "a1green", "a1red", "a2green", "a2red", "wd" + "a1green", "a1red", "a2green", "a2red", "wd" def __setattr__(self, key, value): """Verhindert Ueberschreibung der LEDs.""" @@ -1177,10 +1179,10 @@ class Flat(Base): """ __slots__ = "_slc_temperature", "_slc_frequency", "_slc_led", \ - "_slc_switch", "_slc_dout", \ - "a1green", "a1red", "a2green", "a2red", \ - "a3green", "a3red", "a4green", "a4red", \ - "a5green", "a5red", "relais", "switch", "wd" + "_slc_switch", "_slc_dout", \ + "a1green", "a1red", "a2green", "a2red", \ + "a3green", "a3red", "a4green", "a4red", \ + "a5green", "a5red", "relais", "switch", "wd" def __setattr__(self, key, value): """Verhindert Ueberschreibung der LEDs.""" @@ -1538,8 +1540,3 @@ class Virtual(Gateway): self._filelock.release() return workokay - - -# Nachträglicher Import -from .io import IOBase, IntIO, IntIOCounter, IntIOReplaceable, MemIO -from revpimodio2 import INP, OUT, MEM, PROCESS_IMAGE_SIZE diff --git a/src/revpimodio2/errors.py b/src/revpimodio2/errors.py new file mode 100644 index 0000000..d5aa7e6 --- /dev/null +++ b/src/revpimodio2/errors.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +"""Error classes of RevPiModIO.""" +__author__ = "Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" +__license__ = "LGPLv3" + + +class RevPiModIOError(Exception): + pass + + +class DeviceNotFoundError(RevPiModIOError): + pass diff --git a/revpimodio2/helper.py b/src/revpimodio2/helper.py similarity index 96% rename from revpimodio2/helper.py rename to src/revpimodio2/helper.py index a202382..341b8e4 100644 --- a/revpimodio2/helper.py +++ b/src/revpimodio2/helper.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- """RevPiModIO Helperklassen und Tools.""" +__author__ = "Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" +__license__ = "LGPLv3" + import queue import warnings from math import ceil @@ -7,12 +11,8 @@ from threading import Event, Lock, Thread from time import sleep from timeit import default_timer -from revpimodio2 import BOTH, FALLING, RISING -from revpimodio2.io import IOBase - -__author__ = "Sven Sager" -__copyright__ = "Copyright (C) 2020 Sven Sager" -__license__ = "LGPLv3" +from ._internal import RISING, FALLING, BOTH +from .io import IOBase class EventCallback(Thread): @@ -88,11 +88,11 @@ class Cycletools: """ __slots__ = "__cycle", "__cycletime", "__ucycle", "__dict_ton", \ - "__dict_tof", "__dict_tp", "__dict_change", \ - "_start_timer", "core", "device", \ - "first", "io", "last", "var", \ - "flag1c", "flag5c", "flag10c", "flag15c", "flag20c", \ - "flank5c", "flank10c", "flank15c", "flank20c" + "__dict_tof", "__dict_tp", "__dict_change", \ + "_start_timer", "core", "device", \ + "first", "io", "last", "var", \ + "flag1c", "flag5c", "flag10c", "flag15c", "flag20c", \ + "flank5c", "flank10c", "flank15c", "flank20c" def __init__(self, cycletime, revpi_object): """Init Cycletools class.""" @@ -208,8 +208,8 @@ class Cycletools: else: value = io.get_value() return self.__dict_change[io] != value and ( - value and edge == RISING or - not value and edge == FALLING + value and edge == RISING or + not value and edge == FALLING ) else: if not isinstance(io, IOBase): @@ -365,8 +365,8 @@ class ProcimgWriter(Thread): """ __slots__ = "__dict_delay", "__eventth", "_eventqth", "__eventwork", \ - "_eventq", "_modio", \ - "_refresh", "_work", "daemon", "lck_refresh", "newdata" + "_eventq", "_modio", \ + "_refresh", "_work", "daemon", "lck_refresh", "newdata" def __init__(self, parentmodio): """Init ProcimgWriter class.""" @@ -394,9 +394,9 @@ class ProcimgWriter(Thread): if io_event._bitshift: boolcp = dev._ba_datacp[io_event._slc_address.start] \ - & io_event._bitshift + & io_event._bitshift boolor = dev._ba_devdata[io_event._slc_address.start] \ - & io_event._bitshift + & io_event._bitshift if boolor == boolcp: continue diff --git a/revpimodio2/io.py b/src/revpimodio2/io.py similarity index 98% rename from revpimodio2/io.py rename to src/revpimodio2/io.py index d397b96..25b50eb 100644 --- a/revpimodio2/io.py +++ b/src/revpimodio2/io.py @@ -1,15 +1,15 @@ # -*- coding: utf-8 -*- """RevPiModIO Modul fuer die Verwaltung der IOs.""" +__author__ = "Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" +__license__ = "LGPLv3" + import struct from re import match as rematch from threading import Event -from revpimodio2 import BOTH, FALLING, INP, MEM, OUT, RISING, consttostr, \ - PROCESS_IMAGE_SIZE - -__author__ = "Sven Sager" -__copyright__ = "Copyright (C) 2020 Sven Sager" -__license__ = "LGPLv3" +from ._internal import consttostr, RISING, FALLING, BOTH, INP, OUT, \ + MEM, PROCESS_IMAGE_SIZE try: # Funktioniert nur auf Unix @@ -209,10 +209,9 @@ class IOList(object): if io._defaultvalue is None: # Nur bei StructIO und keiner gegebenen defaultvalue übernehmen if io._bitshift: + io_byte_address = io._parentio_address - io.address io._defaultvalue = bool( - io._parentio_defaultvalue[ - io._parentio_address - io.address - ] & io._bitshift + io._parentio_defaultvalue[io_byte_address] & io._bitshift ) else: io._defaultvalue = calc_defaultvalue @@ -290,11 +289,12 @@ class IOBase(object): """ __slots__ = "__bit_ioctl_off", "__bit_ioctl_on", "_bitaddress", \ - "_bitshift", "_bitlength", "_byteorder", "_defaultvalue", \ - "_export", "_iotype", "_length", "_name", "_parentdevice", \ - "_read_only_io", "_signed", "_slc_address", "bmk" + "_bitshift", "_bitlength", "_byteorder", "_defaultvalue", \ + "_export", "_iotype", "_length", "_name", "_parentdevice", \ + "_read_only_io", "_signed", "_slc_address", "bmk" - def __init__(self, parentdevice, valuelist: list, iotype: int, byteorder: str, signed: bool): + def __init__(self, parentdevice, valuelist: list, iotype: int, + byteorder: str, signed: bool): """ Instantiierung der IOBase-Klasse. @@ -428,7 +428,8 @@ class IOBase(object): """ return self._name - def __reg_xevent(self, func, delay: int, edge: int, as_thread: bool, overwrite: bool, prefire: bool) -> None: + def __reg_xevent(self, func, delay: int, edge: int, as_thread: bool, + overwrite: bool, prefire: bool) -> None: """ Verwaltet reg_event und reg_timerevent. @@ -1043,8 +1044,9 @@ class IntIOCounter(IntIO): # Deviceposition + leer + Counter_ID # ID-Bits: 7|6|5|4|3|2|1|0|15|14|13|12|11|10|9|8 self.__ioctl_arg = \ - parentdevice._position.to_bytes(1, "little") + b'\x00' + \ - (1 << counter_id).to_bytes(2, "little") + parentdevice._position.to_bytes(1, "little") \ + + b'\x00' \ + + (1 << counter_id).to_bytes(2, "little") """ IOCTL fuellt dieses struct, welches durch padding im Speicher nach @@ -1180,7 +1182,7 @@ class StructIO(IOBase): """ __slots__ = "__frm", "_parentio_address", "_parentio_defaultvalue", \ - "_parentio_length", "_parentio_name", "_wordorder" + "_parentio_length", "_parentio_name", "_wordorder" def __init__(self, parentio, name: str, frm: str, **kwargs): """ diff --git a/revpimodio2/modio.py b/src/revpimodio2/modio.py similarity index 98% rename from revpimodio2/modio.py rename to src/revpimodio2/modio.py index 475e358..4676de4 100644 --- a/revpimodio2/modio.py +++ b/src/revpimodio2/modio.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- """RevPiModIO Hauptklasse fuer piControl0 Zugriff.""" +__author__ = "Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" +__license__ = "LGPLv3" + import warnings from configparser import ConfigParser from json import load as jload @@ -12,12 +16,14 @@ from stat import S_ISCHR from threading import Event, Lock, Thread from timeit import default_timer -from revpimodio2 import BOTH, DeviceNotFoundError, FALLING, RISING, acheck - -__author__ = "Sven Sager" -__copyright__ = "Copyright (C) 2020 Sven Sager" -__license__ = "LGPLv3" - +from . import app as appmodule +from . import device as devicemodule +from . import helper as helpermodule +from . import summary as summarymodule +from ._internal import acheck, RISING, FALLING, BOTH +from .errors import DeviceNotFoundError +from .io import IOList +from .io import StructIO from .pictory import ProductType @@ -33,14 +39,16 @@ class RevPiModIO(object): Device Positionen oder Device Namen. """ - __slots__ = "__cleanupfunc", "_autorefresh", "_buffedwrite", "_exit_level", \ - "_configrsc", "_shared_procimg", "_exit", "_imgwriter", "_ioerror", \ - "_length", "_looprunning", "_lst_devselect", "_lst_refresh", \ - "_lst_shared", \ - "_maxioerrors", "_myfh", "_myfh_lck", "_monitoring", "_procimg", \ - "_simulator", "_syncoutputs", "_th_mainloop", "_waitexit", \ - "core", "app", "device", "exitsignal", "io", "summary", "_debug", \ - "_replace_io_file", "_run_on_pi" + __slots__ = "__cleanupfunc", \ + "_autorefresh", "_buffedwrite", "_configrsc", "_debug", \ + "_exit", "_exit_level", "_imgwriter", "_ioerror", \ + "_length", "_looprunning", "_lst_devselect", "_lst_refresh", \ + "_lst_shared", \ + "_maxioerrors", "_monitoring", "_myfh", "_myfh_lck", \ + "_procimg", "_replace_io_file", "_run_on_pi", \ + "_set_device_based_cycle_time", "_simulator", "_shared_procimg", \ + "_syncoutputs", "_th_mainloop", "_waitexit", \ + "app", "core", "device", "exitsignal", "io", "summary" def __init__( self, autorefresh=False, monitoring=False, syncoutputs=True, @@ -81,6 +89,7 @@ class RevPiModIO(object): self._configrsc = configrsc self._monitoring = monitoring self._procimg = "/dev/piControl0" if procimg is None else procimg + self._set_device_based_cycle_time = True self._simulator = simulator self._shared_procimg = shared_procimg or direct_output self._syncoutputs = syncoutputs @@ -333,8 +342,8 @@ class RevPiModIO(object): # ImgWriter erstellen self._imgwriter = helpermodule.ProcimgWriter(self) - # Refreshzeit CM1 25 Hz / CM3 50 Hz - if not isinstance(self, RevPiNetIO): + if self._set_device_based_cycle_time: + # Refreshzeit CM1 25 Hz / CM3 50 Hz self._imgwriter.refresh = 20 if cpu_count() > 1 else 40 # Aktuellen Outputstatus von procimg einlesen @@ -1446,13 +1455,4 @@ def run_plc( rpi.handlesignalend() return rpi.cycleloop(func, cycletime) - -# Nachträglicher Import -from . import app as appmodule -from . import device as devicemodule -from . import helper as helpermodule -from . import summary as summarymodule -from .io import IOList -from .io import StructIO - -from .netio import RevPiNetIODriver, RevPiNetIO +from .netio import RevPiNetIODriver diff --git a/revpimodio2/netio.py b/src/revpimodio2/netio.py similarity index 97% rename from revpimodio2/netio.py rename to src/revpimodio2/netio.py index 2869235..6fce7da 100644 --- a/revpimodio2/netio.py +++ b/src/revpimodio2/netio.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- """RevPiModIO Hauptklasse fuer Netzwerkzugriff.""" +__author__ = "Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" +__license__ = "LGPLv3" + import socket import warnings from configparser import ConfigParser @@ -8,14 +12,10 @@ from re import compile from struct import pack, unpack from threading import Event, Lock, Thread -from revpimodio2 import DeviceNotFoundError from .device import Device +from .errors import DeviceNotFoundError from .modio import RevPiModIO as _RevPiModIO -__author__ = "Sven Sager" -__copyright__ = "Copyright (C) 2020 Sven Sager" -__license__ = "LGPLv3" - # Synchronisierungsbefehl _syssync = b'\x01\x06\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17' # Disconnectbefehl @@ -57,11 +57,11 @@ class NetFH(Thread): """ __slots__ = "__buff_size", "__buff_block", "__buff_recv", \ - "__by_buff", "__check_replace_ios", "__config_changed", \ - "__int_buff", "__dictdirty", "__flusherr", "__replace_ios_h", \ - "__pictory_h", "__position", "__sockerr", "__sockend", \ - "__socklock", "__timeout", "__waitsync", "_address", \ - "_slavesock", "daemon" + "__by_buff", "__check_replace_ios", "__config_changed", \ + "__int_buff", "__dictdirty", "__flusherr", "__replace_ios_h", \ + "__pictory_h", "__position", "__sockerr", "__sockend", \ + "__socklock", "__timeout", "__waitsync", "_address", \ + "_slavesock", "daemon" def __init__(self, address: tuple, check_replace_ios: bool, timeout=500): """ @@ -344,7 +344,9 @@ class NetFH(Thread): # b CM ii ii 00000000 b = 16 buff = self._direct_sr(pack( "=c2sHH8xc", - HEADER_START, b'FD', self.__int_buff, len(self.__by_buff), HEADER_STOP + HEADER_START, + b'FD', self.__int_buff, len(self.__by_buff), + HEADER_STOP ) + self.__by_buff, 1) except Exception: raise @@ -663,9 +665,10 @@ class NetFH(Thread): self.__int_buff += 1 # Datenblock mit Position und Länge in Puffer ablegen - self.__by_buff += self.__position.to_bytes(length=2, byteorder="little") + \ - len(bytebuff).to_bytes(length=2, byteorder="little") + \ - bytebuff + self.__by_buff += \ + self.__position.to_bytes(length=2, byteorder="little") \ + + len(bytebuff).to_bytes(length=2, byteorder="little") \ + + bytebuff # TODO: Bufferlänge und dann flushen? @@ -760,6 +763,7 @@ class RevPiNetIO(_RevPiModIO): shared_procimg=shared_procimg, direct_output=direct_output, ) + self._set_device_based_cycle_time = False # Netzwerkfilehandler anlegen self._myfh = self._create_myfh() diff --git a/revpimodio2/pictory.py b/src/revpimodio2/pictory.py similarity index 99% rename from revpimodio2/pictory.py rename to src/revpimodio2/pictory.py index 466d0a9..13069aa 100644 --- a/revpimodio2/pictory.py +++ b/src/revpimodio2/pictory.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- """Pictory aliases for IO values.""" - __author__ = "Théo Rozier" -__copyright__ = "Copyright (C) 2020 Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" __license__ = "LGPLv3" diff --git a/revpimodio2/summary.py b/src/revpimodio2/summary.py similarity index 91% rename from revpimodio2/summary.py rename to src/revpimodio2/summary.py index a024000..da5b9a7 100644 --- a/revpimodio2/summary.py +++ b/src/revpimodio2/summary.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Bildet die Summary-Sektion von piCtory ab.""" __author__ = "Sven Sager" -__copyright__ = "Copyright (C) 2020 Sven Sager" +__copyright__ = "Copyright (C) 2023 Sven Sager" __license__ = "LGPLv3"