diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 2e1637c..029a1a8 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -3,8 +3,6 @@ - - diff --git a/Makefile b/Makefile index 0c44674..07dca0b 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ endif SYSTEM_PYTHON = python3 PYTHON = $(or $(wildcard $(VENV_PATH)/bin/python), $(SYSTEM_PYTHON)) -all: build docs +all: test build docs .PHONY: all diff --git a/src/revpimodio2/__about__.py b/src/revpimodio2/__about__.py index bbe1c74..b75248f 100644 --- a/src/revpimodio2/__about__.py +++ b/src/revpimodio2/__about__.py @@ -3,4 +3,4 @@ __author__ = "Sven Sager " __copyright__ = "Copyright (C) 2023 Sven Sager" __license__ = "LGPLv2" -__version__ = "2.7.1" +__version__ = "2.7.2" diff --git a/src/revpimodio2/_internal.py b/src/revpimodio2/_internal.py index 1ae18ff..80cc8bb 100644 --- a/src/revpimodio2/_internal.py +++ b/src/revpimodio2/_internal.py @@ -8,6 +8,7 @@ __license__ = "LGPLv2" OFF = 0 GREEN = 1 RED = 2 +BLUE = 4 RISING = 31 FALLING = 32 BOTH = 33 @@ -53,6 +54,8 @@ def consttostr(value) -> str: return "GREEN" elif value == 2: return "RED" + elif value == 4: + return "BLUE" elif value == 31: return "RISING" elif value == 32: diff --git a/src/revpimodio2/device.py b/src/revpimodio2/device.py index 263265e..b2f92d4 100644 --- a/src/revpimodio2/device.py +++ b/src/revpimodio2/device.py @@ -1113,6 +1113,19 @@ class Connect4(ModularBase): raise AttributeError("direct assignment is not supported - use .value Attribute") 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: """Connect4-Klasse vorbereiten.""" super()._devconfigure() @@ -1298,7 +1311,7 @@ class Connect4(ModularBase): ) self.x2out = IOBase( 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, "little", False, @@ -1308,52 +1321,52 @@ class Connect4(ModularBase): """ 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: """ 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: """ 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] - return (unpack("> 6 + return self.__led_calculator((unpack("> 6) def _get_leda4(self) -> int: """ 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: """ 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: """ 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: - self.a1red(bool(value & 1)) - self.a1green(bool(value & 2)) + self.a1red(bool(value & 2)) + self.a1green(bool(value & 1)) self.a1blue(bool(value & 4)) else: 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. - :param: value 0=aus, 1=rot, 2=gruen, 4=blue + :param: value 0=aus, 1=gruen, 2=rot, 4=blue """ if 0 <= value <= 7: - self.a2red(bool(value & 1)) - self.a2green(bool(value & 2)) + self.a2red(bool(value & 2)) + self.a2green(bool(value & 1)) self.a2blue(bool(value & 4)) else: 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. - :param: value 0=aus, 1=rot, 2=gruen, 4=blue + :param: value 0=aus, 1=gruen, 2=rot, 4=blue """ if 0 <= value <= 7: - self.a3red(bool(value & 1)) - self.a3green(bool(value & 2)) + self.a3red(bool(value & 2)) + self.a3green(bool(value & 1)) self.a3blue(bool(value & 4)) else: 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. - :param: value 0=aus, 1=rot, 2=gruen, 4=blue + :param: value 0=aus, 1=gruen, 2=rot, 4=blue """ if 0 <= value <= 7: - self.a4red(bool(value & 1)) - self.a4green(bool(value & 2)) + self.a4red(bool(value & 2)) + self.a4green(bool(value & 1)) self.a4blue(bool(value & 4)) else: raise ValueError("led status must be between 0 and 7") @@ -1401,15 +1414,22 @@ class Connect4(ModularBase): """ 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: - self.a5red(bool(value & 1)) - self.a5green(bool(value & 2)) + self.a5red(bool(value & 2)) + self.a5green(bool(value & 1)) self.a5blue(bool(value & 4)) else: raise ValueError("led status must be between 0 and 7") + def wd_toggle(self): + """Toggle watchdog bit to prevent a timeout.""" + raise NotImplementedError( + "On the Connect 4, the hardware watchdog was removed from the process image by " + "KUNBUS. This function is no longer available on Connect 4 devices." + ) + A1 = property(_get_leda1, _set_leda1) A2 = property(_get_leda2, _set_leda2) A3 = property(_get_leda3, _set_leda3) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..35c6c20 --- /dev/null +++ b/tests/__init__.py @@ -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) diff --git a/tests/compact/config_compact.rsc b/tests/compact/config_compact.rsc new file mode 100644 index 0000000..7597d64 --- /dev/null +++ b/tests/compact/config_compact.rsc @@ -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":[]} \ No newline at end of file diff --git a/tests/compact/config_compact_bits.json b/tests/compact/config_compact_bits.json new file mode 100644 index 0000000..72788e0 --- /dev/null +++ b/tests/compact/config_compact_bits.json @@ -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": [] +} \ No newline at end of file diff --git a/tests/compact/test_compact.py b/tests/compact/test_compact.py new file mode 100644 index 0000000..395e440 --- /dev/null +++ b/tests/compact/test_compact.py @@ -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 diff --git a/tests/flat/config_flat.rsc b/tests/flat/config_flat.rsc new file mode 100644 index 0000000..945561f --- /dev/null +++ b/tests/flat/config_flat.rsc @@ -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":[]} \ No newline at end of file diff --git a/tests/flat/config_flat_bits.rsc b/tests/flat/config_flat_bits.rsc new file mode 100644 index 0000000..c78c7d2 --- /dev/null +++ b/tests/flat/config_flat_bits.rsc @@ -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": [] +} \ No newline at end of file diff --git a/tests/flat/test_flat.py b/tests/flat/test_flat.py new file mode 100644 index 0000000..98e8472 --- /dev/null +++ b/tests/flat/test_flat.py @@ -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 diff --git a/tests/replace_io/config.rsc b/tests/replace_io/config.rsc new file mode 100644 index 0000000..de4cbbc --- /dev/null +++ b/tests/replace_io/config.rsc @@ -0,0 +1 @@ +{"App":{"name": "PiCtory", "version": "1.2.3","saveTS": "20170826120906","language": "en","layout": {"north":{"size":70,"initClosed":false,"initHidden":false},"south":{"size":480,"initClosed":false,"initHidden":false,"children":{"layout1":{"east":{"size":500,"initClosed":false,"initHidden":false}}}},"east":{"size":70,"initClosed":true,"initHidden":false,"children":{"layout1":{"north":{"size":100,"initClosed":false,"initHidden":false},"south":{"size":98,"initClosed":false,"initHidden":false}}}},"west":{"size":200,"initClosed":false,"initHidden":false,"children":{"layout1":{}}}}},"Summary":{"inpTotal": 338,"outTotal": 113},"Devices":[{"catalogNr": "RevPiCore","GUID": "4ebb85e8-92ea-415d-b191-cc58c2857c0a","id": "device_RevPiCore_20170404_1_2_001","type": "BASE","productType": "95","position": "0","name": "picore01","bmk": "RevPi Core V1.2","inpVariant": 0,"outVariant": 0,"comment": "This is a RevPiCore 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_Temperatur","0","8","4",false,"0003", "",""],"4": ["Core_Frequency","0","8","5",false,"0004", "",""]},"out": {"0": ["RevPiLED","0","8","6",true,"0005", "",""],"1": ["RS485ErrorLimit1","10","16","7",false,"0006", "",""],"2": ["RS485ErrorLimit2","1000","16","9",false,"0007", "",""]},"mem": {},"extend": {}},{"catalogNr": "RevPiDI","GUID": "2e2c089e-6bef-14c0-852b-41b7cf48d846","id": "device_RevPiDI_20160818_1_0_001","type": "LEFT_RIGHT","productType": "97","position": "32","name": "di01","bmk": "RevPi DI","inpVariant": 0,"outVariant": 0,"comment": "","offset": 11,"inp": {"0": ["notaus_ok","0","1","0",true,"0000", "","0"],"1": ["motorschutz_ok","0","1","0",true,"0001", "","1"],"2": ["fu_ok","0","1","0",true,"0002", "","2"],"3": ["fu_motoran","0","1","0",true,"0003", "","3"],"4": ["I_5","0","1","0",true,"0004", "","4"],"5": ["I_6","0","1","0",true,"0005", "","5"],"6": ["I_7","0","1","0",true,"0006", "","6"],"7": ["I_8","0","1","0",true,"0007", "","7"],"8": ["t_automatik","0","1","0",true,"0008", "","8"],"9": ["t_start","0","1","0",true,"0009", "","9"],"10": ["t_stop","0","1","0",true,"0010", "","10"],"11": ["t_quit","0","1","0",true,"0011", "","11"],"12": ["t_notaus","0","1","0",true,"0012", "","12"],"13": ["I_14","0","1","0",true,"0013", "","13"],"14": ["I_15","0","1","0",true,"0014", "","14"],"15": ["I_16","0","1","0",true,"0015", "","15"],"16": ["Status","0","16","4",false,"0016", "",""],"17": ["Counter_1","0","32","6",false,"0017", "",""],"18": ["Counter_2","0","32","10",false,"0018", "",""],"19": ["Counter_3","0","32","14",false,"0019", "",""],"20": ["Counter_4","0","32","18",false,"0020", "",""],"21": ["Counter_5","0","32","22",false,"0021", "",""],"22": ["Counter_6","0","32","26",false,"0022", "",""],"23": ["Counter_7","0","32","30",false,"0023", "",""],"24": ["Counter_8","0","32","34",false,"0024", "",""],"25": ["Counter_9","0","32","38",false,"0025", "",""],"26": ["Counter_10","0","32","42",false,"0026", "",""],"27": ["Counter_11","0","32","46",false,"0027", "",""],"28": ["Counter_12","0","32","50",false,"0028", "",""],"29": ["Counter_13","0","32","54",false,"0029", "",""],"30": ["Counter_14","0","32","58",false,"0030", "",""],"31": ["Counter_15","0","32","62",false,"0031", "",""],"32": ["Counter_16","0","32","66",false,"0032", "",""],"33": ["Output_Status","0","16","2",false,"0050", "",""]},"out": {"0": ["Output","0","16","70",false,"0051", "",""],"1": ["PWM_1","0","8","72",false,"0052", "",""],"2": ["PWM_2","0","8","73",false,"0053", "",""],"3": ["PWM_3","0","8","74",false,"0054", "",""],"4": ["PWM_4","0","8","75",false,"0055", "",""],"5": ["PWM_5","0","8","76",false,"0056", "",""],"6": ["PWM_6","0","8","77",false,"0057", "",""],"7": ["PWM_7","0","8","78",false,"0058", "",""],"8": ["PWM_8","0","8","79",false,"0059", "",""],"9": ["PWM_9","0","8","80",false,"0060", "",""],"10": ["PWM_10","0","8","81",false,"0061", "",""],"11": ["PWM_11","0","8","82",false,"0062", "",""],"12": ["PWM_12","0","8","83",false,"0063", "",""],"13": ["PWM_13","0","8","84",false,"0064", "",""],"14": ["PWM_14","0","8","85",false,"0065", "",""],"15": ["PWM_15","0","8","86",false,"0066", "",""],"16": ["PWM_16","0","8","87",false,"0067", "",""]},"mem": {"0": ["InputMode_1","0","8","88",false,"0033", "",""],"1": ["InputMode_2","0","8","89",false,"0034", "",""],"2": ["InputMode_3","0","8","90",false,"0035", "",""],"3": ["InputMode_4","0","8","91",false,"0036", "",""],"4": ["InputMode_5","0","8","92",false,"0037", "",""],"5": ["InputMode_6","0","8","93",false,"0038", "",""],"6": ["InputMode_7","0","8","94",false,"0039", "",""],"7": ["InputMode_8","0","8","95",false,"0040", "",""],"8": ["InputMode_9","0","8","96",false,"0041", "",""],"9": ["InputMode_10","0","8","97",false,"0042", "",""],"10": ["InputMode_11","0","8","98",false,"0043", "",""],"11": ["InputMode_12","0","8","99",false,"0044", "",""],"12": ["InputMode_13","0","8","100",false,"0045", "",""],"13": ["InputMode_14","0","8","101",false,"0046", "",""],"14": ["InputMode_15","0","8","102",false,"0047", "",""],"15": ["InputMode_16","0","8","103",false,"0048", "",""],"16": ["InputDebounce","0","16","104",false,"0049", "",""],"17": ["OutputPushPull","0","16","106",false,"0068", "",""],"18": ["OutputOpenLoadDetect","0","16","108",false,"0069", "",""],"19": ["OutputPWMActive","0","16","110",false,"0070", "",""],"20": ["OutputPWMFrequency","2","8","112",false,"0071", "",""]},"extend": {}},{"catalogNr": "RevPiDI","GUID": "81e6c459-0398-a7c4-4954-d793ee9a5b89","id": "device_RevPiDI_20160818_1_0_002","type": "LEFT_RIGHT","productType": "97","position": "33","name": "di02","bmk": "RevPi DI","inpVariant": 0,"outVariant": 0,"comment": "","offset": 124,"inp": {"0": ["m_druck_ok","0","1","0",true,"0000", "","0"],"1": ["m_m1_eingefahren","0","1","0",true,"0001", "","1"],"2": ["m_m1_ausgefahren","0","1","0",true,"0002", "","2"],"3": ["m_m2_eingefahren","0","1","0",true,"0003", "","3"],"4": ["m_m2_ausgefahren","0","1","0",true,"0004", "","4"],"5": ["m_m3_eingefahren","0","1","0",true,"0005", "","5"],"6": ["m_m3_ausgefahren","0","1","0",true,"0006", "","6"],"7": ["s_rutsche","0","1","0",true,"0007", "","7"],"8": ["s_metall","0","1","0",true,"0008", "","8"],"9": ["s_magazin1","0","1","0",true,"0009", "","9"],"10": ["s_magazin2","0","1","0",true,"0010", "","10"],"11": ["I_12_i03","0","1","0",true,"0011", "","11"],"12": ["I_13_i03","0","1","0",true,"0012", "","12"],"13": ["I_14_i03","0","1","0",true,"0013", "","13"],"14": ["I_15_i03","0","1","0",true,"0014", "","14"],"15": ["mb_status","0","1","0",true,"0015", "","15"],"16": ["Status_i03","0","16","4",false,"0016", "",""],"17": ["Counter_1_i03","0","32","6",false,"0017", "",""],"18": ["Counter_2_i03","0","32","10",false,"0018", "",""],"19": ["Counter_3_i03","0","32","14",false,"0019", "",""],"20": ["Counter_4_i03","0","32","18",false,"0020", "",""],"21": ["Counter_5_i03","0","32","22",false,"0021", "",""],"22": ["Counter_6_i03","0","32","26",false,"0022", "",""],"23": ["Counter_7_i03","0","32","30",false,"0023", "",""],"24": ["Counter_8_i03","0","32","34",false,"0024", "",""],"25": ["Counter_9_i03","0","32","38",false,"0025", "",""],"26": ["Counter_10_i03","0","32","42",false,"0026", "",""],"27": ["Counter_11_i03","0","32","46",false,"0027", "",""],"28": ["Counter_12_i03","0","32","50",false,"0028", "",""],"29": ["Counter_13_i03","0","32","54",false,"0029", "",""],"30": ["Counter_14_i03","0","32","58",false,"0030", "",""],"31": ["Counter_15_i03","0","32","62",false,"0031", "",""],"32": ["Counter_16_i03","0","32","66",false,"0032", "",""],"33": ["Output_Status_i03","0","16","2",false,"0050", "",""]},"out": {"0": ["Output_i03","0","16","70",false,"0051", "",""],"1": ["PWM_1_i03","0","8","72",false,"0052", "",""],"2": ["PWM_2_i03","0","8","73",false,"0053", "",""],"3": ["PWM_3_i03","0","8","74",false,"0054", "",""],"4": ["PWM_4_i03","0","8","75",false,"0055", "",""],"5": ["PWM_5_i03","0","8","76",false,"0056", "",""],"6": ["PWM_6_i03","0","8","77",false,"0057", "",""],"7": ["PWM_7_i03","0","8","78",false,"0058", "",""],"8": ["PWM_8_i03","0","8","79",false,"0059", "",""],"9": ["PWM_9_i03","0","8","80",false,"0060", "",""],"10": ["PWM_10_i03","0","8","81",false,"0061", "",""],"11": ["PWM_11_i03","0","8","82",false,"0062", "",""],"12": ["PWM_12_i03","0","8","83",false,"0063", "",""],"13": ["PWM_13_i03","0","8","84",false,"0064", "",""],"14": ["PWM_14_i03","0","8","85",false,"0065", "",""],"15": ["PWM_15_i03","0","8","86",false,"0066", "",""],"16": ["PWM_16_i03","0","8","87",false,"0067", "",""]},"mem": {"0": ["InputMode_1_i03","0","8","88",false,"0033", "",""],"1": ["InputMode_2_i03","0","8","89",false,"0034", "",""],"2": ["InputMode_3_i03","0","8","90",false,"0035", "",""],"3": ["InputMode_4_i03","0","8","91",false,"0036", "",""],"4": ["InputMode_5_i03","0","8","92",false,"0037", "",""],"5": ["InputMode_6_i03","0","8","93",false,"0038", "",""],"6": ["InputMode_7_i03","0","8","94",false,"0039", "",""],"7": ["InputMode_8_i03","0","8","95",false,"0040", "",""],"8": ["InputMode_9_i03","0","8","96",false,"0041", "",""],"9": ["InputMode_10_i03","0","8","97",false,"0042", "",""],"10": ["InputMode_11_i03","0","8","98",false,"0043", "",""],"11": ["InputMode_12_i03","0","8","99",false,"0044", "",""],"12": ["InputMode_13_i03","0","8","100",false,"0045", "",""],"13": ["InputMode_14_i03","0","8","101",false,"0046", "",""],"14": ["InputMode_15_i03","0","8","102",false,"0047", "",""],"15": ["InputMode_16_i03","0","8","103",false,"0048", "",""],"16": ["InputDebounce_i03","0","16","104",false,"0049", "",""],"17": ["OutputPushPull_i03","0","16","106",false,"0068", "",""],"18": ["OutputOpenLoadDetect_i03","0","16","108",false,"0069", "",""],"19": ["OutputPWMActive_i03","0","16","110",false,"0070", "",""],"20": ["OutputPWMFrequency_i03","2","8","112",false,"0071", "",""]},"extend": {}},{"catalogNr": "RevPiDO","GUID": "4f8da9ea-91b2-d028-c60d-4476096a9dc2","id": "device_RevPiDO_20160818_1_0_001","type": "LEFT_RIGHT","productType": "98","position": "34","name": "do01","bmk": "RevPi DO","inpVariant": 0,"outVariant": 0,"comment": "","offset": 237,"inp": {"0": ["Output_Status_i04","0","16","2",false,"0000", "",""],"1": ["Status_i04","0","16","4",false,"0001", "",""],"2": ["Input","0","16","0",false,"0038", "",""],"3": ["Counter_1_i04","0","32","6",false,"0039", "",""],"4": ["Counter_2_i04","0","32","10",false,"0040", "",""],"5": ["Counter_3_i04","0","32","14",false,"0041", "",""],"6": ["Counter_4_i04","0","32","18",false,"0042", "",""],"7": ["Counter_5_i04","0","32","22",false,"0043", "",""],"8": ["Counter_6_i04","0","32","26",false,"0044", "",""],"9": ["Counter_7_i04","0","32","30",false,"0045", "",""],"10": ["Counter_8_i04","0","32","34",false,"0046", "",""],"11": ["Counter_9_i04","0","32","38",false,"0047", "",""],"12": ["Counter_10_i04","0","32","42",false,"0048", "",""],"13": ["Counter_11_i04","0","32","46",false,"0049", "",""],"14": ["Counter_12_i04","0","32","50",false,"0050", "",""],"15": ["Counter_13_i04","0","32","54",false,"0051", "",""],"16": ["Counter_14_i04","0","32","58",false,"0052", "",""],"17": ["Counter_15_i04","0","32","62",false,"0053", "",""],"18": ["Counter_16_i04","0","32","66",false,"0054", "",""]},"out": {"0": ["fu_rechts","0","1","70",true,"0002", "","0"],"1": ["fu_links","0","1","70",true,"0003", "","1"],"2": ["fu_schnell","0","1","70",true,"0004", "","2"],"3": ["fu_lahm","0","1","70",true,"0005", "","3"],"4": ["v_druck","0","1","70",true,"0006", "","4"],"5": ["v_m1_einfahren","0","1","70",true,"0007", "","5"],"6": ["v_m1_ausfahren","0","1","70",true,"0008", "","6"],"7": ["v_m2_einfahren","0","1","70",true,"0009", "","7"],"8": ["v_m2_ausfahren","0","1","70",true,"0010", "","8"],"9": ["v_m3_einfahren","0","1","70",true,"0011", "","9"],"10": ["v_m3_ausfahren","0","1","70",true,"0012", "","10"],"11": ["O_12","0","1","70",true,"0013", "","11"],"12": ["O_13","0","1","70",true,"0014", "","12"],"13": ["O_14","0","1","70",true,"0015", "","13"],"14": ["O_15","0","1","70",true,"0016", "","14"],"15": ["fu_frei","0","1","70",true,"0017", "","15"],"16": ["PWM_1_i04","0","8","72",false,"0018", "",""],"17": ["PWM_2_i04","0","8","73",false,"0019", "",""],"18": ["PWM_3_i04","0","8","74",false,"0020", "",""],"19": ["PWM_4_i04","0","8","75",false,"0021", "",""],"20": ["PWM_5_i04","0","8","76",false,"0022", "",""],"21": ["PWM_6_i04","0","8","77",false,"0023", "",""],"22": ["PWM_7_i04","0","8","78",false,"0024", "",""],"23": ["PWM_8_i04","0","8","79",false,"0025", "",""],"24": ["PWM_9_i04","0","8","80",false,"0026", "",""],"25": ["PWM_10_i04","0","8","81",false,"0027", "",""],"26": ["PWM_11_i04","0","8","82",false,"0028", "",""],"27": ["PWM_12_i04","0","8","83",false,"0029", "",""],"28": ["PWM_13_i04","0","8","84",false,"0030", "",""],"29": ["PWM_14_i04","0","8","85",false,"0031", "",""],"30": ["PWM_15_i04","0","8","86",false,"0032", "",""],"31": ["PWM_16_i04","0","8","87",false,"0033", "",""]},"mem": {"0": ["OutputPushPull_i04","0","16","106",false,"0034", "",""],"1": ["OutputOpenLoadDetect_i04","0","16","108",false,"0035", "",""],"2": ["OutputPWMActive_i04","0","16","110",false,"0036", "",""],"3": ["OutputPWMFrequency_i04","1","8","112",false,"0037", "",""],"4": ["InputMode_1_i04","0","8","88",false,"0055", "",""],"5": ["InputMode_2_i04","0","8","89",false,"0056", "",""],"6": ["InputMode_3_i04","0","8","90",false,"0057", "",""],"7": ["InputMode_4_i04","0","8","91",false,"0058", "",""],"8": ["InputMode_5_i04","0","8","92",false,"0059", "",""],"9": ["InputMode_6_i04","0","8","93",false,"0060", "",""],"10": ["InputMode_7_i04","0","8","94",false,"0061", "",""],"11": ["InputMode_8_i04","0","8","95",false,"0062", "",""],"12": ["InputMode_9_i04","0","8","96",false,"0063", "",""],"13": ["InputMode_10_i04","0","8","97",false,"0064", "",""],"14": ["InputMode_11_i04","0","8","98",false,"0065", "",""],"15": ["InputMode_12_i04","0","8","99",false,"0066", "",""],"16": ["InputMode_13_i04","0","8","100",false,"0067", "",""],"17": ["InputMode_14_i04","0","8","101",false,"0068", "",""],"18": ["InputMode_15_i04","0","8","102",false,"0069", "",""],"19": ["InputMode_16_i04","0","8","103",false,"0070", "",""],"20": ["InputDebounce_i04","0","16","104",false,"0071", "",""]},"extend": {}},{"catalogNr": "RevPiDO","GUID": "b8a70c62-9b91-9e1a-af2a-37f74b16aca2","id": "device_RevPiDO_20160818_1_0_002","type": "LEFT_RIGHT","productType": "98","position": "35","name": "do02","bmk": "RevPi DO","inpVariant": 0,"outVariant": 0,"comment": "","offset": 350,"inp": {"0": ["Output_Status_i05","0","16","2",false,"0000", "",""],"1": ["Status_i05","0","16","4",false,"0001", "",""],"2": ["Input_i05","0","16","0",false,"0038", "",""],"3": ["Counter_1_i05","0","32","6",false,"0039", "",""],"4": ["Counter_2_i05","0","32","10",false,"0040", "",""],"5": ["Counter_3_i05","0","32","14",false,"0041", "",""],"6": ["Counter_4_i05","0","32","18",false,"0042", "",""],"7": ["Counter_5_i05","0","32","22",false,"0043", "",""],"8": ["Counter_6_i05","0","32","26",false,"0044", "",""],"9": ["Counter_7_i05","0","32","30",false,"0045", "",""],"10": ["Counter_8_i05","0","32","34",false,"0046", "",""],"11": ["Counter_9_i05","0","32","38",false,"0047", "",""],"12": ["Counter_10_i05","0","32","42",false,"0048", "",""],"13": ["Counter_11_i05","0","32","46",false,"0049", "",""],"14": ["Counter_12_i05","0","32","50",false,"0050", "",""],"15": ["Counter_13_i05","0","32","54",false,"0051", "",""],"16": ["Counter_14_i05","0","32","58",false,"0052", "",""],"17": ["Counter_15_i05","0","32","62",false,"0053", "",""],"18": ["Counter_16_i05","0","32","66",false,"0054", "",""]},"out": {"0": ["fu_reset","0","1","70",true,"0002", "","0"],"1": ["h_start","0","1","70",true,"0003", "","1"],"2": ["h_fehler","0","1","70",true,"0004", "","2"],"3": ["O_04_i05","0","1","70",true,"0005", "","3"],"4": ["O_05_i05","0","1","70",true,"0006", "","4"],"5": ["O_06_i05","0","1","70",true,"0007", "","5"],"6": ["O_07_i05","0","1","70",true,"0008", "","6"],"7": ["O_08_i05","0","1","70",true,"0009", "","7"],"8": ["O_09_i05","0","1","70",true,"0010", "","8"],"9": ["O_10_i05","0","1","70",true,"0011", "","9"],"10": ["O_11_i05","0","1","70",true,"0012", "","10"],"11": ["O_12_i05","0","1","70",true,"0013", "","11"],"12": ["O_13_i05","0","1","70",true,"0014", "","12"],"13": ["O_14_i05","0","1","70",true,"0015", "","13"],"14": ["O_15_i05","0","1","70",true,"0016", "","14"],"15": ["mb_connect","0","1","70",true,"0017", "","15"],"16": ["PWM_1_i05","0","8","72",false,"0018", "",""],"17": ["PWM_2_i05","0","8","73",false,"0019", "",""],"18": ["PWM_3_i05","0","8","74",false,"0020", "",""],"19": ["PWM_4_i05","0","8","75",false,"0021", "",""],"20": ["PWM_5_i05","0","8","76",false,"0022", "",""],"21": ["PWM_6_i05","0","8","77",false,"0023", "",""],"22": ["PWM_7_i05","0","8","78",false,"0024", "",""],"23": ["PWM_8_i05","0","8","79",false,"0025", "",""],"24": ["PWM_9_i05","0","8","80",false,"0026", "",""],"25": ["PWM_10_i05","0","8","81",false,"0027", "",""],"26": ["PWM_11_i05","0","8","82",false,"0028", "",""],"27": ["PWM_12_i05","0","8","83",false,"0029", "",""],"28": ["PWM_13_i05","0","8","84",false,"0030", "",""],"29": ["PWM_14_i05","0","8","85",false,"0031", "",""],"30": ["PWM_15_i05","0","8","86",false,"0032", "",""],"31": ["PWM_16_i05","0","8","87",false,"0033", "",""]},"mem": {"0": ["OutputPushPull_i05","0","16","106",false,"0034", "",""],"1": ["OutputOpenLoadDetect_i05","0","16","108",false,"0035", "",""],"2": ["OutputPWMActive_i05","0","16","110",false,"0036", "",""],"3": ["OutputPWMFrequency_i05","1","8","112",false,"0037", "",""],"4": ["InputMode_1_i05","0","8","88",false,"0055", "",""],"5": ["InputMode_2_i05","0","8","89",false,"0056", "",""],"6": ["InputMode_3_i05","0","8","90",false,"0057", "",""],"7": ["InputMode_4_i05","0","8","91",false,"0058", "",""],"8": ["InputMode_5_i05","0","8","92",false,"0059", "",""],"9": ["InputMode_6_i05","0","8","93",false,"0060", "",""],"10": ["InputMode_7_i05","0","8","94",false,"0061", "",""],"11": ["InputMode_8_i05","0","8","95",false,"0062", "",""],"12": ["InputMode_9_i05","0","8","96",false,"0063", "",""],"13": ["InputMode_10_i05","0","8","97",false,"0064", "",""],"14": ["InputMode_11_i05","0","8","98",false,"0065", "",""],"15": ["InputMode_12_i05","0","8","99",false,"0066", "",""],"16": ["InputMode_13_i05","0","8","100",false,"0067", "",""],"17": ["InputMode_14_i05","0","8","101",false,"0068", "",""],"18": ["InputMode_15_i05","0","8","102",false,"0069", "",""],"19": ["InputMode_16_i05","0","8","103",false,"0070", "",""],"20": ["InputDebounce_i05","0","16","104",false,"0071", "",""]},"extend": {}},{"catalogNr": "RevPiAIO","GUID": "76f10e57-ecaf-2a45-f4df-b9a66e3f40db","id": "device_RevPiAIO_20170301_1_0_001","type": "LEFT_RIGHT","productType": "103","position": "36","name": "aio01","bmk": "RevPi AIO","inpVariant": 0,"outVariant": 0,"comment": "","offset": 463,"inp": {"0": ["fu_ist","0","16","0",false,"0000", "",""],"1": ["InputValue_2","0","16","2",false,"0001", "",""],"2": ["InputValue_3","0","16","4",false,"0002", "",""],"3": ["InputValue_4","0","16","6",false,"0003", "",""],"4": ["InputStatus_1","0","8","8",false,"0004", "",""],"5": ["InputStatus_2","0","8","9",false,"0005", "",""],"6": ["InputStatus_3","0","8","10",false,"0006", "",""],"7": ["InputStatus_4","0","8","11",false,"0007", "",""],"8": ["tmp_schrank","0","16","12",false,"0008", "",""],"9": ["RTDValue_2","0","16","14",false,"0009", "",""],"10": ["RTDStatus_1","0","8","16",false,"0010", "",""],"11": ["RTDStatus_2","0","8","17",false,"0011", "",""],"12": ["OutputStatus_1","0","8","18",false,"0012", "",""],"13": ["OutputStatus_2","0","8","19",false,"0013", "",""]},"out": {"0": ["OutputValue_1","0","16","20",false,"0014", "",""],"1": ["fu_soll","0","16","22",false,"0015", "",""]},"mem": {"0": ["Input1Range","1","8","24",false,"0016", "You must use wire bridges for current measurement!",""],"1": ["Input1Multiplier","1","16","25",false,"0017", "",""],"2": ["Input1Divisor","1","16","27",false,"0018", "",""],"3": ["Input1Offset","0","16","29",false,"0019", "",""],"4": ["Input2Range","1","8","31",false,"0020", "You must use wire bridges for current measurement!",""],"5": ["Input2Multiplier","1","16","32",false,"0021", "",""],"6": ["Input2Divisor","1","16","34",false,"0022", "",""],"7": ["Input2Offset","0","16","36",false,"0023", "",""],"8": ["Input3Range","1","8","38",false,"0024", "You must use wire bridges for current measurement!",""],"9": ["Input3Multiplier","1","16","39",false,"0025", "",""],"10": ["Input3Divisor","1","16","41",false,"0026", "",""],"11": ["Input3Offset","0","16","43",false,"0027", "",""],"12": ["Input4Range","1","8","45",false,"0028", "You must use wire bridges for current measurement!",""],"13": ["Input4Multiplier","1","16","46",false,"0029", "",""],"14": ["Input4Divisor","1","16","48",false,"0030", "",""],"15": ["Input4Offset","0","16","50",false,"0031", "",""],"16": ["ADC_DataRate","0","8","52",false,"0032", "Use lowest value for highest precision and a maximum 50 Hz suppression",""],"17": ["RTD1Type","0","8","53",false,"0033", "",""],"18": ["RTD1Wiring","0","8","54",false,"0034", "You must use wire bridges for 2-wire sensors!",""],"19": ["RTD1Multiplier","1","16","55",false,"0035", "",""],"20": ["RTD1Divisor","1","16","57",false,"0036", "",""],"21": ["RTD1Offset","0","16","59",false,"0037", "",""],"22": ["RTD2Type","0","8","61",false,"0038", "",""],"23": ["RTD2Wiring","0","8","62",false,"0039", "You must use wire bridges for 2-wire sensors!",""],"24": ["RTD2Multiplier","1","16","63",false,"0040", "",""],"25": ["RTD2Divisor","1","16","65",false,"0041", "",""],"26": ["RTD2Offset","0","16","67",false,"0042", "",""],"27": ["Output1Range","0","8","69",false,"0043", "",""],"28": ["Output1EnableSlew","0","8","70",false,"0044", "Enable slew rate deceleration",""],"29": ["Output1SlewStepSize","0","8","71",false,"0045", "Slew rate step size",""],"30": ["Output1SlewClock","0","8","72",false,"0046", "lock rate of slew rate deceleration in kHz",""],"31": ["Output1Multiplier","1","16","73",false,"0047", "",""],"32": ["Output1Divisor","1","16","75",false,"0048", "",""],"33": ["Output1Offset","0","16","77",false,"0049", "",""],"34": ["Output2Range","2","8","79",false,"0050", "",""],"35": ["Output2EnableSlew","0","8","80",false,"0051", "Enable slew rate deceleration",""],"36": ["Output2SlewStepSize","0","8","81",false,"0052", "Slew rate step size",""],"37": ["Output2SlewClock","0","8","82",false,"0053", "lock rate of slew rate deceleration in kHz",""],"38": ["Output2Multiplier","1","16","83",false,"0054", "",""],"39": ["Output2Divisor","1","16","85",false,"0055", "",""],"40": ["Output2Offset","0","16","87",false,"0056", "",""]},"extend": {}},{"catalogNr": "Virtual01","GUID": "c3bf8705-d96a-6452-2566-40c5d86a5061","id": "device_Virtual01_20160818_1_0_001","type": "VIRTUAL","productType": "32768","position": "64","name": "virt01","bmk": "Virtual Device 32 Byte","inpVariant": 0,"outVariant": 0,"comment": "Virtual Device to reserve space in process image for user applications","offset": 552,"inp": {"0": ["pbit0_7","0","8","0",false,"0000", "",""],"1": ["pbit8_15","0","8","1",false,"0001", "",""],"2": ["pbit16_23","0","8","2",false,"0002", "",""],"3": ["pbit24_31","0","8","3",false,"0003", "",""],"4": ["magazin1_max","4","8","4",false,"0004", "",""],"5": ["magazin2_max","4","8","5",false,"0005", "",""],"6": ["p_drehzahl1","136","8","6",false,"0006", "",""],"7": ["p_drehzahl2","19","8","7",false,"0007", "",""],"8": ["Input_9","0","8","8",false,"0008", "",""],"9": ["Input_10","0","8","9",false,"0009", "",""],"10": ["Input_11","0","8","10",false,"0010", "",""],"11": ["Input_12","0","8","11",false,"0011", "",""],"12": ["Input_13","0","8","12",false,"0012", "",""],"13": ["Input_14","0","8","13",false,"0013", "",""],"14": ["Input_15","0","8","14",false,"0014", "",""],"15": ["Input_16","0","8","15",false,"0015", "",""],"16": ["Input_17","0","8","16",false,"0016", "",""],"17": ["Input_18","0","8","17",false,"0017", "",""],"18": ["Input_19","0","8","18",false,"0018", "",""],"19": ["Input_20","0","8","19",false,"0019", "",""],"20": ["Input_21","0","8","20",false,"0020", "",""],"21": ["Input_22","0","8","21",false,"0021", "",""],"22": ["Input_23","0","8","22",false,"0022", "",""],"23": ["Input_24","0","8","23",false,"0023", "",""],"24": ["Input_25","0","8","24",false,"0024", "",""],"25": ["Input_26","0","8","25",false,"0025", "",""],"26": ["Input_27","0","8","26",false,"0026", "",""],"27": ["Input_28","0","8","27",false,"0027", "",""],"28": ["Input_29","0","8","28",false,"0028", "",""],"29": ["Input_30","0","8","29",false,"0029", "",""],"30": ["Input_31","0","8","30",false,"0030", "",""],"31": ["Input_32","0","8","31",false,"0031", "",""]},"out": {"0": ["meldung0_7","0","8","32",false,"0032", "",""],"1": ["meldung8_15","0","8","33",false,"0033", "",""],"2": ["meldung16_23","0","8","34",false,"0034", "",""],"3": ["meldung24_31","0","8","35",false,"0035", "",""],"4": ["magazin1","0","8","36",false,"0036", "",""],"5": ["magazin2","0","8","37",false,"0037", "",""],"6": ["Output_7","0","8","38",false,"0038", "",""],"7": ["Output_8","0","8","39",false,"0039", "",""],"8": ["Output_9","0","8","40",false,"0040", "",""],"9": ["Output_10","0","8","41",false,"0041", "",""],"10": ["Output_11","0","8","42",false,"0042", "",""],"11": ["Output_12","0","8","43",false,"0043", "",""],"12": ["Output_13","0","8","44",false,"0044", "",""],"13": ["Output_14","0","8","45",false,"0045", "",""],"14": ["Output_15","0","8","46",false,"0046", "",""],"15": ["Output_16","0","8","47",false,"0047", "",""],"16": ["Output_17","0","8","48",false,"0048", "",""],"17": ["Output_18","0","8","49",false,"0049", "",""],"18": ["Output_19","0","8","50",false,"0050", "",""],"19": ["Output_20","0","8","51",false,"0051", "",""],"20": ["Output_21","0","8","52",false,"0052", "",""],"21": ["Output_22","0","8","53",false,"0053", "",""],"22": ["Output_23","0","8","54",false,"0054", "",""],"23": ["Output_24","0","8","55",false,"0055", "",""],"24": ["Output_25","0","8","56",false,"0056", "",""],"25": ["Output_26","0","8","57",false,"0057", "",""],"26": ["Output_27","0","8","58",false,"0058", "",""],"27": ["Output_28","0","8","59",false,"0059", "",""],"28": ["Output_29","0","8","60",false,"0060", "",""],"29": ["Output_30","0","8","61",false,"0061", "",""],"30": ["Output_31","0","8","62",false,"0062", "",""],"31": ["Output_32","0","8","63",false,"0063", "",""]},"mem": {},"extend": {}}],"Connections":[]} \ No newline at end of file diff --git a/tests/replace_io/replace_io.conf b/tests/replace_io/replace_io.conf new file mode 100644 index 0000000..bfa4605 --- /dev/null +++ b/tests/replace_io/replace_io.conf @@ -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 diff --git a/tests/replace_io/replace_io_bytes.conf b/tests/replace_io/replace_io_bytes.conf new file mode 100644 index 0000000..54f6555 --- /dev/null +++ b/tests/replace_io/replace_io_bytes.conf @@ -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 + diff --git a/tests/replace_io/replace_io_bytes_fail.conf b/tests/replace_io/replace_io_bytes_fail.conf new file mode 100644 index 0000000..6281aac --- /dev/null +++ b/tests/replace_io/replace_io_bytes_fail.conf @@ -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 + diff --git a/tests/replace_io/replace_io_fail.conf b/tests/replace_io/replace_io_fail.conf new file mode 100644 index 0000000..5df5be1 --- /dev/null +++ b/tests/replace_io/replace_io_fail.conf @@ -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 diff --git a/tests/replace_io/replace_io_failbit_int.conf b/tests/replace_io/replace_io_failbit_int.conf new file mode 100644 index 0000000..4941844 --- /dev/null +++ b/tests/replace_io/replace_io_failbit_int.conf @@ -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 diff --git a/tests/replace_io/replace_io_faildefaultvalue_bool.conf b/tests/replace_io/replace_io_faildefaultvalue_bool.conf new file mode 100644 index 0000000..60900cd --- /dev/null +++ b/tests/replace_io/replace_io_faildefaultvalue_bool.conf @@ -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 diff --git a/tests/replace_io/replace_io_faildefaultvalue_int.conf b/tests/replace_io/replace_io_faildefaultvalue_int.conf new file mode 100644 index 0000000..fe47481 --- /dev/null +++ b/tests/replace_io/replace_io_faildefaultvalue_int.conf @@ -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 diff --git a/tests/replace_io/replace_io_failformat.conf b/tests/replace_io/replace_io_failformat.conf new file mode 100644 index 0000000..d69ee92 --- /dev/null +++ b/tests/replace_io/replace_io_failformat.conf @@ -0,0 +1,4 @@ +[test1 +replace=Output_19 +frm h + diff --git a/tests/replace_io/test_replace_io.py b/tests/replace_io/test_replace_io.py new file mode 100644 index 0000000..2919cb1 --- /dev/null +++ b/tests/replace_io/test_replace_io.py @@ -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")) diff --git a/tests/revpi4/config_connect4.rsc b/tests/revpi4/config_connect4.rsc new file mode 100644 index 0000000..25fd350 --- /dev/null +++ b/tests/revpi4/config_connect4.rsc @@ -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":[]} \ No newline at end of file diff --git a/tests/revpi4/test_connect4.py b/tests/revpi4/test_connect4.py new file mode 100644 index 0000000..463658c --- /dev/null +++ b/tests/revpi4/test_connect4.py @@ -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(NotImplementedError): + rpi.core.wd_toggle() + + with self.assertRaisesRegex(AttributeError, r"direct assignment is not supported"): + rpi.core.a5green = True + + rpi.exit() + del rpi