mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 22:03:53 +01:00
Merge tag 'unstable/2.7.2_rc1' into pkg/debian_rc
This commit is contained in:
2
.idea/vcs.xml
generated
2
.idea/vcs.xml
generated
@@ -3,8 +3,6 @@
|
|||||||
<component name="CommitMessageInspectionProfile">
|
<component name="CommitMessageInspectionProfile">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<inspection_tool class="BodyLimit" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="BodyLimit" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="CommitFormat" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="CommitNamingConvention" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="SubjectBodySeparation" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="SubjectBodySeparation" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="SubjectLimit" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="SubjectLimit" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
</profile>
|
</profile>
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -16,7 +16,7 @@ endif
|
|||||||
SYSTEM_PYTHON = python3
|
SYSTEM_PYTHON = python3
|
||||||
PYTHON = $(or $(wildcard $(VENV_PATH)/bin/python), $(SYSTEM_PYTHON))
|
PYTHON = $(or $(wildcard $(VENV_PATH)/bin/python), $(SYSTEM_PYTHON))
|
||||||
|
|
||||||
all: build docs
|
all: test build docs
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
__author__ = "Sven Sager <akira@revpimodio.org>"
|
__author__ = "Sven Sager <akira@revpimodio.org>"
|
||||||
__copyright__ = "Copyright (C) 2023 Sven Sager"
|
__copyright__ = "Copyright (C) 2023 Sven Sager"
|
||||||
__license__ = "LGPLv2"
|
__license__ = "LGPLv2"
|
||||||
__version__ = "2.7.0rc3"
|
__version__ = "2.7.2rc1"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ __license__ = "LGPLv2"
|
|||||||
OFF = 0
|
OFF = 0
|
||||||
GREEN = 1
|
GREEN = 1
|
||||||
RED = 2
|
RED = 2
|
||||||
|
BLUE = 4
|
||||||
RISING = 31
|
RISING = 31
|
||||||
FALLING = 32
|
FALLING = 32
|
||||||
BOTH = 33
|
BOTH = 33
|
||||||
@@ -53,6 +54,8 @@ def consttostr(value) -> str:
|
|||||||
return "GREEN"
|
return "GREEN"
|
||||||
elif value == 2:
|
elif value == 2:
|
||||||
return "RED"
|
return "RED"
|
||||||
|
elif value == 4:
|
||||||
|
return "BLUE"
|
||||||
elif value == 31:
|
elif value == 31:
|
||||||
return "RISING"
|
return "RISING"
|
||||||
elif value == 32:
|
elif value == 32:
|
||||||
|
|||||||
@@ -1113,6 +1113,19 @@ class Connect4(ModularBase):
|
|||||||
raise AttributeError("direct assignment is not supported - use .value Attribute")
|
raise AttributeError("direct assignment is not supported - use .value Attribute")
|
||||||
super(Connect4, self).__setattr__(key, value)
|
super(Connect4, self).__setattr__(key, value)
|
||||||
|
|
||||||
|
def __led_calculator(self, led_value: int) -> int:
|
||||||
|
"""
|
||||||
|
Calculate the LED value of Connect 4.
|
||||||
|
|
||||||
|
Only the Connect 4 has swapped LED colors red and green. We have to recalculate that
|
||||||
|
values to match our values for GREEN, RED and BLUE.
|
||||||
|
"""
|
||||||
|
led_calculated = led_value & 0b001
|
||||||
|
led_calculated <<= 1
|
||||||
|
led_calculated += bool(led_value & 0b010)
|
||||||
|
led_calculated += led_value & 0b100
|
||||||
|
return led_calculated
|
||||||
|
|
||||||
def _devconfigure(self) -> None:
|
def _devconfigure(self) -> None:
|
||||||
"""Connect4-Klasse vorbereiten."""
|
"""Connect4-Klasse vorbereiten."""
|
||||||
super()._devconfigure()
|
super()._devconfigure()
|
||||||
@@ -1298,7 +1311,7 @@ class Connect4(ModularBase):
|
|||||||
)
|
)
|
||||||
self.x2out = IOBase(
|
self.x2out = IOBase(
|
||||||
self,
|
self,
|
||||||
["core.x2out", 0, 1, self._slc_led.start, exp_x2out, None, "Connect_X2_OUT", "6"],
|
["core.x2out", 0, 1, self._slc_output.start, exp_x2out, None, "Connect_X2_OUT", "0"],
|
||||||
OUT,
|
OUT,
|
||||||
"little",
|
"little",
|
||||||
False,
|
False,
|
||||||
@@ -1308,52 +1321,52 @@ class Connect4(ModularBase):
|
|||||||
"""
|
"""
|
||||||
Gibt den Zustand der LED A1 vom Connect zurueck.
|
Gibt den Zustand der LED A1 vom Connect zurueck.
|
||||||
|
|
||||||
:return: 0=aus, 1=rot, 2=gruen, 4=blau
|
:return: 0=aus, 1=gruen, 2=root, 4=blau
|
||||||
"""
|
"""
|
||||||
return self._ba_devdata[self._slc_led.start] & 0b00000111
|
return self.__led_calculator(self._ba_devdata[self._slc_led.start] & 0b00000111)
|
||||||
|
|
||||||
def _get_leda2(self) -> int:
|
def _get_leda2(self) -> int:
|
||||||
"""
|
"""
|
||||||
Gibt den Zustand der LED A2 vom Core zurueck.
|
Gibt den Zustand der LED A2 vom Core zurueck.
|
||||||
|
|
||||||
:return: 0=aus, 1=rot, 2=gruen, 4=blau
|
:return: 0=aus, 1=gruen, 2=root, 4=blau
|
||||||
"""
|
"""
|
||||||
return (self._ba_devdata[self._slc_led.start] & 0b00111000) >> 3
|
return self.__led_calculator((self._ba_devdata[self._slc_led.start] & 0b00111000) >> 3)
|
||||||
|
|
||||||
def _get_leda3(self) -> int:
|
def _get_leda3(self) -> int:
|
||||||
"""
|
"""
|
||||||
Gibt den Zustand der LED A3 vom Core zurueck.
|
Gibt den Zustand der LED A3 vom Core zurueck.
|
||||||
|
|
||||||
:return: 0=aus, 1=rot, 2=gruen, 4=blau
|
:return: 0=aus, 1=gruen, 2=root, 4=blau
|
||||||
"""
|
"""
|
||||||
word_led = self._ba_devdata[self._slc_led]
|
word_led = self._ba_devdata[self._slc_led]
|
||||||
return (unpack("<H", word_led)[0] & 0b0000000111000000) >> 6
|
return self.__led_calculator((unpack("<H", word_led)[0] & 0b0000000111000000) >> 6)
|
||||||
|
|
||||||
def _get_leda4(self) -> int:
|
def _get_leda4(self) -> int:
|
||||||
"""
|
"""
|
||||||
Gibt den Zustand der LED A4 vom Core zurueck.
|
Gibt den Zustand der LED A4 vom Core zurueck.
|
||||||
|
|
||||||
:return: 0=aus, 1=rot, 2=gruen, 4=blau
|
:return: 0=aus, 1=gruen, 2=root, 4=blau
|
||||||
"""
|
"""
|
||||||
return (self._ba_devdata[self._slc_led.start + 1] & 0b00001110) >> 1
|
return self.__led_calculator((self._ba_devdata[self._slc_led.start + 1] & 0b00001110) >> 1)
|
||||||
|
|
||||||
def _get_leda5(self) -> int:
|
def _get_leda5(self) -> int:
|
||||||
"""
|
"""
|
||||||
Gibt den Zustand der LED A5 vom Core zurueck.
|
Gibt den Zustand der LED A5 vom Core zurueck.
|
||||||
|
|
||||||
:return: 0=aus, 1=rot, 2=gruen, 4=blau
|
:return: 0=aus, 1=gruen, 2=root, 4=blau
|
||||||
"""
|
"""
|
||||||
return (self._ba_devdata[self._slc_led.start + 1] & 0b01110000) >> 4
|
return self.__led_calculator((self._ba_devdata[self._slc_led.start + 1] & 0b01110000) >> 4)
|
||||||
|
|
||||||
def _set_leda1(self, value: int) -> None:
|
def _set_leda1(self, value: int) -> None:
|
||||||
"""
|
"""
|
||||||
Setzt den Zustand der LED A1 vom Connect.
|
Setzt den Zustand der LED A1 vom Connect.
|
||||||
|
|
||||||
:param: value 0=aus, 1=rot, 2=gruen, 4=blue
|
:param: value 0=aus, 1=gruen, 2=rot, 4=blue
|
||||||
"""
|
"""
|
||||||
if 0 <= value <= 7:
|
if 0 <= value <= 7:
|
||||||
self.a1red(bool(value & 1))
|
self.a1red(bool(value & 2))
|
||||||
self.a1green(bool(value & 2))
|
self.a1green(bool(value & 1))
|
||||||
self.a1blue(bool(value & 4))
|
self.a1blue(bool(value & 4))
|
||||||
else:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 7")
|
raise ValueError("led status must be between 0 and 7")
|
||||||
@@ -1362,11 +1375,11 @@ class Connect4(ModularBase):
|
|||||||
"""
|
"""
|
||||||
Setzt den Zustand der LED A2 vom Connect.
|
Setzt den Zustand der LED A2 vom Connect.
|
||||||
|
|
||||||
:param: value 0=aus, 1=rot, 2=gruen, 4=blue
|
:param: value 0=aus, 1=gruen, 2=rot, 4=blue
|
||||||
"""
|
"""
|
||||||
if 0 <= value <= 7:
|
if 0 <= value <= 7:
|
||||||
self.a2red(bool(value & 1))
|
self.a2red(bool(value & 2))
|
||||||
self.a2green(bool(value & 2))
|
self.a2green(bool(value & 1))
|
||||||
self.a2blue(bool(value & 4))
|
self.a2blue(bool(value & 4))
|
||||||
else:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 7")
|
raise ValueError("led status must be between 0 and 7")
|
||||||
@@ -1375,11 +1388,11 @@ class Connect4(ModularBase):
|
|||||||
"""
|
"""
|
||||||
Setzt den Zustand der LED A3 vom Connect.
|
Setzt den Zustand der LED A3 vom Connect.
|
||||||
|
|
||||||
:param: value 0=aus, 1=rot, 2=gruen, 4=blue
|
:param: value 0=aus, 1=gruen, 2=rot, 4=blue
|
||||||
"""
|
"""
|
||||||
if 0 <= value <= 7:
|
if 0 <= value <= 7:
|
||||||
self.a3red(bool(value & 1))
|
self.a3red(bool(value & 2))
|
||||||
self.a3green(bool(value & 2))
|
self.a3green(bool(value & 1))
|
||||||
self.a3blue(bool(value & 4))
|
self.a3blue(bool(value & 4))
|
||||||
else:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 7")
|
raise ValueError("led status must be between 0 and 7")
|
||||||
@@ -1388,11 +1401,11 @@ class Connect4(ModularBase):
|
|||||||
"""
|
"""
|
||||||
Setzt den Zustand der LED A4 vom Connect.
|
Setzt den Zustand der LED A4 vom Connect.
|
||||||
|
|
||||||
:param: value 0=aus, 1=rot, 2=gruen, 4=blue
|
:param: value 0=aus, 1=gruen, 2=rot, 4=blue
|
||||||
"""
|
"""
|
||||||
if 0 <= value <= 7:
|
if 0 <= value <= 7:
|
||||||
self.a4red(bool(value & 1))
|
self.a4red(bool(value & 2))
|
||||||
self.a4green(bool(value & 2))
|
self.a4green(bool(value & 1))
|
||||||
self.a4blue(bool(value & 4))
|
self.a4blue(bool(value & 4))
|
||||||
else:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 7")
|
raise ValueError("led status must be between 0 and 7")
|
||||||
@@ -1401,11 +1414,11 @@ class Connect4(ModularBase):
|
|||||||
"""
|
"""
|
||||||
Setzt den Zustand der LED A5 vom Connect.
|
Setzt den Zustand der LED A5 vom Connect.
|
||||||
|
|
||||||
:param: value 0=aus, 1=rot, 2=gruen, 4=blue
|
:param: value 0=aus, 1=gruen, 2=rot, 4=blue
|
||||||
"""
|
"""
|
||||||
if 0 <= value <= 7:
|
if 0 <= value <= 7:
|
||||||
self.a5red(bool(value & 1))
|
self.a5red(bool(value & 2))
|
||||||
self.a5green(bool(value & 2))
|
self.a5green(bool(value & 1))
|
||||||
self.a5blue(bool(value & 4))
|
self.a5blue(bool(value & 4))
|
||||||
else:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 7")
|
raise ValueError("led status must be between 0 and 7")
|
||||||
|
|||||||
@@ -115,13 +115,14 @@ class IOList(object):
|
|||||||
self.__modio._imgwriter.newdata.clear()
|
self.__modio._imgwriter.newdata.clear()
|
||||||
|
|
||||||
# Write outputs on devices without autorefresh
|
# Write outputs on devices without autorefresh
|
||||||
self.__modio.writeprocimg()
|
if not self.__modio._monitoring:
|
||||||
|
self.__modio.writeprocimg()
|
||||||
|
|
||||||
if self.__modio._imgwriter.is_alive():
|
if self.__modio._imgwriter.is_alive():
|
||||||
# Wait until imgwriter has written outputs
|
# Wait until imgwriter has written outputs
|
||||||
self.__modio._imgwriter.newdata.wait(2.5)
|
self.__modio._imgwriter.newdata.wait(2.5)
|
||||||
|
|
||||||
if self.__modio._context_manager:
|
if not self.__modio._context_manager:
|
||||||
# Do not reset if ModIO is in a context manager itself, it will handle that flag
|
# Do not reset if ModIO is in a context manager itself, it will handle that flag
|
||||||
self.__modio._looprunning = False
|
self.__modio._looprunning = False
|
||||||
|
|
||||||
|
|||||||
@@ -218,7 +218,8 @@ class RevPiModIO(object):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
self.writeprocimg()
|
if not self._monitoring:
|
||||||
|
self.writeprocimg()
|
||||||
self.exit(full=True)
|
self.exit(full=True)
|
||||||
self._looprunning = False
|
self._looprunning = False
|
||||||
self._context_manager = False
|
self._context_manager = False
|
||||||
|
|||||||
44
tests/__init__.py
Normal file
44
tests/__init__.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Shared functions for tests."""
|
||||||
|
__author__ = "Sven Sager"
|
||||||
|
__copyright__ = "Copyright (C) 2024 Sven Sager"
|
||||||
|
__license__ = "GPLv2"
|
||||||
|
|
||||||
|
from os.path import dirname, join
|
||||||
|
from tempfile import NamedTemporaryFile
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
import revpimodio2
|
||||||
|
|
||||||
|
DEFAULT_PROCIMG = join(dirname(__file__), "proc.img")
|
||||||
|
RUN_ON_REVPI = False # todo: Check revpi system
|
||||||
|
|
||||||
|
|
||||||
|
class TestRevPiModIO(TestCase):
|
||||||
|
|
||||||
|
data_dir = dirname(__file__)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.fh_procimg = NamedTemporaryFile("wb+", 0, prefix="test_procimg_")
|
||||||
|
self.fh_procimg.write(b"\x00" * 4096)
|
||||||
|
self.fh_procimg.seek(0)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.fh_procimg.close()
|
||||||
|
|
||||||
|
def modio(self, **kwargs):
|
||||||
|
"""Default ModIO object with temp process image."""
|
||||||
|
if not RUN_ON_REVPI:
|
||||||
|
if "procimg" in kwargs:
|
||||||
|
# Use a copy of given prepared process image
|
||||||
|
with open(kwargs["procimg"], "rb") as fh:
|
||||||
|
self.fh_procimg.write(fh.read())
|
||||||
|
self.fh_procimg.seek(0)
|
||||||
|
|
||||||
|
# Always use the temporary process image of testing class
|
||||||
|
kwargs["procimg"] = self.fh_procimg.name
|
||||||
|
|
||||||
|
# Always use a config inside the testing folder (default config.rsc)
|
||||||
|
kwargs["configrsc"] = join(self.data_dir, kwargs.get("configrsc", "config.rsc"))
|
||||||
|
|
||||||
|
return revpimodio2.RevPiModIO(**kwargs)
|
||||||
1
tests/compact/config_compact.rsc
Normal file
1
tests/compact/config_compact.rsc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"App":{"name": "PiCtory", "version": "1.4.3","saveTS": "20200428181820","language": "en","layout": {"north":{"size":70,"initClosed":false,"initHidden":false},"south":{"size":420,"initClosed":false,"initHidden":false,"children":{"layout1":{"east":{"size":500,"initClosed":false,"initHidden":false}}}},"east":{"size":0,"initClosed":true,"initHidden":false,"children":{}},"west":{"size":200,"initClosed":false,"initHidden":false,"children":{"layout1":{}}}}},"Summary":{"inpTotal": 23,"outTotal": 6},"Devices":[{"GUID": "d22a4b56-7646-ab9b-b205-52a738abf5e0","id": "device_RevPiCompact_20171023_1_0_001","type": "BASE","productType": "104","position": "0","name": "RevPi Compact","bmk": "RevPi Compact","inpVariant": 0,"outVariant": 0,"comment": "This is a RevPiCompact Device","offset": 0,"inp": {"0": ["Core_Temperature","0","8","0",false,"0000", "",""],"1": ["Core_Frequency","0","8","1",false,"0001", "",""],"2": ["DIn_i01","0","8","2",true,"0002", "",""],"3": ["AIn_1","0","16","3",false,"0003", "",""],"4": ["AIn_2","0","16","5",false,"0004", "",""],"5": ["AIn_3","0","16","7",false,"0005", "",""],"6": ["AIn_4","0","16","9",false,"0006", "",""],"7": ["AIn_5","0","16","11",false,"0007", "",""],"8": ["AIn_6","0","16","13",false,"0008", "",""],"9": ["AIn_7","0","16","15",false,"0009", "",""],"10": ["AIn_8","0","16","17",false,"0010", "",""],"11": ["DIn_Status","0","8","19",false,"0011", "",""],"12": ["DOut_Status","0","8","20",false,"0012", "",""],"13": ["AIn_Status","0","8","21",false,"0013", "",""],"14": ["AOut_Status","0","8","22",false,"0014", "",""]},"out": {"0": ["RevPiLED","0","8","23",true,"0015", "",""],"1": ["DOut","0","8","24",false,"0016", "",""],"2": ["AOut_1","0","16","25",false,"0017", "",""],"3": ["AOut_2","0","16","27",false,"0018", "",""]},"mem": {"0": ["InputDebounce","0","8","29",false,"0019", "",""],"1": ["AInMode_1","0","8","30",false,"0020", "Select the type of input signal",""],"2": ["AInMode_2","0","8","31",false,"0021", "Select the type of input signal",""],"3": ["AInMode_3","0","8","32",false,"0022", "Select the type of input signal",""],"4": ["AInMode_4","0","8","33",false,"0023", "Select the type of input signal",""],"5": ["AInMode_5","0","8","34",false,"0024", "Select the type of input signal",""],"6": ["AInMode_6","0","8","35",false,"0025", "Select the type of input signal",""],"7": ["AInMode_7","0","8","36",false,"0026", "Select the type of input signal",""],"8": ["AInMode_8","0","8","37",false,"0027", "Select the type of input signal",""]},"extend": {}}],"Connections":[]}
|
||||||
420
tests/compact/config_compact_bits.json
Normal file
420
tests/compact/config_compact_bits.json
Normal file
@@ -0,0 +1,420 @@
|
|||||||
|
{
|
||||||
|
"App": {
|
||||||
|
"name": "PiCtory",
|
||||||
|
"version": "1.4.3",
|
||||||
|
"saveTS": "20200428181820",
|
||||||
|
"language": "en",
|
||||||
|
"layout": {
|
||||||
|
"north": {
|
||||||
|
"size": 70,
|
||||||
|
"initClosed": false,
|
||||||
|
"initHidden": false
|
||||||
|
},
|
||||||
|
"south": {
|
||||||
|
"size": 420,
|
||||||
|
"initClosed": false,
|
||||||
|
"initHidden": false,
|
||||||
|
"children": {
|
||||||
|
"layout1": {
|
||||||
|
"east": {
|
||||||
|
"size": 500,
|
||||||
|
"initClosed": false,
|
||||||
|
"initHidden": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"east": {
|
||||||
|
"size": 0,
|
||||||
|
"initClosed": true,
|
||||||
|
"initHidden": false,
|
||||||
|
"children": {}
|
||||||
|
},
|
||||||
|
"west": {
|
||||||
|
"size": 200,
|
||||||
|
"initClosed": false,
|
||||||
|
"initHidden": false,
|
||||||
|
"children": {
|
||||||
|
"layout1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Summary": {
|
||||||
|
"inpTotal": 23,
|
||||||
|
"outTotal": 6
|
||||||
|
},
|
||||||
|
"Devices": [
|
||||||
|
{
|
||||||
|
"GUID": "d22a4b56-7646-ab9b-b205-52a738abf5e0",
|
||||||
|
"id": "device_RevPiCompact_20171023_1_0_001",
|
||||||
|
"type": "BASE",
|
||||||
|
"productType": "104",
|
||||||
|
"position": "0",
|
||||||
|
"name": "RevPi Compact",
|
||||||
|
"bmk": "RevPi Compact",
|
||||||
|
"inpVariant": 0,
|
||||||
|
"outVariant": 0,
|
||||||
|
"comment": "This is a RevPiCompact Device",
|
||||||
|
"offset": 0,
|
||||||
|
"inp": {
|
||||||
|
"0": [
|
||||||
|
"Core_Temperature",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"0",
|
||||||
|
false,
|
||||||
|
"0000",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"Core_Frequency",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"1",
|
||||||
|
false,
|
||||||
|
"0001",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"2": [
|
||||||
|
"DIn_i01",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"2",
|
||||||
|
true,
|
||||||
|
"0002",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"3": [
|
||||||
|
"AIn_1",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"3",
|
||||||
|
false,
|
||||||
|
"0003",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"4": [
|
||||||
|
"AIn_2",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"5",
|
||||||
|
false,
|
||||||
|
"0004",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"5": [
|
||||||
|
"AIn_3",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"7",
|
||||||
|
false,
|
||||||
|
"0005",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"6": [
|
||||||
|
"AIn_4",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"9",
|
||||||
|
false,
|
||||||
|
"0006",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"7": [
|
||||||
|
"AIn_5",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"11",
|
||||||
|
false,
|
||||||
|
"0007",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"8": [
|
||||||
|
"AIn_6",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"13",
|
||||||
|
false,
|
||||||
|
"0008",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"9": [
|
||||||
|
"AIn_7",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"15",
|
||||||
|
false,
|
||||||
|
"0009",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"10": [
|
||||||
|
"AIn_8",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"17",
|
||||||
|
false,
|
||||||
|
"0010",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"11": [
|
||||||
|
"DIn_Status",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"19",
|
||||||
|
false,
|
||||||
|
"0011",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"12": [
|
||||||
|
"DOut_Status",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"20",
|
||||||
|
false,
|
||||||
|
"0012",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"13": [
|
||||||
|
"AIn_Status",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"21",
|
||||||
|
false,
|
||||||
|
"0013",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"14": [
|
||||||
|
"AOut_Status",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"22",
|
||||||
|
false,
|
||||||
|
"0014",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"out": {
|
||||||
|
"0": [
|
||||||
|
"a1green",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"23",
|
||||||
|
true,
|
||||||
|
"0012",
|
||||||
|
"",
|
||||||
|
"0"
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"a1red",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"23",
|
||||||
|
true,
|
||||||
|
"0013",
|
||||||
|
"",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"2": [
|
||||||
|
"a2green",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"23",
|
||||||
|
true,
|
||||||
|
"0014",
|
||||||
|
"",
|
||||||
|
"2"
|
||||||
|
],
|
||||||
|
"3": [
|
||||||
|
"a2red",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"23",
|
||||||
|
true,
|
||||||
|
"0015",
|
||||||
|
"",
|
||||||
|
"3"
|
||||||
|
],
|
||||||
|
"4": [
|
||||||
|
"a3green",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"23",
|
||||||
|
true,
|
||||||
|
"0016",
|
||||||
|
"",
|
||||||
|
"4"
|
||||||
|
],
|
||||||
|
"5": [
|
||||||
|
"a3red",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"23",
|
||||||
|
true,
|
||||||
|
"0017",
|
||||||
|
"",
|
||||||
|
"5"
|
||||||
|
],
|
||||||
|
"6": [
|
||||||
|
"x2out",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"23",
|
||||||
|
true,
|
||||||
|
"0018",
|
||||||
|
"",
|
||||||
|
"6"
|
||||||
|
],
|
||||||
|
"7": [
|
||||||
|
"wd",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"23",
|
||||||
|
true,
|
||||||
|
"0019",
|
||||||
|
"",
|
||||||
|
"7"
|
||||||
|
],
|
||||||
|
"8": [
|
||||||
|
"DOut",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"24",
|
||||||
|
false,
|
||||||
|
"0016",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"9": [
|
||||||
|
"AOut_1",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"25",
|
||||||
|
false,
|
||||||
|
"0017",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"10": [
|
||||||
|
"AOut_2",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"27",
|
||||||
|
false,
|
||||||
|
"0018",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mem": {
|
||||||
|
"0": [
|
||||||
|
"InputDebounce",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"29",
|
||||||
|
false,
|
||||||
|
"0019",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"AInMode_1",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"30",
|
||||||
|
false,
|
||||||
|
"0020",
|
||||||
|
"Select the type of input signal",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"2": [
|
||||||
|
"AInMode_2",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"31",
|
||||||
|
false,
|
||||||
|
"0021",
|
||||||
|
"Select the type of input signal",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"3": [
|
||||||
|
"AInMode_3",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"32",
|
||||||
|
false,
|
||||||
|
"0022",
|
||||||
|
"Select the type of input signal",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"4": [
|
||||||
|
"AInMode_4",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"33",
|
||||||
|
false,
|
||||||
|
"0023",
|
||||||
|
"Select the type of input signal",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"5": [
|
||||||
|
"AInMode_5",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"34",
|
||||||
|
false,
|
||||||
|
"0024",
|
||||||
|
"Select the type of input signal",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"6": [
|
||||||
|
"AInMode_6",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"35",
|
||||||
|
false,
|
||||||
|
"0025",
|
||||||
|
"Select the type of input signal",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"7": [
|
||||||
|
"AInMode_7",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"36",
|
||||||
|
false,
|
||||||
|
"0026",
|
||||||
|
"Select the type of input signal",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"8": [
|
||||||
|
"AInMode_8",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"37",
|
||||||
|
false,
|
||||||
|
"0027",
|
||||||
|
"Select the type of input signal",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"extend": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Connections": []
|
||||||
|
}
|
||||||
61
tests/compact/test_compact.py
Normal file
61
tests/compact/test_compact.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Test for RevPi Compact."""
|
||||||
|
__author__ = "Sven Sager"
|
||||||
|
__copyright__ = "Copyright (C) 2024 Sven Sager"
|
||||||
|
__license__ = "GPLv2"
|
||||||
|
|
||||||
|
from os.path import join, dirname
|
||||||
|
|
||||||
|
import revpimodio2
|
||||||
|
from tests import TestRevPiModIO
|
||||||
|
|
||||||
|
|
||||||
|
class TestCompact(TestRevPiModIO):
|
||||||
|
|
||||||
|
data_dir = dirname(__file__)
|
||||||
|
|
||||||
|
def test_compact(self):
|
||||||
|
rpi = self.modio(configrsc="config_compact.rsc")
|
||||||
|
|
||||||
|
self.assertIsInstance(rpi.core, revpimodio2.device.Compact)
|
||||||
|
|
||||||
|
# COMPACT LEDs prüfen
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x00")
|
||||||
|
rpi.core.A1 = revpimodio2.OFF
|
||||||
|
self.assertEqual(rpi.core.A1, 0)
|
||||||
|
rpi.core.A1 = revpimodio2.GREEN
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x01")
|
||||||
|
self.assertEqual(rpi.core.A1, 1)
|
||||||
|
rpi.core.A1 = revpimodio2.RED
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x02")
|
||||||
|
self.assertEqual(rpi.core.A1, 2)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi.core.A1 = 5
|
||||||
|
|
||||||
|
rpi.core.A2 = revpimodio2.OFF
|
||||||
|
self.assertEqual(rpi.core.A2, 0)
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x02")
|
||||||
|
rpi.core.A2 = revpimodio2.GREEN
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x06")
|
||||||
|
self.assertEqual(rpi.core.A2, 1)
|
||||||
|
rpi.core.A2 = revpimodio2.RED
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x0a")
|
||||||
|
self.assertEqual(rpi.core.A2, 2)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi.core.A2 = 5
|
||||||
|
|
||||||
|
# Spezielle Werte aufrufen
|
||||||
|
self.assertIsInstance(rpi.core.temperature, int)
|
||||||
|
self.assertIsInstance(rpi.core.frequency, int)
|
||||||
|
rpi.core.wd_toggle()
|
||||||
|
|
||||||
|
# Directzuweisung nicht erlaubt
|
||||||
|
with self.assertRaisesRegex(AttributeError, r"direct assignment is not supported"):
|
||||||
|
rpi.core.a1green = True
|
||||||
|
|
||||||
|
rpi.exit()
|
||||||
|
del rpi
|
||||||
|
|
||||||
|
# Bit piCtory config
|
||||||
|
rpi = self.modio(configrsc="config_compact_bits.json")
|
||||||
|
del rpi
|
||||||
1
tests/flat/config_flat.rsc
Normal file
1
tests/flat/config_flat.rsc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"App":{"name": "PiCtory", "version": "1.4.8","saveTS": "20210212181938","language": "en","layout": {"north":{"size":70,"initClosed":false,"initHidden":false},"south":{"size":285,"initClosed":false,"initHidden":false,"children":{"layout1":{"east":{"size":500,"initClosed":false,"initHidden":false}}}},"east":{"size":70,"initClosed":true,"initHidden":false,"children":{}},"west":{"size":200,"initClosed":false,"initHidden":false,"children":{"layout1":{}}}}},"Summary":{"inpTotal": 7,"outTotal": 5},"Devices":[{"GUID": "d8ded3e4-5b2b-3407-baa3-abbdde07e335","id": "device_RevPiFlat_20200921_1_0_001","type": "BASE","productType": "135","position": "0","name": "flat01","bmk": "RevPi Flat","inpVariant": 0,"outVariant": 0,"comment": "This is a RevPiFlat Device","offset": 0,"inp": {"0": ["AIn","0","16","0",true,"0000", "",""],"1": ["AIn_Status","0","8","2",false,"0001", "",""],"2": ["AOut_Status","0","8","3",false,"0002", "",""],"3": ["Core_Temperature","0","8","4",false,"0003", "",""],"4": ["Core_Frequency","0","8","5",false,"0004", "",""],"5": ["Top_Button","0","8","6",true,"0005", "",""]},"out": {"0": ["RevPiLED","0","16","7",true,"0006", "",""],"1": ["AOut","0","16","9",true,"0007", "",""],"2": ["DOut","0","8","11",true,"0008", "",""]},"mem": {"0": ["AInMode","0","8","12",false,"0009", "Select the type of analog input signal",""]},"extend": {}}],"Connections":[]}
|
||||||
260
tests/flat/config_flat_bits.rsc
Normal file
260
tests/flat/config_flat_bits.rsc
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
{
|
||||||
|
"App": {
|
||||||
|
"name": "PiCtory",
|
||||||
|
"version": "1.4.8",
|
||||||
|
"saveTS": "20210212181938",
|
||||||
|
"language": "en",
|
||||||
|
"layout": {
|
||||||
|
"north": {
|
||||||
|
"size": 70,
|
||||||
|
"initClosed": false,
|
||||||
|
"initHidden": false
|
||||||
|
},
|
||||||
|
"south": {
|
||||||
|
"size": 285,
|
||||||
|
"initClosed": false,
|
||||||
|
"initHidden": false,
|
||||||
|
"children": {
|
||||||
|
"layout1": {
|
||||||
|
"east": {
|
||||||
|
"size": 500,
|
||||||
|
"initClosed": false,
|
||||||
|
"initHidden": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"east": {
|
||||||
|
"size": 70,
|
||||||
|
"initClosed": true,
|
||||||
|
"initHidden": false,
|
||||||
|
"children": {}
|
||||||
|
},
|
||||||
|
"west": {
|
||||||
|
"size": 200,
|
||||||
|
"initClosed": false,
|
||||||
|
"initHidden": false,
|
||||||
|
"children": {
|
||||||
|
"layout1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Summary": {
|
||||||
|
"inpTotal": 7,
|
||||||
|
"outTotal": 5
|
||||||
|
},
|
||||||
|
"Devices": [
|
||||||
|
{
|
||||||
|
"GUID": "d8ded3e4-5b2b-3407-baa3-abbdde07e335",
|
||||||
|
"id": "device_RevPiFlat_20200921_1_0_001",
|
||||||
|
"type": "BASE",
|
||||||
|
"productType": "135",
|
||||||
|
"position": "0",
|
||||||
|
"name": "flat01",
|
||||||
|
"bmk": "RevPi Flat",
|
||||||
|
"inpVariant": 0,
|
||||||
|
"outVariant": 0,
|
||||||
|
"comment": "This is a RevPiFlat Device",
|
||||||
|
"offset": 0,
|
||||||
|
"inp": {
|
||||||
|
"0": [
|
||||||
|
"AIn",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"0",
|
||||||
|
true,
|
||||||
|
"0000",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"AIn_Status",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"2",
|
||||||
|
false,
|
||||||
|
"0001",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"2": [
|
||||||
|
"AOut_Status",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"3",
|
||||||
|
false,
|
||||||
|
"0002",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"3": [
|
||||||
|
"Core_Temperature",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"4",
|
||||||
|
false,
|
||||||
|
"0003",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"4": [
|
||||||
|
"Core_Frequency",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"5",
|
||||||
|
false,
|
||||||
|
"0004",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"5": [
|
||||||
|
"switch",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"6",
|
||||||
|
true,
|
||||||
|
"0005",
|
||||||
|
"",
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"out": {
|
||||||
|
"0": [
|
||||||
|
"a1green",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"7",
|
||||||
|
true,
|
||||||
|
"0006",
|
||||||
|
"",
|
||||||
|
"0"
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"a1red",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"7",
|
||||||
|
true,
|
||||||
|
"0007",
|
||||||
|
"",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"2": [
|
||||||
|
"a2green",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"7",
|
||||||
|
true,
|
||||||
|
"0008",
|
||||||
|
"",
|
||||||
|
"2"
|
||||||
|
],
|
||||||
|
"3": [
|
||||||
|
"a2red",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"7",
|
||||||
|
true,
|
||||||
|
"0009",
|
||||||
|
"",
|
||||||
|
"3"
|
||||||
|
],
|
||||||
|
"4": [
|
||||||
|
"a3green",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"7",
|
||||||
|
true,
|
||||||
|
"0010",
|
||||||
|
"",
|
||||||
|
"4"
|
||||||
|
],
|
||||||
|
"5": [
|
||||||
|
"a3red",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"7",
|
||||||
|
true,
|
||||||
|
"0011",
|
||||||
|
"",
|
||||||
|
"5"
|
||||||
|
],
|
||||||
|
"6": [
|
||||||
|
"a4green",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"7",
|
||||||
|
true,
|
||||||
|
"0012",
|
||||||
|
"",
|
||||||
|
"6"
|
||||||
|
],
|
||||||
|
"7": [
|
||||||
|
"a4red",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"7",
|
||||||
|
true,
|
||||||
|
"0013",
|
||||||
|
"",
|
||||||
|
"7"
|
||||||
|
],
|
||||||
|
"8": [
|
||||||
|
"a5green",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"7",
|
||||||
|
true,
|
||||||
|
"0014",
|
||||||
|
"",
|
||||||
|
"8"
|
||||||
|
],
|
||||||
|
"9": [
|
||||||
|
"a5red",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"7",
|
||||||
|
true,
|
||||||
|
"0015",
|
||||||
|
"",
|
||||||
|
"9"
|
||||||
|
],
|
||||||
|
"10": [
|
||||||
|
"AOut",
|
||||||
|
"0",
|
||||||
|
"16",
|
||||||
|
"9",
|
||||||
|
true,
|
||||||
|
"0016",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"11": [
|
||||||
|
"relais",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"11",
|
||||||
|
true,
|
||||||
|
"0017",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mem": {
|
||||||
|
"0": [
|
||||||
|
"AInMode",
|
||||||
|
"0",
|
||||||
|
"8",
|
||||||
|
"12",
|
||||||
|
false,
|
||||||
|
"0009",
|
||||||
|
"Select the type of analog input signal",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"extend": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Connections": []
|
||||||
|
}
|
||||||
94
tests/flat/test_flat.py
Normal file
94
tests/flat/test_flat.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Test RevPi Flat devices."""
|
||||||
|
__author__ = "Sven Sager"
|
||||||
|
__copyright__ = "Copyright (C) 2024 Sven Sager"
|
||||||
|
__license__ = "GPLv2"
|
||||||
|
|
||||||
|
from os.path import dirname
|
||||||
|
|
||||||
|
import revpimodio2
|
||||||
|
from tests import TestRevPiModIO
|
||||||
|
|
||||||
|
|
||||||
|
class TestFlat(TestRevPiModIO):
|
||||||
|
|
||||||
|
data_dir = dirname(__file__)
|
||||||
|
|
||||||
|
def test_flat(self):
|
||||||
|
rpi = self.modio(configrsc="config_flat.rsc")
|
||||||
|
rpi.setdefaultvalues()
|
||||||
|
|
||||||
|
self.assertIsInstance(rpi.core, revpimodio2.device.Flat)
|
||||||
|
|
||||||
|
# FLAT LEDs prüfen
|
||||||
|
rpi.core.A1 = revpimodio2.OFF
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x00\x00")
|
||||||
|
self.assertEqual(rpi.core.A1, 0)
|
||||||
|
rpi.core.A1 = revpimodio2.GREEN
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x01\x00")
|
||||||
|
self.assertEqual(rpi.core.A1, 1)
|
||||||
|
rpi.core.A1 = revpimodio2.RED
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x02\x00")
|
||||||
|
self.assertEqual(rpi.core.A1, 2)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi.core.A1 = 5
|
||||||
|
|
||||||
|
rpi.core.A2 = revpimodio2.OFF
|
||||||
|
self.assertEqual(rpi.core.A2, 0)
|
||||||
|
rpi.core.A2 = revpimodio2.GREEN
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x06\x00")
|
||||||
|
self.assertEqual(rpi.core.A2, 1)
|
||||||
|
rpi.core.A2 = revpimodio2.RED
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x0a\x00")
|
||||||
|
self.assertEqual(rpi.core.A2, 2)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi.core.A2 = 5
|
||||||
|
|
||||||
|
rpi.core.A3 = revpimodio2.OFF
|
||||||
|
self.assertEqual(rpi.core.A3, 0)
|
||||||
|
rpi.core.A3 = revpimodio2.GREEN
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x1a\x00")
|
||||||
|
self.assertEqual(rpi.core.A3, 1)
|
||||||
|
rpi.core.A3 = revpimodio2.RED
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x2a\x00")
|
||||||
|
self.assertEqual(rpi.core.A3, 2)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi.core.A3 = 5
|
||||||
|
|
||||||
|
rpi.core.A4 = revpimodio2.OFF
|
||||||
|
self.assertEqual(rpi.core.A4, 0)
|
||||||
|
rpi.core.A4 = revpimodio2.GREEN
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\x6a\x00")
|
||||||
|
self.assertEqual(rpi.core.A4, 1)
|
||||||
|
rpi.core.A4 = revpimodio2.RED
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\xaa\x00")
|
||||||
|
self.assertEqual(rpi.core.A4, 2)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi.core.A4 = 5
|
||||||
|
|
||||||
|
rpi.core.A5 = revpimodio2.OFF
|
||||||
|
self.assertEqual(rpi.core.A5, 0)
|
||||||
|
rpi.core.A5 = revpimodio2.GREEN
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\xaa\x01")
|
||||||
|
self.assertEqual(rpi.core.A5, 1)
|
||||||
|
rpi.core.A5 = revpimodio2.RED
|
||||||
|
self.assertEqual(rpi.io.RevPiLED.get_value(), b"\xaa\x02")
|
||||||
|
self.assertEqual(rpi.core.A5, 2)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi.core.A5 = 5
|
||||||
|
|
||||||
|
# Spezielle Werte aufrufen
|
||||||
|
self.assertIsInstance(rpi.core.temperature, int)
|
||||||
|
self.assertIsInstance(rpi.core.frequency, int)
|
||||||
|
rpi.core.wd_toggle()
|
||||||
|
|
||||||
|
# Directzuweisung nicht erlaubt
|
||||||
|
with self.assertRaisesRegex(AttributeError, r"direct assignment is not supported"):
|
||||||
|
rpi.core.a1green = True
|
||||||
|
|
||||||
|
rpi.exit()
|
||||||
|
del rpi
|
||||||
|
|
||||||
|
# Bit piCtory config
|
||||||
|
rpi = self.modio(configrsc="config_flat_bits.rsc")
|
||||||
|
del rpi
|
||||||
1
tests/replace_io/config.rsc
Normal file
1
tests/replace_io/config.rsc
Normal file
File diff suppressed because one or more lines are too long
22
tests/replace_io/replace_io.conf
Normal file
22
tests/replace_io/replace_io.conf
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
[test1]
|
||||||
|
replace=Output_19
|
||||||
|
frm=b
|
||||||
|
defaultvalue=255
|
||||||
|
byteorder=big
|
||||||
|
|
||||||
|
[r_bit0]
|
||||||
|
replace=Output_20
|
||||||
|
bmk=EinBit
|
||||||
|
frm=?
|
||||||
|
bit=0
|
||||||
|
|
||||||
|
[r_bit1]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=1
|
||||||
|
defaultvalue=True
|
||||||
|
|
||||||
|
[r_bit5]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=5
|
||||||
5
tests/replace_io/replace_io_bytes.conf
Normal file
5
tests/replace_io/replace_io_bytes.conf
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[data_values]
|
||||||
|
replace = I_LiftData
|
||||||
|
frm = 200s
|
||||||
|
defaultvalue = 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
|
||||||
5
tests/replace_io/replace_io_bytes_fail.conf
Normal file
5
tests/replace_io/replace_io_bytes_fail.conf
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[data_values]
|
||||||
|
replace = I_LiftData
|
||||||
|
frm = 200s
|
||||||
|
defaultvalue = 255 0 0 0 0 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
|
||||||
19
tests/replace_io/replace_io_fail.conf
Normal file
19
tests/replace_io/replace_io_fail.conf
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[test1]
|
||||||
|
replace=Output_19
|
||||||
|
frm=h
|
||||||
|
|
||||||
|
[r_bit0]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=0
|
||||||
|
|
||||||
|
[r_bit1]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=1
|
||||||
|
defaultvalue=True
|
||||||
|
|
||||||
|
[r_bit5]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=5
|
||||||
19
tests/replace_io/replace_io_failbit_int.conf
Normal file
19
tests/replace_io/replace_io_failbit_int.conf
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[test1]
|
||||||
|
replace=Output_19
|
||||||
|
frm=b
|
||||||
|
|
||||||
|
[r_bit0]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=True
|
||||||
|
|
||||||
|
[r_bit1]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=1
|
||||||
|
defaultvalue=True
|
||||||
|
|
||||||
|
[r_bit5]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=5
|
||||||
19
tests/replace_io/replace_io_faildefaultvalue_bool.conf
Normal file
19
tests/replace_io/replace_io_faildefaultvalue_bool.conf
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[test1]
|
||||||
|
replace=Output_19
|
||||||
|
frm=c
|
||||||
|
|
||||||
|
[r_bit0]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=0
|
||||||
|
|
||||||
|
[r_bit1]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=1
|
||||||
|
defaultvalue=komisch
|
||||||
|
|
||||||
|
[r_bit5]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=5
|
||||||
20
tests/replace_io/replace_io_faildefaultvalue_int.conf
Normal file
20
tests/replace_io/replace_io_faildefaultvalue_int.conf
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
[test1]
|
||||||
|
replace=Output_19
|
||||||
|
frm=c
|
||||||
|
defaultvalue=True
|
||||||
|
|
||||||
|
[r_bit0]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=0
|
||||||
|
|
||||||
|
[r_bit1]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=1
|
||||||
|
defaultvalue=True
|
||||||
|
|
||||||
|
[r_bit5]
|
||||||
|
replace=Output_20
|
||||||
|
frm=?
|
||||||
|
bit=5
|
||||||
4
tests/replace_io/replace_io_failformat.conf
Normal file
4
tests/replace_io/replace_io_failformat.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[test1
|
||||||
|
replace=Output_19
|
||||||
|
frm h
|
||||||
|
|
||||||
65
tests/replace_io/test_replace_io.py
Normal file
65
tests/replace_io/test_replace_io.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Tests for replace io file."""
|
||||||
|
__author__ = "Sven Sager"
|
||||||
|
__copyright__ = "Copyright (C) 2024 Sven Sager"
|
||||||
|
__license__ = "GPLv2"
|
||||||
|
|
||||||
|
from os.path import join, dirname
|
||||||
|
|
||||||
|
from tests import TestRevPiModIO
|
||||||
|
|
||||||
|
|
||||||
|
class TestReplaceIO(TestRevPiModIO):
|
||||||
|
|
||||||
|
data_dir = dirname(__file__)
|
||||||
|
|
||||||
|
def test_replace_io_file(self):
|
||||||
|
replace_io_file = join(self.data_dir, "replace_io.conf")
|
||||||
|
rpi = self.modio(replace_io_file=replace_io_file)
|
||||||
|
self.assertEqual(rpi.replace_io_file, replace_io_file)
|
||||||
|
rpi.setdefaultvalues()
|
||||||
|
self.assertEqual(rpi.io.test1.value, -1)
|
||||||
|
self.assertFalse(rpi.io.r_bit0.value)
|
||||||
|
self.assertTrue(rpi.io.r_bit1.value)
|
||||||
|
self.assertFalse(rpi.io.r_bit5.value)
|
||||||
|
self.assertFalse("Output_19" in rpi.io)
|
||||||
|
|
||||||
|
self.assertEqual(rpi.io.test1.byteorder, "big")
|
||||||
|
self.assertEqual(rpi.io.r_bit0.byteorder, "little")
|
||||||
|
|
||||||
|
self.assertEqual(rpi.io.r_bit0.bmk, "EinBit")
|
||||||
|
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
rpi.export_replaced_ios("/gehtnich/replace_io.conf")
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi.io.test1.export = 1
|
||||||
|
rpi.io.test1.export = True
|
||||||
|
rpi.io.Input_20.replace_io("byte_test", "3s", defaultvalue=b"\xff\x00\x80", export=True)
|
||||||
|
rpi.export_replaced_ios("/tmp/replace_io.conf")
|
||||||
|
del rpi
|
||||||
|
|
||||||
|
rpi = self.modio(replace_io_file="/tmp/replace_io.conf")
|
||||||
|
self.assertTrue(rpi.io.test1.export)
|
||||||
|
self.assertTrue(rpi.io.byte_test.export)
|
||||||
|
self.assertEqual(rpi.io.byte_test.defaultvalue, b"\xff\x00\x80")
|
||||||
|
|
||||||
|
def test_fb_replace_io_fail(self):
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
rpi = self.modio(replace_io_file=join(self.data_dir, "replace_io_fail.conf"))
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
rpi = self.modio(replace_io_file="no_file_nonono")
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
rpi = self.modio(replace_io_file=join(self.data_dir, "replace_io_failformat.conf"))
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi = self.modio(
|
||||||
|
replace_io_file=join(self.data_dir, "replace_io_faildefaultvalue_bool.conf")
|
||||||
|
)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi = self.modio(
|
||||||
|
replace_io_file=join(self.data_dir, "replace_io_faildefaultvalue_int.conf")
|
||||||
|
)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
rpi = self.modio(replace_io_file=join(self.data_dir, "replace_io_failbit_int.conf"))
|
||||||
|
with self.assertRaisesRegex(ValueError, r"defaultvalue to bytes"):
|
||||||
|
rpi = self.modio(replace_io_file=join(self.data_dir, "replace_io_bytes_fail.conf"))
|
||||||
1
tests/revpi4/config_connect4.rsc
Normal file
1
tests/revpi4/config_connect4.rsc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"App":{"name": "PiCtory", "version": "2.1.0","saveTS": "20230627075202","language": "en","layout": {"north":{"size":70,"initClosed":false,"initHidden":false},"south":{"size":200,"initClosed":false,"initHidden":false,"children":{"layout1":{"east":{"size":500,"initClosed":false,"initHidden":false}}}},"east":{"size":70,"initClosed":true,"initHidden":false,"children":{}},"west":{"size":253,"initClosed":false,"initHidden":false,"children":{"layout1":{}}}}},"Summary":{"inpTotal": 6,"outTotal": 7},"Devices":[{"GUID": "d2621a30-e371-87de-2b81-b301da201aa8","id": "device_RevPiConnect4_20230409_1_0_001","type": "BASE","productType": "136","position": "0","name": "RevPi Connect 4","bmk": "RevPi Connect 4","inpVariant": 0,"outVariant": 0,"comment": "This is a RevPi Connect 4 Device","offset": 0,"inp": {"0": ["RevPiStatus","0","8","0",true,"0000", "",""],"1": ["RevPiIOCycle","0","8","1",true,"0001", "",""],"2": ["RS485ErrorCnt","0","16","2",false,"0002", "",""],"3": ["Core_Temperature","0","8","4",false,"0003", "",""],"4": ["Core_Frequency","0","8","5",false,"0004", "",""]},"out": {"0": ["RevPiOutput","0","8","6",true,"0005", "",""],"1": ["RS485ErrorLimit1","10","16","7",false,"0006", "",""],"2": ["RS485ErrorLimit2","1000","16","9",false,"0007", "",""],"3": ["RevPiLED","0","16","11",true,"0008", "",""]},"mem": {},"extend": {}}],"Connections":[]}
|
||||||
59
tests/revpi4/test_connect4.py
Normal file
59
tests/revpi4/test_connect4.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Tests for RevPi 4 devices."""
|
||||||
|
__author__ = "Sven Sager"
|
||||||
|
__copyright__ = "Copyright (C) 2024 Sven Sager"
|
||||||
|
__license__ = "GPLv2"
|
||||||
|
|
||||||
|
from os.path import join, dirname
|
||||||
|
|
||||||
|
import revpimodio2
|
||||||
|
from tests import TestRevPiModIO
|
||||||
|
|
||||||
|
|
||||||
|
class TestRevPi4(TestRevPiModIO):
|
||||||
|
|
||||||
|
data_dir = dirname(__file__)
|
||||||
|
|
||||||
|
def test_connect4(self):
|
||||||
|
rpi = self.modio(configrsc="config_connect4.rsc")
|
||||||
|
rpi.setdefaultvalues()
|
||||||
|
|
||||||
|
self.assertIsInstance(rpi.core, revpimodio2.device.Connect4)
|
||||||
|
|
||||||
|
# Test all LED (A1 - A5) with all colors
|
||||||
|
lst_led_test = [
|
||||||
|
(rpi.core._get_leda1, rpi.core._set_leda1),
|
||||||
|
(rpi.core._get_leda2, rpi.core._set_leda2),
|
||||||
|
(rpi.core._get_leda3, rpi.core._set_leda3),
|
||||||
|
(rpi.core._get_leda4, rpi.core._set_leda4),
|
||||||
|
(rpi.core._get_leda5, rpi.core._set_leda5),
|
||||||
|
]
|
||||||
|
for i in range(len(lst_led_test)):
|
||||||
|
get_led = lst_led_test[i][0]
|
||||||
|
set_led = lst_led_test[i][1]
|
||||||
|
for k in (
|
||||||
|
(revpimodio2.GREEN, 2),
|
||||||
|
(revpimodio2.RED, 1),
|
||||||
|
(revpimodio2.BLUE, 4),
|
||||||
|
(revpimodio2.OFF, 0),
|
||||||
|
):
|
||||||
|
set_led(k[0])
|
||||||
|
self.assertEqual(
|
||||||
|
rpi.io.RevPiLED.get_value(),
|
||||||
|
(k[1] << (i * 3)).to_bytes(2, "little"),
|
||||||
|
)
|
||||||
|
self.assertEqual(get_led(), k[0])
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
set_led(8)
|
||||||
|
|
||||||
|
self.assertIsInstance(rpi.core.temperature, int)
|
||||||
|
self.assertIsInstance(rpi.core.frequency, int)
|
||||||
|
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
rpi.core.wd_toggle()
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(AttributeError, r"direct assignment is not supported"):
|
||||||
|
rpi.core.a5green = True
|
||||||
|
|
||||||
|
rpi.exit()
|
||||||
|
del rpi
|
||||||
Reference in New Issue
Block a user