Reorder package to src-layout.

Move package to src directory and update project base files for build
process.
This commit is contained in:
2023-01-19 13:20:26 +01:00
parent 36c30ae6d6
commit 1057e6daa4
16 changed files with 237 additions and 168 deletions

7
.idea/revpimodio2.iml generated
View File

@@ -1,10 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4"> <module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="Python 3.9" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.9" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
<component name="PackageRequirementsSettings">
<option name="versionSpecifier" value="Greater or equal (&gt;=x.y.z)" />
</component>
<component name="TestRunnerService"> <component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" /> <option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component> </component>

View File

@@ -1,4 +1,5 @@
global-exclude test/* recursive-include src/revpimodio *.py
global-exclude *.pyc
include LICENSE.txt include LICENSE.txt
include MANIFEST.in
include README.md include README.md
include setup.py

43
Makefile Normal file
View File

@@ -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

2
requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
setuptools>=65.6.3
wheel

View File

@@ -1,40 +1,43 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Setupscript fuer python3-revpimodio.""" """Setupscript for revpimodio."""
__author__ = "Sven Sager" __author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2020 Sven Sager" __copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "LGPLv3" __license__ = "LGPLv3"
from distutils.core import setup from setuptools import setup, find_namespace_packages
setup( 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="Sven Sager",
author_email="akira@narux.de", author_email="akira@narux.de",
url="https://revpimodio.org/",
download_url="https://revpimodio.org/quellen/",
maintainer="Sven Sager", maintainer="Sven Sager",
maintainer_email="akira@revpimodio.org", 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", description="Python3 programming for RevolutionPi of Kunbus GmbH",
long_description="" long_description="Das Modul stellt alle Devices und IOs aus der piCtory Konfiguration \n"
"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"
"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"
"Werte über deren vergebenen Namen. Lese- und Schreibaktionen mit dem \n" "Prozessabbild werden von dem Modul selbst verwaltet, ohne dass sich \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"
"der Programmierer um Offsets und Adressen kümmern muss. Für die \n" "Gatewaymodule wie ModbusTCP oder Profinet sind eigene 'Inputs' und \n"
"Gatewaymodule wie ModbusTCP oder Profinet sind eigene 'Inputs' und \n" "'Outputs' über einen bestimmten Adressbereich definierbar. Auf \n"
"'Outputs' über einen bestimmten Adressbereich definierbar. Auf \n" "diese IOs kann mit Python3 über den Namen direkt auf die Werte \n"
"diese IOs kann mit Python3 über den Namen direkt auf die Werte \n" "zugegriffen werden.",
"zugegriffen werden.", keywords=["revpi", "revolution pi", "revpimodio", "plc", "automation"],
classifiers=[ classifiers=[
"Development Status :: 5 - Production/Stable", "Development Status :: 5 - Production/Stable",
"Environment :: Console", "Environment :: Console",

View File

@@ -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 <akira@revpimodio.org>"
__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

View File

@@ -1,28 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """Internal functions and values for this package."""
Stellt alle Klassen fuer den RevolutionPi zur Verfuegung. __author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2023 Sven Sager"
Webpage: https://revpimodio.org/ __license__ = "GPLv3"
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 <akira@revpimodio.org>"
__copyright__ = "Copyright (C) 2020 Sven Sager"
__license__ = "LGPLv3"
__name__ = "revpimodio2"
__version__ = "2.6.0rc1"
# Global package values # Global package values
OFF = 0 OFF = 0
@@ -37,12 +17,6 @@ MEM = 302
PROCESS_IMAGE_SIZE = 4096 PROCESS_IMAGE_SIZE = 4096
class DeviceNotFoundError(Exception):
"""Fehler wenn ein Device nicht gefunden wird."""
pass
def acheck(check_type, **kwargs) -> None: def acheck(check_type, **kwargs) -> None:
""" """
Check type of given arguments. Check type of given arguments.
@@ -93,10 +67,3 @@ def consttostr(value) -> str:
return "MEM" return "MEM"
else: else:
return "" 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

View File

@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Bildet die App Sektion von piCtory ab.""" """Bildet die App Sektion von piCtory ab."""
from time import strptime
__author__ = "Sven Sager" __author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2020 Sven Sager" __copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "LGPLv3" __license__ = "LGPLv3"
from time import strptime
class App(object): class App(object):
"""Bildet die App Sektion der config.rsc ab.""" """Bildet die App Sektion der config.rsc ab."""

View File

@@ -1,13 +1,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Modul fuer die Verwaltung der Devices.""" """Modul fuer die Verwaltung der Devices."""
__author__ = "Sven Sager" __author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2021 Sven Sager" __copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "LGPLv3" __license__ = "LGPLv3"
import warnings import warnings
from threading import Event, Lock, Thread from threading import Event, Lock, Thread
from ._internal import INP, OUT, MEM, PROCESS_IMAGE_SIZE
from .helper import ProcimgWriter from .helper import ProcimgWriter
from .io import IOBase, IntIO, IntIOCounter, IntIOReplaceable, MemIO
from .pictory import ProductType from .pictory import ProductType
@@ -127,13 +129,13 @@ class Device(object):
""" """
__slots__ = "__my_io_list", "_ba_devdata", "_ba_datacp", \ __slots__ = "__my_io_list", "_ba_devdata", "_ba_datacp", \
"_dict_events", "_filelock", "_modio", "_name", \ "_dict_events", "_filelock", "_modio", "_name", \
"_offset", "_position", "_producttype", "_selfupdate", \ "_offset", "_position", "_producttype", "_selfupdate", \
"_slc_devoff", "_slc_inp", "_slc_inpoff", "_slc_mem", \ "_slc_devoff", "_slc_inp", "_slc_inpoff", "_slc_mem", \
"_slc_memoff", "_slc_out", "_slc_outoff", "_shared_procimg", \ "_slc_memoff", "_slc_out", "_slc_outoff", "_shared_procimg", \
"_shared_write", \ "_shared_write", \
"bmk", "catalognr", "comment", "extend", \ "bmk", "catalognr", "comment", "extend", \
"guid", "id", "inpvariant", "outvariant", "type" "guid", "id", "inpvariant", "outvariant", "type"
def __init__(self, parentmodio, dict_device, simulator=False): def __init__(self, parentmodio, dict_device, simulator=False):
""" """
@@ -244,7 +246,7 @@ class Device(object):
return False return False
else: else:
return key in self._modio.io \ 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): def __getitem__(self, key):
""" """
@@ -574,9 +576,9 @@ class Core(Base):
""" """
__slots__ = "_slc_cycle", "_slc_errorcnt", "_slc_statusbyte", \ __slots__ = "_slc_cycle", "_slc_errorcnt", "_slc_statusbyte", \
"_slc_temperature", "_slc_errorlimit1", "_slc_errorlimit2", \ "_slc_temperature", "_slc_errorlimit1", "_slc_errorlimit2", \
"_slc_frequency", "_slc_led", "a1green", "a1red", \ "_slc_frequency", "_slc_led", "a1green", "a1red", \
"a2green", "a2red", "wd" "a2green", "a2red", "wd"
def __setattr__(self, key, value): def __setattr__(self, key, value):
"""Verhindert Ueberschreibung der LEDs.""" """Verhindert Ueberschreibung der LEDs."""
@@ -899,7 +901,7 @@ class Connect(Core):
""" """
__slots__ = "__evt_wdtoggle", "__th_wdtoggle", "a3green", "a3red", \ __slots__ = "__evt_wdtoggle", "__th_wdtoggle", "a3green", "a3red", \
"x2in", "x2out" "x2in", "x2out"
def __setattr__(self, key, value): def __setattr__(self, key, value):
"""Verhindert Ueberschreibung der speziellen IOs.""" """Verhindert Ueberschreibung der speziellen IOs."""
@@ -1039,7 +1041,7 @@ class Compact(Base):
""" """
__slots__ = "_slc_temperature", "_slc_frequency", "_slc_led", \ __slots__ = "_slc_temperature", "_slc_frequency", "_slc_led", \
"a1green", "a1red", "a2green", "a2red", "wd" "a1green", "a1red", "a2green", "a2red", "wd"
def __setattr__(self, key, value): def __setattr__(self, key, value):
"""Verhindert Ueberschreibung der LEDs.""" """Verhindert Ueberschreibung der LEDs."""
@@ -1177,10 +1179,10 @@ class Flat(Base):
""" """
__slots__ = "_slc_temperature", "_slc_frequency", "_slc_led", \ __slots__ = "_slc_temperature", "_slc_frequency", "_slc_led", \
"_slc_switch", "_slc_dout", \ "_slc_switch", "_slc_dout", \
"a1green", "a1red", "a2green", "a2red", \ "a1green", "a1red", "a2green", "a2red", \
"a3green", "a3red", "a4green", "a4red", \ "a3green", "a3red", "a4green", "a4red", \
"a5green", "a5red", "relais", "switch", "wd" "a5green", "a5red", "relais", "switch", "wd"
def __setattr__(self, key, value): def __setattr__(self, key, value):
"""Verhindert Ueberschreibung der LEDs.""" """Verhindert Ueberschreibung der LEDs."""
@@ -1538,8 +1540,3 @@ class Virtual(Gateway):
self._filelock.release() self._filelock.release()
return workokay return workokay
# Nachträglicher Import
from .io import IOBase, IntIO, IntIOCounter, IntIOReplaceable, MemIO
from revpimodio2 import INP, OUT, MEM, PROCESS_IMAGE_SIZE

13
src/revpimodio2/errors.py Normal file
View File

@@ -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

View File

@@ -1,5 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""RevPiModIO Helperklassen und Tools.""" """RevPiModIO Helperklassen und Tools."""
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "LGPLv3"
import queue import queue
import warnings import warnings
from math import ceil from math import ceil
@@ -7,12 +11,8 @@ from threading import Event, Lock, Thread
from time import sleep from time import sleep
from timeit import default_timer from timeit import default_timer
from revpimodio2 import BOTH, FALLING, RISING from ._internal import RISING, FALLING, BOTH
from revpimodio2.io import IOBase from .io import IOBase
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2020 Sven Sager"
__license__ = "LGPLv3"
class EventCallback(Thread): class EventCallback(Thread):
@@ -88,11 +88,11 @@ class Cycletools:
""" """
__slots__ = "__cycle", "__cycletime", "__ucycle", "__dict_ton", \ __slots__ = "__cycle", "__cycletime", "__ucycle", "__dict_ton", \
"__dict_tof", "__dict_tp", "__dict_change", \ "__dict_tof", "__dict_tp", "__dict_change", \
"_start_timer", "core", "device", \ "_start_timer", "core", "device", \
"first", "io", "last", "var", \ "first", "io", "last", "var", \
"flag1c", "flag5c", "flag10c", "flag15c", "flag20c", \ "flag1c", "flag5c", "flag10c", "flag15c", "flag20c", \
"flank5c", "flank10c", "flank15c", "flank20c" "flank5c", "flank10c", "flank15c", "flank20c"
def __init__(self, cycletime, revpi_object): def __init__(self, cycletime, revpi_object):
"""Init Cycletools class.""" """Init Cycletools class."""
@@ -208,8 +208,8 @@ class Cycletools:
else: else:
value = io.get_value() value = io.get_value()
return self.__dict_change[io] != value and ( return self.__dict_change[io] != value and (
value and edge == RISING or value and edge == RISING or
not value and edge == FALLING not value and edge == FALLING
) )
else: else:
if not isinstance(io, IOBase): if not isinstance(io, IOBase):
@@ -365,8 +365,8 @@ class ProcimgWriter(Thread):
""" """
__slots__ = "__dict_delay", "__eventth", "_eventqth", "__eventwork", \ __slots__ = "__dict_delay", "__eventth", "_eventqth", "__eventwork", \
"_eventq", "_modio", \ "_eventq", "_modio", \
"_refresh", "_work", "daemon", "lck_refresh", "newdata" "_refresh", "_work", "daemon", "lck_refresh", "newdata"
def __init__(self, parentmodio): def __init__(self, parentmodio):
"""Init ProcimgWriter class.""" """Init ProcimgWriter class."""
@@ -394,9 +394,9 @@ class ProcimgWriter(Thread):
if io_event._bitshift: if io_event._bitshift:
boolcp = dev._ba_datacp[io_event._slc_address.start] \ boolcp = dev._ba_datacp[io_event._slc_address.start] \
& io_event._bitshift & io_event._bitshift
boolor = dev._ba_devdata[io_event._slc_address.start] \ boolor = dev._ba_devdata[io_event._slc_address.start] \
& io_event._bitshift & io_event._bitshift
if boolor == boolcp: if boolor == boolcp:
continue continue

View File

@@ -1,15 +1,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""RevPiModIO Modul fuer die Verwaltung der IOs.""" """RevPiModIO Modul fuer die Verwaltung der IOs."""
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "LGPLv3"
import struct import struct
from re import match as rematch from re import match as rematch
from threading import Event from threading import Event
from revpimodio2 import BOTH, FALLING, INP, MEM, OUT, RISING, consttostr, \ from ._internal import consttostr, RISING, FALLING, BOTH, INP, OUT, \
PROCESS_IMAGE_SIZE MEM, PROCESS_IMAGE_SIZE
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2020 Sven Sager"
__license__ = "LGPLv3"
try: try:
# Funktioniert nur auf Unix # Funktioniert nur auf Unix
@@ -209,10 +209,9 @@ class IOList(object):
if io._defaultvalue is None: if io._defaultvalue is None:
# Nur bei StructIO und keiner gegebenen defaultvalue übernehmen # Nur bei StructIO und keiner gegebenen defaultvalue übernehmen
if io._bitshift: if io._bitshift:
io_byte_address = io._parentio_address - io.address
io._defaultvalue = bool( io._defaultvalue = bool(
io._parentio_defaultvalue[ io._parentio_defaultvalue[io_byte_address] & io._bitshift
io._parentio_address - io.address
] & io._bitshift
) )
else: else:
io._defaultvalue = calc_defaultvalue io._defaultvalue = calc_defaultvalue
@@ -290,11 +289,12 @@ class IOBase(object):
""" """
__slots__ = "__bit_ioctl_off", "__bit_ioctl_on", "_bitaddress", \ __slots__ = "__bit_ioctl_off", "__bit_ioctl_on", "_bitaddress", \
"_bitshift", "_bitlength", "_byteorder", "_defaultvalue", \ "_bitshift", "_bitlength", "_byteorder", "_defaultvalue", \
"_export", "_iotype", "_length", "_name", "_parentdevice", \ "_export", "_iotype", "_length", "_name", "_parentdevice", \
"_read_only_io", "_signed", "_slc_address", "bmk" "_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. Instantiierung der IOBase-Klasse.
@@ -428,7 +428,8 @@ class IOBase(object):
""" """
return self._name 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. Verwaltet reg_event und reg_timerevent.
@@ -1043,8 +1044,9 @@ class IntIOCounter(IntIO):
# Deviceposition + leer + Counter_ID # Deviceposition + leer + Counter_ID
# ID-Bits: 7|6|5|4|3|2|1|0|15|14|13|12|11|10|9|8 # ID-Bits: 7|6|5|4|3|2|1|0|15|14|13|12|11|10|9|8
self.__ioctl_arg = \ self.__ioctl_arg = \
parentdevice._position.to_bytes(1, "little") + b'\x00' + \ parentdevice._position.to_bytes(1, "little") \
(1 << counter_id).to_bytes(2, "little") + b'\x00' \
+ (1 << counter_id).to_bytes(2, "little")
""" """
IOCTL fuellt dieses struct, welches durch padding im Speicher nach IOCTL fuellt dieses struct, welches durch padding im Speicher nach
@@ -1180,7 +1182,7 @@ class StructIO(IOBase):
""" """
__slots__ = "__frm", "_parentio_address", "_parentio_defaultvalue", \ __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): def __init__(self, parentio, name: str, frm: str, **kwargs):
""" """

View File

@@ -1,5 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""RevPiModIO Hauptklasse fuer piControl0 Zugriff.""" """RevPiModIO Hauptklasse fuer piControl0 Zugriff."""
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "LGPLv3"
import warnings import warnings
from configparser import ConfigParser from configparser import ConfigParser
from json import load as jload from json import load as jload
@@ -12,12 +16,14 @@ from stat import S_ISCHR
from threading import Event, Lock, Thread from threading import Event, Lock, Thread
from timeit import default_timer from timeit import default_timer
from revpimodio2 import BOTH, DeviceNotFoundError, FALLING, RISING, acheck from . import app as appmodule
from . import device as devicemodule
__author__ = "Sven Sager" from . import helper as helpermodule
__copyright__ = "Copyright (C) 2020 Sven Sager" from . import summary as summarymodule
__license__ = "LGPLv3" from ._internal import acheck, RISING, FALLING, BOTH
from .errors import DeviceNotFoundError
from .io import IOList
from .io import StructIO
from .pictory import ProductType from .pictory import ProductType
@@ -33,14 +39,16 @@ class RevPiModIO(object):
Device Positionen oder Device Namen. Device Positionen oder Device Namen.
""" """
__slots__ = "__cleanupfunc", "_autorefresh", "_buffedwrite", "_exit_level", \ __slots__ = "__cleanupfunc", \
"_configrsc", "_shared_procimg", "_exit", "_imgwriter", "_ioerror", \ "_autorefresh", "_buffedwrite", "_configrsc", "_debug", \
"_length", "_looprunning", "_lst_devselect", "_lst_refresh", \ "_exit", "_exit_level", "_imgwriter", "_ioerror", \
"_lst_shared", \ "_length", "_looprunning", "_lst_devselect", "_lst_refresh", \
"_maxioerrors", "_myfh", "_myfh_lck", "_monitoring", "_procimg", \ "_lst_shared", \
"_simulator", "_syncoutputs", "_th_mainloop", "_waitexit", \ "_maxioerrors", "_monitoring", "_myfh", "_myfh_lck", \
"core", "app", "device", "exitsignal", "io", "summary", "_debug", \ "_procimg", "_replace_io_file", "_run_on_pi", \
"_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__( def __init__(
self, autorefresh=False, monitoring=False, syncoutputs=True, self, autorefresh=False, monitoring=False, syncoutputs=True,
@@ -81,6 +89,7 @@ class RevPiModIO(object):
self._configrsc = configrsc self._configrsc = configrsc
self._monitoring = monitoring self._monitoring = monitoring
self._procimg = "/dev/piControl0" if procimg is None else procimg self._procimg = "/dev/piControl0" if procimg is None else procimg
self._set_device_based_cycle_time = True
self._simulator = simulator self._simulator = simulator
self._shared_procimg = shared_procimg or direct_output self._shared_procimg = shared_procimg or direct_output
self._syncoutputs = syncoutputs self._syncoutputs = syncoutputs
@@ -333,8 +342,8 @@ class RevPiModIO(object):
# ImgWriter erstellen # ImgWriter erstellen
self._imgwriter = helpermodule.ProcimgWriter(self) self._imgwriter = helpermodule.ProcimgWriter(self)
# Refreshzeit CM1 25 Hz / CM3 50 Hz if self._set_device_based_cycle_time:
if not isinstance(self, RevPiNetIO): # Refreshzeit CM1 25 Hz / CM3 50 Hz
self._imgwriter.refresh = 20 if cpu_count() > 1 else 40 self._imgwriter.refresh = 20 if cpu_count() > 1 else 40
# Aktuellen Outputstatus von procimg einlesen # Aktuellen Outputstatus von procimg einlesen
@@ -1446,13 +1455,4 @@ def run_plc(
rpi.handlesignalend() rpi.handlesignalend()
return rpi.cycleloop(func, cycletime) return rpi.cycleloop(func, cycletime)
from .netio import RevPiNetIODriver
# 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

View File

@@ -1,5 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""RevPiModIO Hauptklasse fuer Netzwerkzugriff.""" """RevPiModIO Hauptklasse fuer Netzwerkzugriff."""
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "LGPLv3"
import socket import socket
import warnings import warnings
from configparser import ConfigParser from configparser import ConfigParser
@@ -8,14 +12,10 @@ from re import compile
from struct import pack, unpack from struct import pack, unpack
from threading import Event, Lock, Thread from threading import Event, Lock, Thread
from revpimodio2 import DeviceNotFoundError
from .device import Device from .device import Device
from .errors import DeviceNotFoundError
from .modio import RevPiModIO as _RevPiModIO from .modio import RevPiModIO as _RevPiModIO
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2020 Sven Sager"
__license__ = "LGPLv3"
# Synchronisierungsbefehl # Synchronisierungsbefehl
_syssync = b'\x01\x06\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17' _syssync = b'\x01\x06\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
# Disconnectbefehl # Disconnectbefehl
@@ -57,11 +57,11 @@ class NetFH(Thread):
""" """
__slots__ = "__buff_size", "__buff_block", "__buff_recv", \ __slots__ = "__buff_size", "__buff_block", "__buff_recv", \
"__by_buff", "__check_replace_ios", "__config_changed", \ "__by_buff", "__check_replace_ios", "__config_changed", \
"__int_buff", "__dictdirty", "__flusherr", "__replace_ios_h", \ "__int_buff", "__dictdirty", "__flusherr", "__replace_ios_h", \
"__pictory_h", "__position", "__sockerr", "__sockend", \ "__pictory_h", "__position", "__sockerr", "__sockend", \
"__socklock", "__timeout", "__waitsync", "_address", \ "__socklock", "__timeout", "__waitsync", "_address", \
"_slavesock", "daemon" "_slavesock", "daemon"
def __init__(self, address: tuple, check_replace_ios: bool, timeout=500): 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 # b CM ii ii 00000000 b = 16
buff = self._direct_sr(pack( buff = self._direct_sr(pack(
"=c2sHH8xc", "=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) ) + self.__by_buff, 1)
except Exception: except Exception:
raise raise
@@ -663,9 +665,10 @@ class NetFH(Thread):
self.__int_buff += 1 self.__int_buff += 1
# Datenblock mit Position und Länge in Puffer ablegen # Datenblock mit Position und Länge in Puffer ablegen
self.__by_buff += self.__position.to_bytes(length=2, byteorder="little") + \ self.__by_buff += \
len(bytebuff).to_bytes(length=2, byteorder="little") + \ self.__position.to_bytes(length=2, byteorder="little") \
bytebuff + len(bytebuff).to_bytes(length=2, byteorder="little") \
+ bytebuff
# TODO: Bufferlänge und dann flushen? # TODO: Bufferlänge und dann flushen?
@@ -760,6 +763,7 @@ class RevPiNetIO(_RevPiModIO):
shared_procimg=shared_procimg, shared_procimg=shared_procimg,
direct_output=direct_output, direct_output=direct_output,
) )
self._set_device_based_cycle_time = False
# Netzwerkfilehandler anlegen # Netzwerkfilehandler anlegen
self._myfh = self._create_myfh() self._myfh = self._create_myfh()

View File

@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Pictory aliases for IO values.""" """Pictory aliases for IO values."""
__author__ = "Théo Rozier" __author__ = "Théo Rozier"
__copyright__ = "Copyright (C) 2020 Sven Sager" __copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "LGPLv3" __license__ = "LGPLv3"

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Bildet die Summary-Sektion von piCtory ab.""" """Bildet die Summary-Sektion von piCtory ab."""
__author__ = "Sven Sager" __author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2020 Sven Sager" __copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "LGPLv3" __license__ = "LGPLv3"