diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index deb3530..a9b5fcb 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -36,6 +36,15 @@ jobs: timezoneLinux: "Europe/Berlin" timezoneMacos: "Europe/Berlin" timezoneWindows: "Europe/Berlin" + # - name: Start Mosquitto + # uses: namoshek/mosquitto-github-action@v1 + # with: + # version: '1.6' + # ports: '1883:1883 8883:8883' + # certificates: ${{ github.workspace }}/.ci/tls-certificates + # config: ${{ github.workspace }}/.ci/mosquitto.conf + # password-file: ${{ github.workspace}}/.ci/mosquitto.passwd + # container-name: 'mqtt' - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis @@ -46,7 +55,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install flake8 pytest pytest-asyncio pytest-cov coverage + if [ -f requirements-test.txt ]; then pip install -r requirements-test.txt; fi if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with flake8 run: | diff --git a/app/requirements-test.txt b/app/requirements-test.txt new file mode 100644 index 0000000..d07ed29 --- /dev/null +++ b/app/requirements-test.txt @@ -0,0 +1,6 @@ + flake8 + pytest + pytest-asyncio + pytest-cov + mock + coverage \ No newline at end of file diff --git a/app/src/gen3/talent.py b/app/src/gen3/talent.py index 90f258c..611c9fc 100644 --- a/app/src/gen3/talent.py +++ b/app/src/gen3/talent.py @@ -177,7 +177,7 @@ class Talent(Message): return self.__build_header(0x70, 0x77) - self._send_buffer += b'\x00\x01\xa3\x28' # fixme + self._send_buffer += b'\x00\x01\xa3\x28' # magic ? self._send_buffer += struct.pack('!B', len(modbus_pdu)) self._send_buffer += modbus_pdu self.__finish_send_msg() diff --git a/app/src/mqtt.py b/app/src/mqtt.py index 7bc9ce0..a51f039 100644 --- a/app/src/mqtt.py +++ b/app/src/mqtt.py @@ -2,10 +2,16 @@ import asyncio import logging import aiomqtt import traceback -from modbus import Modbus -from messages import Message -from config import Config -from singleton import Singleton +if __name__ == "app.src.mqtt": + from app.src.modbus import Modbus + from app.src.messages import Message + from app.src.config import Config + from app.src.singleton import Singleton +else: # pragma: no cover + from modbus import Modbus + from messages import Message + from config import Config + from singleton import Singleton logger_mqtt = logging.getLogger('mqtt') @@ -22,6 +28,14 @@ class Mqtt(metaclass=Singleton): self.task = loop.create_task(self.__loop()) self.ha_restarts = 0 + ha = Config.get('ha') + self.ha_status_topic = f"{ha['auto_conf_prefix']}/status" + self.mb_rated_topic = f"{ha['entity_prefix']}/+/rated_load" + self.mb_out_coeff_topic = f"{ha['entity_prefix']}/+/out_coeff" + self.mb_reads_topic = f"{ha['entity_prefix']}/+/modbus_read_regs" + self.mb_inputs_topic = f"{ha['entity_prefix']}/+/modbus_read_inputs" + self.mb_at_cmd_topic = f"{ha['entity_prefix']}/+/at_cmd" + @property def ha_restarts(self): return self._ha_restarts @@ -49,7 +63,6 @@ class Mqtt(metaclass=Singleton): async def __loop(self) -> None: mqtt = Config.get('mqtt') - ha = Config.get('ha') logger_mqtt.info(f'start MQTT: host:{mqtt["host"]} port:' f'{mqtt["port"]} ' f'user:{mqtt["user"]}') @@ -59,12 +72,6 @@ class Mqtt(metaclass=Singleton): password=mqtt['passwd']) interval = 5 # Seconds - ha_status_topic = f"{ha['auto_conf_prefix']}/status" - mb_rated_topic = "tsun/+/rated_load" # fixme - mb_out_coeff_topic = "tsun/+/out_coeff" # fixme - mb_reads_topic = "tsun/+/modbus_read_regs" # fixme - mb_inputs_topic = "tsun/+/modbus_read_inputs" # fixme - mb_at_cmd_topic = "tsun/+/at_cmd" # fixme while True: try: @@ -74,51 +81,15 @@ class Mqtt(metaclass=Singleton): if self.__cb_mqtt_is_up: await self.__cb_mqtt_is_up() - # async with self.__client.messages() as messages: - await self.__client.subscribe(ha_status_topic) - await self.__client.subscribe(mb_rated_topic) - await self.__client.subscribe(mb_out_coeff_topic) - await self.__client.subscribe(mb_reads_topic) - await self.__client.subscribe(mb_inputs_topic) - await self.__client.subscribe(mb_at_cmd_topic) + await self.__client.subscribe(self.ha_status_topic) + await self.__client.subscribe(self.mb_rated_topic) + await self.__client.subscribe(self.mb_out_coeff_topic) + await self.__client.subscribe(self.mb_reads_topic) + await self.__client.subscribe(self.mb_inputs_topic) + await self.__client.subscribe(self.mb_at_cmd_topic) async for message in self.__client.messages: - if message.topic.matches(ha_status_topic): - status = message.payload.decode("UTF-8") - logger_mqtt.info('Home-Assistant Status:' - f' {status}') - if status == 'online': - self.ha_restarts += 1 - await self.__cb_mqtt_is_up() - - if message.topic.matches(mb_rated_topic): - await self.modbus_cmd(message, - Modbus.WRITE_SINGLE_REG, - 1, 0x2008) - - if message.topic.matches(mb_out_coeff_topic): - payload = message.payload.decode("UTF-8") - val = round(float(payload) * 1024/100) - - if val < 0 or val > 1024: - logger_mqtt.error('out_coeff: value must be in' - 'the range 0..100,' - f' got: {payload}') - else: - await self.modbus_cmd(message, - Modbus.WRITE_SINGLE_REG, - 0, 0x202c, val) - - if message.topic.matches(mb_reads_topic): - await self.modbus_cmd(message, - Modbus.READ_REGS, 2) - - if message.topic.matches(mb_inputs_topic): - await self.modbus_cmd(message, - Modbus.READ_INPUTS, 2) - - if message.topic.matches(mb_at_cmd_topic): - await self.at_cmd(message) + await self.dispatch_msg(message) except aiomqtt.MqttError: if Config.is_default('mqtt'): @@ -142,46 +113,76 @@ class Mqtt(metaclass=Singleton): f"Exception:\n" f"{traceback.format_exc()}") + async def dispatch_msg(self, message): + if message.topic.matches(self.ha_status_topic): + status = message.payload.decode("UTF-8") + logger_mqtt.info('Home-Assistant Status:' + f' {status}') + if status == 'online': + self.ha_restarts += 1 + await self.__cb_mqtt_is_up() + + if message.topic.matches(self.mb_rated_topic): + await self.modbus_cmd(message, + Modbus.WRITE_SINGLE_REG, + 1, 0x2008) + + if message.topic.matches(self.mb_out_coeff_topic): + payload = message.payload.decode("UTF-8") + try: + val = round(float(payload) * 1024/100) + if val < 0 or val > 1024: + logger_mqtt.error('out_coeff: value must be in' + 'the range 0..100,' + f' got: {payload}') + else: + await self.modbus_cmd(message, + Modbus.WRITE_SINGLE_REG, + 0, 0x202c, val) + except Exception: + pass + + if message.topic.matches(self.mb_reads_topic): + await self.modbus_cmd(message, + Modbus.READ_REGS, 2) + + if message.topic.matches(self.mb_inputs_topic): + await self.modbus_cmd(message, + Modbus.READ_INPUTS, 2) + + if message.topic.matches(self.mb_at_cmd_topic): + await self.at_cmd(message) + def each_inverter(self, message, func_name: str): topic = str(message.topic) node_id = topic.split('/')[1] + '/' - found = False for m in Message: if m.server_side and (m.node_id == node_id): - found = True logger_mqtt.debug(f'Found: {node_id}') fnc = getattr(m, func_name, None) if callable(fnc): yield fnc else: logger_mqtt.warning(f'Cmd not supported by: {node_id}') + break - if not found: + else: logger_mqtt.warning(f'Node_id: {node_id} not found') async def modbus_cmd(self, message, func, params=0, addr=0, val=0): - topic = str(message.topic) - node_id = topic.split('/')[1] + '/' - # refactor into a loop over a table payload = message.payload.decode("UTF-8") - logger_mqtt.info(f'MODBUS via MQTT: {topic} = {payload}') - for m in Message: - if m.server_side and (m.node_id == node_id): - logger_mqtt.debug(f'Found: {node_id}') - fnc = getattr(m, "send_modbus_cmd", None) - res = payload.split(',') - if params > 0 and params != len(res): - logger_mqtt.error(f'Parameter expected: {params}, ' - f'got: {len(res)}') - return - - if callable(fnc): - if params == 1: - val = int(payload) - elif params == 2: - addr = int(res[0], base=16) - val = int(res[1]) # lenght - await fnc(func, addr, val, logging.INFO) + for fnc in self.each_inverter(message, "send_modbus_cmd"): + res = payload.split(',') + if params > 0 and params != len(res): + logger_mqtt.error(f'Parameter expected: {params}, ' + f'got: {len(res)}') + return + if params == 1: + val = int(payload) + elif params == 2: + addr = int(res[0], base=16) + val = int(res[1]) # lenght + await fnc(func, addr, val, logging.INFO) async def at_cmd(self, message): payload = message.payload.decode("UTF-8") diff --git a/app/src/singleton.py b/app/src/singleton.py index 48778b9..8222146 100644 --- a/app/src/singleton.py +++ b/app/src/singleton.py @@ -1,9 +1,14 @@ +from weakref import WeakValueDictionary + + class Singleton(type): - _instances = {} + _instances = WeakValueDictionary() def __call__(cls, *args, **kwargs): # logger_mqtt.debug('singleton: __call__') if cls not in cls._instances: - cls._instances[cls] = super(Singleton, - cls).__call__(*args, **kwargs) + instance = super(Singleton, + cls).__call__(*args, **kwargs) + cls._instances[cls] = instance + return cls._instances[cls] diff --git a/app/tests/test_mqtt.py b/app/tests/test_mqtt.py new file mode 100644 index 0000000..7dea973 --- /dev/null +++ b/app/tests/test_mqtt.py @@ -0,0 +1,250 @@ +# test_with_pytest.py +import pytest +import asyncio +import aiomqtt +import logging + +from mock import patch, Mock +from app.src.mqtt import Mqtt +from app.src.modbus import Modbus +from app.src.gen3plus.solarman_v5 import SolarmanV5 +from app.src.config import Config + + +pytest_plugins = ('pytest_asyncio',) + + + +@pytest.fixture(scope="module") +def test_port(): + return 1883 + +@pytest.fixture(scope="module") +def test_hostname(): + # if getenv("GITHUB_ACTIONS") == "true": + # return 'mqtt' + # else: + return 'test.mosquitto.org' + +@pytest.fixture +def config_mqtt_conn(test_hostname, test_port): + Config.act_config = {'mqtt':{'host': test_hostname, 'port': test_port, 'user': '', 'passwd': ''}, + 'ha':{'auto_conf_prefix': 'homeassistant','discovery_prefix': 'homeassistant', 'entity_prefix': 'tsun'} + } + +@pytest.fixture +def config_no_conn(test_port): + Config.act_config = {'mqtt':{'host': "", 'port': test_port, 'user': '', 'passwd': ''}, + 'ha':{'auto_conf_prefix': 'homeassistant','discovery_prefix': 'homeassistant', 'entity_prefix': 'tsun'} + } + +@pytest.fixture +def spy_at_cmd(): + conn = SolarmanV5(server_side=True, client_mode= False) + conn.node_id = 'inv_2/' + with patch.object(conn, 'send_at_cmd', wraps=conn.send_at_cmd) as wrapped_conn: + yield wrapped_conn + conn.close() + +@pytest.fixture +def spy_modbus_cmd(): + conn = SolarmanV5(server_side=True, client_mode= False) + conn.node_id = 'inv_1/' + with patch.object(conn, 'send_modbus_cmd', wraps=conn.send_modbus_cmd) as wrapped_conn: + yield wrapped_conn + conn.close() + +@pytest.fixture +def spy_modbus_cmd_client(): + conn = SolarmanV5(server_side=False, client_mode= False) + conn.node_id = 'inv_1/' + with patch.object(conn, 'send_modbus_cmd', wraps=conn.send_modbus_cmd) as wrapped_conn: + yield wrapped_conn + conn.close() + +def test_native_client(test_hostname, test_port): + """Sanity check: Make sure the paho-mqtt client can connect to the test + MQTT server. + """ + + import paho.mqtt.client as mqtt + import threading + + c = mqtt.Client() + c.loop_start() + try: + # Just make sure the client connects successfully + on_connect = threading.Event() + c.on_connect = Mock(side_effect=lambda *_: on_connect.set()) + c.connect_async(test_hostname, test_port) + assert on_connect.wait(5) + finally: + c.loop_stop() + +@pytest.mark.asyncio +async def test_mqtt_no_config(config_no_conn): + _ = config_no_conn + assert asyncio.get_running_loop() + + on_connect = asyncio.Event() + async def cb(): + on_connect.set() + + try: + m = Mqtt(cb) + assert m.task + await asyncio.sleep(1) + assert not on_connect.is_set() + try: + await m.publish('homeassistant/status', 'online') + assert False + except Exception: + pass + except TimeoutError: + assert False + finally: + await m.close() + +@pytest.mark.asyncio +async def test_mqtt_connection(config_mqtt_conn): + _ = config_mqtt_conn + assert asyncio.get_running_loop() + + on_connect = asyncio.Event() + async def cb(): + on_connect.set() + + try: + m = Mqtt(cb) + assert m.task + assert await asyncio.wait_for(on_connect.wait(), 5) + # await asyncio.sleep(1) + assert 0 == m.ha_restarts + await m.publish('homeassistant/status', 'online') + except TimeoutError: + assert False + finally: + await m.close() + await m.publish('homeassistant/status', 'online') + + +@pytest.mark.asyncio +async def test_msg_dispatch(config_mqtt_conn, spy_modbus_cmd): + _ = config_mqtt_conn + spy = spy_modbus_cmd + try: + m = Mqtt(None) + msg = aiomqtt.Message(topic= 'tsun/inv_1/rated_load', payload= b'2', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_awaited_once_with(Modbus.WRITE_SINGLE_REG, 0x2008, 2, logging.INFO) + + spy.reset_mock() + msg = aiomqtt.Message(topic= 'tsun/inv_1/out_coeff', payload= b'100', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_awaited_once_with(Modbus.WRITE_SINGLE_REG, 0x202c, 1024, logging.INFO) + + spy.reset_mock() + msg = aiomqtt.Message(topic= 'tsun/inv_1/out_coeff', payload= b'50', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_awaited_once_with(Modbus.WRITE_SINGLE_REG, 0x202c, 512, logging.INFO) + + spy.reset_mock() + msg = aiomqtt.Message(topic= 'tsun/inv_1/modbus_read_regs', payload= b'0x3000, 10', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_awaited_once_with(Modbus.READ_REGS, 0x3000, 10, logging.INFO) + + spy.reset_mock() + msg = aiomqtt.Message(topic= 'tsun/inv_1/modbus_read_inputs', payload= b'0x3000, 10', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_awaited_once_with(Modbus.READ_INPUTS, 0x3000, 10, logging.INFO) + + finally: + await m.close() + +@pytest.mark.asyncio +async def test_msg_dispatch_err(config_mqtt_conn, spy_modbus_cmd): + _ = config_mqtt_conn + spy = spy_modbus_cmd + try: + m = Mqtt(None) + # test out of range param + msg = aiomqtt.Message(topic= 'tsun/inv_1/out_coeff', payload= b'-1', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_not_called() + + # test unknown node_id + spy.reset_mock() + msg = aiomqtt.Message(topic= 'tsun/inv_2/out_coeff', payload= b'2', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_not_called() + + # test invalid fload param + spy.reset_mock() + msg = aiomqtt.Message(topic= 'tsun/inv_1/out_coeff', payload= b'2, 3', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_not_called() + + spy.reset_mock() + msg = aiomqtt.Message(topic= 'tsun/inv_1/modbus_read_regs', payload= b'0x3000, 10, 7', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_not_called() + finally: + await m.close() + +@pytest.mark.asyncio +async def test_msg_ignore_client_conn(config_mqtt_conn, spy_modbus_cmd_client): + '''don't call function if connnection is not in server mode''' + _ = config_mqtt_conn + spy = spy_modbus_cmd_client + try: + m = Mqtt(None) + msg = aiomqtt.Message(topic= 'tsun/inv_1/rated_load', payload= b'2', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_not_called() + finally: + await m.close() + +@pytest.mark.asyncio +async def test_ha_reconnect(config_mqtt_conn): + _ = config_mqtt_conn + on_connect = asyncio.Event() + async def cb(): + on_connect.set() + + try: + m = Mqtt(cb) + msg = aiomqtt.Message(topic= 'homeassistant/status', payload= b'offline', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + assert not on_connect.is_set() + + msg = aiomqtt.Message(topic= 'homeassistant/status', payload= b'online', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + assert on_connect.is_set() + + finally: + await m.close() + +@pytest.mark.asyncio +async def test_ignore_unknown_func(config_mqtt_conn): + '''don't dispatch for unknwon function names''' + _ = config_mqtt_conn + try: + m = Mqtt(None) + msg = aiomqtt.Message(topic= 'tsun/inv_1/rated_load', payload= b'2', qos= 0, retain = False, mid= 0, properties= None) + for _ in m.each_inverter(msg, 'unkown_fnc'): + assert False + finally: + await m.close() + +@pytest.mark.asyncio +async def test_at_cmd_dispatch(config_mqtt_conn, spy_at_cmd): + _ = config_mqtt_conn + spy = spy_at_cmd + try: + m = Mqtt(None) + msg = aiomqtt.Message(topic= 'tsun/inv_2/at_cmd', payload= b'AT+', qos= 0, retain = False, mid= 0, properties= None) + await m.dispatch_msg(msg) + spy.assert_awaited_once_with('AT+') + + finally: + await m.close() diff --git a/app/tests/test_singleton.py b/app/tests/test_singleton.py new file mode 100644 index 0000000..2ea82eb --- /dev/null +++ b/app/tests/test_singleton.py @@ -0,0 +1,18 @@ +# test_with_pytest.py +import pytest +from app.src.singleton import Singleton + +class Test(metaclass=Singleton): + def __init__(self): + pass # is a dummy test class + +def test_singleton_metaclass(): + a = Test() + assert 1 == len(Singleton._instances) + b = Test() + assert 1 == len(Singleton._instances) + assert a is b + del a + assert 1 == len(Singleton._instances) + del b + assert 0 == len(Singleton._instances) diff --git a/app/tests/test_solarman.py b/app/tests/test_solarman.py index 66d17f0..c9227bd 100644 --- a/app/tests/test_solarman.py +++ b/app/tests/test_solarman.py @@ -8,7 +8,7 @@ from app.src.gen3plus.solarman_v5 import SolarmanV5 from app.src.config import Config from app.src.infos import Infos, Register from app.src.modbus import Modbus -from app.src.messages import State +from app.src.messages import State, Message pytest_plugins = ('pytest_asyncio',) @@ -773,7 +773,7 @@ def test_invalid_checksum(invalid_checksum, device_ind_msg): m.close() def test_read_message_twice(config_no_tsun_inv1, device_ind_msg, device_rsp_msg): - config_no_tsun_inv1 + _ = config_no_tsun_inv1 m = MemoryStream(device_ind_msg, (0,)) m.append_msg(device_ind_msg) m.read() # read complete msg, and dispatch msg @@ -815,7 +815,7 @@ def test_read_message_in_chunks(device_ind_msg): m.close() def test_read_message_in_chunks2(config_tsun_inv1, device_ind_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(device_ind_msg, (4,10,0)) m.read() # read 4 bytes, header incomplere assert not m.header_valid @@ -840,7 +840,7 @@ def test_read_message_in_chunks2(config_tsun_inv1, device_ind_msg): m.close() def test_read_two_messages(config_tsun_allow_all, device_ind_msg, device_rsp_msg, inverter_ind_msg, inverter_rsp_msg): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(device_ind_msg, (0,)) m.append_msg(inverter_ind_msg) assert 0 == m.sensor_list @@ -869,7 +869,7 @@ def test_read_two_messages(config_tsun_allow_all, device_ind_msg, device_rsp_msg m.close() def test_read_two_messages2(config_tsun_allow_all, inverter_ind_msg, inverter_ind_msg_81, inverter_rsp_msg, inverter_rsp_msg_81): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(inverter_ind_msg, (0,)) m.append_msg(inverter_ind_msg_81) m.read() # read complete msg, and dispatch msg @@ -895,7 +895,7 @@ def test_read_two_messages2(config_tsun_allow_all, inverter_ind_msg, inverter_in m.close() def test_unkown_message(config_tsun_inv1, unknown_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(unknown_msg, (0,)) m.read() # read complete msg, and dispatch msg assert not m.header_valid # must be invalid, since msg was handled and buffer flushed @@ -913,7 +913,7 @@ def test_unkown_message(config_tsun_inv1, unknown_msg): m.close() def test_device_rsp(config_tsun_inv1, device_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(device_rsp_msg, (0,), False) m.read() # read complete msg, and dispatch msg assert not m.header_valid # must be invalid, since msg was handled and buffer flushed @@ -931,7 +931,7 @@ def test_device_rsp(config_tsun_inv1, device_rsp_msg): m.close() def test_inverter_rsp(config_tsun_inv1, inverter_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(inverter_rsp_msg, (0,), False) m.read() # read complete msg, and dispatch msg assert not m.header_valid # must be invalid, since msg was handled and buffer flushed @@ -949,7 +949,7 @@ def test_inverter_rsp(config_tsun_inv1, inverter_rsp_msg): m.close() def test_heartbeat_ind(config_tsun_inv1, heartbeat_ind_msg, heartbeat_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(heartbeat_ind_msg, (0,)) m.read() # read complete msg, and dispatch msg assert not m.header_valid # must be invalid, since msg was handled and buffer flushed @@ -966,7 +966,7 @@ def test_heartbeat_ind(config_tsun_inv1, heartbeat_ind_msg, heartbeat_rsp_msg): m.close() def test_heartbeat_ind2(config_tsun_inv1, heartbeat_ind_msg, heartbeat_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(heartbeat_ind_msg, (0,)) m.no_forwarding = True m.read() # read complete msg, and dispatch msg @@ -984,7 +984,7 @@ def test_heartbeat_ind2(config_tsun_inv1, heartbeat_ind_msg, heartbeat_rsp_msg): m.close() def test_heartbeat_rsp(config_tsun_inv1, heartbeat_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(heartbeat_rsp_msg, (0,), False) m.read() # read complete msg, and dispatch msg assert not m.header_valid # must be invalid, since msg was handled and buffer flushed @@ -1002,7 +1002,7 @@ def test_heartbeat_rsp(config_tsun_inv1, heartbeat_rsp_msg): m.close() def test_sync_start_ind(config_tsun_inv1, sync_start_ind_msg, sync_start_rsp_msg, sync_start_fwd_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(sync_start_ind_msg, (0,)) m.read() # read complete msg, and dispatch msg assert not m.header_valid # must be invalid, since msg was handled and buffer flushed @@ -1025,7 +1025,7 @@ def test_sync_start_ind(config_tsun_inv1, sync_start_ind_msg, sync_start_rsp_msg m.close() def test_sync_start_rsp(config_tsun_inv1, sync_start_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(sync_start_rsp_msg, (0,), False) m.read() # read complete msg, and dispatch msg assert not m.header_valid # must be invalid, since msg was handled and buffer flushed @@ -1043,7 +1043,7 @@ def test_sync_start_rsp(config_tsun_inv1, sync_start_rsp_msg): m.close() def test_sync_end_ind(config_tsun_inv1, sync_end_ind_msg, sync_end_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(sync_end_ind_msg, (0,)) m.read() # read complete msg, and dispatch msg assert not m.header_valid # must be invalid, since msg was handled and buffer flushed @@ -1060,7 +1060,7 @@ def test_sync_end_ind(config_tsun_inv1, sync_end_ind_msg, sync_end_rsp_msg): m.close() def test_sync_end_rsp(config_tsun_inv1, sync_end_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(sync_end_rsp_msg, (0,), False) m.read() # read complete msg, and dispatch msg assert not m.header_valid # must be invalid, since msg was handled and buffer flushed @@ -1078,7 +1078,7 @@ def test_sync_end_rsp(config_tsun_inv1, sync_end_rsp_msg): m.close() def test_build_modell_600(config_tsun_allow_all, inverter_ind_msg): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(inverter_ind_msg, (0,)) assert 0 == m.sensor_list assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0) @@ -1097,7 +1097,7 @@ def test_build_modell_600(config_tsun_allow_all, inverter_ind_msg): m.close() def test_build_modell_1600(config_tsun_allow_all, inverter_ind_msg1600): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(inverter_ind_msg1600, (0,)) assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0) assert None == m.db.get_db_value(Register.RATED_POWER, None) @@ -1109,7 +1109,7 @@ def test_build_modell_1600(config_tsun_allow_all, inverter_ind_msg1600): m.close() def test_build_modell_1800(config_tsun_allow_all, inverter_ind_msg1800): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(inverter_ind_msg1800, (0,)) assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0) assert None == m.db.get_db_value(Register.RATED_POWER, None) @@ -1121,7 +1121,7 @@ def test_build_modell_1800(config_tsun_allow_all, inverter_ind_msg1800): m.close() def test_build_modell_2000(config_tsun_allow_all, inverter_ind_msg2000): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(inverter_ind_msg2000, (0,)) assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0) assert None == m.db.get_db_value(Register.RATED_POWER, None) @@ -1133,7 +1133,7 @@ def test_build_modell_2000(config_tsun_allow_all, inverter_ind_msg2000): m.close() def test_build_modell_800(config_tsun_allow_all, inverter_ind_msg800): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(inverter_ind_msg800, (0,)) assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0) assert None == m.db.get_db_value(Register.RATED_POWER, None) @@ -1145,7 +1145,7 @@ def test_build_modell_800(config_tsun_allow_all, inverter_ind_msg800): m.close() def test_build_logger_modell(config_tsun_allow_all, device_ind_msg): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(device_ind_msg, (0,)) assert 0 == m.db.get_db_value(Register.COLLECTOR_FW_VERSION, 0) assert 'IGEN TECH' == m.db.get_db_value(Register.CHIP_TYPE, None) @@ -1156,6 +1156,7 @@ def test_build_logger_modell(config_tsun_allow_all, device_ind_msg): m.close() def test_msg_iterator(): + Message._registry.clear() m1 = SolarmanV5(server_side=True, client_mode=False) m2 = SolarmanV5(server_side=True, client_mode=False) m3 = SolarmanV5(server_side=True, client_mode=False) @@ -1195,7 +1196,7 @@ def test_proxy_counter(): @pytest.mark.asyncio async def test_msg_build_modbus_req(config_tsun_inv1, device_ind_msg, device_rsp_msg, inverter_ind_msg, inverter_rsp_msg, msg_modbus_cmd): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(device_ind_msg, (0,), True) m.read() assert m.control == 0x4110 @@ -1241,7 +1242,7 @@ async def test_msg_build_modbus_req(config_tsun_inv1, device_ind_msg, device_rsp @pytest.mark.asyncio async def test_at_cmd(config_tsun_allow_all, device_ind_msg, device_rsp_msg, inverter_ind_msg, inverter_rsp_msg, at_command_ind_msg, at_command_rsp_msg): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(device_ind_msg, (0,), True) m.read() # read device ind assert m.control == 0x4110 @@ -1298,7 +1299,7 @@ async def test_at_cmd(config_tsun_allow_all, device_ind_msg, device_rsp_msg, inv @pytest.mark.asyncio async def test_at_cmd_blocked(config_tsun_allow_all, device_ind_msg, device_rsp_msg, inverter_ind_msg, inverter_rsp_msg, at_command_ind_msg): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(device_ind_msg, (0,), True) m.read() assert m.control == 0x4110 @@ -1336,7 +1337,7 @@ async def test_at_cmd_blocked(config_tsun_allow_all, device_ind_msg, device_rsp_ m.close() def test_at_cmd_ind(config_tsun_inv1, at_command_ind_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(at_command_ind_msg, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['AT_Command'] = 0 @@ -1360,7 +1361,7 @@ def test_at_cmd_ind(config_tsun_inv1, at_command_ind_msg): m.close() def test_at_cmd_ind_block(config_tsun_inv1, at_command_ind_msg_block): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(at_command_ind_msg_block, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['AT_Command'] = 0 @@ -1384,7 +1385,7 @@ def test_at_cmd_ind_block(config_tsun_inv1, at_command_ind_msg_block): m.close() def test_msg_at_command_rsp1(config_tsun_inv1, at_command_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(at_command_rsp_msg) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0 @@ -1403,7 +1404,7 @@ def test_msg_at_command_rsp1(config_tsun_inv1, at_command_rsp_msg): m.close() def test_msg_at_command_rsp2(config_tsun_inv1, at_command_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(at_command_rsp_msg) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0 @@ -1422,7 +1423,7 @@ def test_msg_at_command_rsp2(config_tsun_inv1, at_command_rsp_msg): m.close() def test_msg_modbus_req(config_tsun_inv1, msg_modbus_cmd, msg_modbus_cmd_fwd): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(b'') m.snr = get_sn_int() m.sensor_list = 0x2b0 @@ -1450,7 +1451,7 @@ def test_msg_modbus_req(config_tsun_inv1, msg_modbus_cmd, msg_modbus_cmd_fwd): m.close() def test_msg_modbus_req2(config_tsun_inv1, msg_modbus_cmd_crc_err): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(b'') m.snr = get_sn_int() m.state = State.up @@ -1477,7 +1478,7 @@ def test_msg_modbus_req2(config_tsun_inv1, msg_modbus_cmd_crc_err): m.close() def test_msg_unknown_cmd_req(config_tsun_inv1, msg_unknown_cmd): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_unknown_cmd, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['AT_Command'] = 0 @@ -1500,7 +1501,7 @@ def test_msg_unknown_cmd_req(config_tsun_inv1, msg_unknown_cmd): def test_msg_modbus_rsp1(config_tsun_inv1, msg_modbus_rsp): '''Modbus response without a valid Modbus request must be dropped''' - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_modbus_rsp) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0 @@ -1519,7 +1520,7 @@ def test_msg_modbus_rsp1(config_tsun_inv1, msg_modbus_rsp): def test_msg_modbus_rsp2(config_tsun_inv1, msg_modbus_rsp): '''Modbus response with a valid Modbus request must be forwarded''' - config_tsun_inv1 # setup config structure + _ = config_tsun_inv1 # setup config structure m = MemoryStream(msg_modbus_rsp) m.mb.rsp_handler = m._SolarmanV5__forward_msg @@ -1557,7 +1558,7 @@ def test_msg_modbus_rsp2(config_tsun_inv1, msg_modbus_rsp): def test_msg_modbus_rsp3(config_tsun_inv1, msg_modbus_rsp): '''Modbus response with a valid Modbus request must be forwarded''' - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_modbus_rsp) m.mb.rsp_handler = m._SolarmanV5__forward_msg @@ -1593,7 +1594,7 @@ def test_msg_modbus_rsp3(config_tsun_inv1, msg_modbus_rsp): m.close() def test_msg_unknown_rsp(config_tsun_inv1, msg_unknown_cmd_rsp): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_unknown_cmd_rsp) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0 @@ -1611,7 +1612,7 @@ def test_msg_unknown_rsp(config_tsun_inv1, msg_unknown_cmd_rsp): m.close() def test_msg_modbus_invalid(config_tsun_inv1, msg_modbus_invalid): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_modbus_invalid, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0 @@ -1625,7 +1626,7 @@ def test_msg_modbus_invalid(config_tsun_inv1, msg_modbus_invalid): m.close() def test_msg_modbus_fragment(config_tsun_inv1, msg_modbus_rsp): - config_tsun_inv1 + _ = config_tsun_inv1 # receive more bytes than expected (7 bytes from the next msg) m = MemoryStream(msg_modbus_rsp+b'\x00\x00\x00\x45\x10\x52\x31', (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -1651,7 +1652,7 @@ def test_msg_modbus_fragment(config_tsun_inv1, msg_modbus_rsp): @pytest.mark.asyncio async def test_modbus_polling(config_tsun_inv1, heartbeat_ind_msg, heartbeat_rsp_msg): - config_tsun_inv1 + _ = config_tsun_inv1 assert asyncio.get_running_loop() m = MemoryStream(heartbeat_ind_msg, (0,)) assert asyncio.get_running_loop() == m.mb_timer.loop @@ -1692,7 +1693,7 @@ async def test_modbus_polling(config_tsun_inv1, heartbeat_ind_msg, heartbeat_rsp @pytest.mark.asyncio async def test_start_client_mode(config_tsun_inv1): - config_tsun_inv1 + _ = config_tsun_inv1 assert asyncio.get_running_loop() m = MemoryStream(b'') assert m.state == State.init diff --git a/app/tests/test_talent.py b/app/tests/test_talent.py index 5aadf8d..62df532 100644 --- a/app/tests/test_talent.py +++ b/app/tests/test_talent.py @@ -541,7 +541,7 @@ def test_read_message(msg_contact_info): m.close() def test_read_message_twice(config_no_tsun_inv1, msg_inverter_ind): - config_no_tsun_inv1 + _ = config_no_tsun_inv1 m = MemoryStream(msg_inverter_ind, (0,)) m.append_msg(msg_inverter_ind) m.read() # read complete msg, and dispatch msg @@ -622,7 +622,7 @@ def test_read_message_in_chunks2(msg_contact_info): m.close() def test_read_two_messages(config_tsun_allow_all, msg2_contact_info,msg_contact_rsp,msg_contact_rsp2): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(msg2_contact_info, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -652,7 +652,7 @@ def test_read_two_messages(config_tsun_allow_all, msg2_contact_info,msg_contact_ m.close() def test_msg_contact_resp(config_tsun_inv1, msg_contact_rsp): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_contact_rsp, (0,), False) m.await_conn_resp_cnt = 1 m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -672,7 +672,7 @@ def test_msg_contact_resp(config_tsun_inv1, msg_contact_rsp): m.close() def test_msg_contact_resp_2(config_tsun_inv1, msg_contact_rsp): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_contact_rsp, (0,), False) m.await_conn_resp_cnt = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -692,7 +692,7 @@ def test_msg_contact_resp_2(config_tsun_inv1, msg_contact_rsp): m.close() def test_msg_contact_resp_3(config_tsun_inv1, msg_contact_rsp): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_contact_rsp, (0,), True) m.await_conn_resp_cnt = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -712,7 +712,7 @@ def test_msg_contact_resp_3(config_tsun_inv1, msg_contact_rsp): m.close() def test_msg_contact_invalid(config_tsun_inv1, msg_contact_invalid): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_contact_invalid, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -730,7 +730,7 @@ def test_msg_contact_invalid(config_tsun_inv1, msg_contact_invalid): m.close() def test_msg_get_time(config_tsun_inv1, msg_get_time): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_get_time, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -749,7 +749,7 @@ def test_msg_get_time(config_tsun_inv1, msg_get_time): m.close() def test_msg_get_time_autark(config_no_tsun_inv1, msg_get_time): - config_no_tsun_inv1 + _ = config_no_tsun_inv1 m = MemoryStream(msg_get_time, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -768,7 +768,7 @@ def test_msg_get_time_autark(config_no_tsun_inv1, msg_get_time): m.close() def test_msg_time_resp(config_tsun_inv1, msg_time_rsp): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_time_rsp, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -787,7 +787,7 @@ def test_msg_time_resp(config_tsun_inv1, msg_time_rsp): m.close() def test_msg_time_resp_autark(config_no_tsun_inv1, msg_time_rsp): - config_no_tsun_inv1 + _ = config_no_tsun_inv1 m = MemoryStream(msg_time_rsp, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -806,7 +806,7 @@ def test_msg_time_resp_autark(config_no_tsun_inv1, msg_time_rsp): m.close() def test_msg_time_inv_resp(config_tsun_inv1, msg_time_rsp_inv): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_time_rsp_inv, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -825,7 +825,7 @@ def test_msg_time_inv_resp(config_tsun_inv1, msg_time_rsp_inv): m.close() def test_msg_time_invalid(config_tsun_inv1, msg_time_invalid): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_time_invalid, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -844,7 +844,7 @@ def test_msg_time_invalid(config_tsun_inv1, msg_time_invalid): m.close() def test_msg_time_invalid_autark(config_no_tsun_inv1, msg_time_invalid): - config_no_tsun_inv1 + _ = config_no_tsun_inv1 m = MemoryStream(msg_time_invalid, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -863,7 +863,7 @@ def test_msg_time_invalid_autark(config_no_tsun_inv1, msg_time_invalid): m.close() def test_msg_cntrl_ind(config_tsun_inv1, msg_controller_ind, msg_controller_ind_ts_offs, msg_controller_ack): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_controller_ind, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -886,7 +886,7 @@ def test_msg_cntrl_ind(config_tsun_inv1, msg_controller_ind, msg_controller_ind_ m.close() def test_msg_cntrl_ack(config_tsun_inv1, msg_controller_ack): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_controller_ack, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -904,7 +904,7 @@ def test_msg_cntrl_ack(config_tsun_inv1, msg_controller_ack): m.close() def test_msg_cntrl_invalid(config_tsun_inv1, msg_controller_invalid): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_controller_invalid, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -927,7 +927,7 @@ def test_msg_cntrl_invalid(config_tsun_inv1, msg_controller_invalid): m.close() def test_msg_inv_ind(config_tsun_inv1, msg_inverter_ind, msg_inverter_ind_ts_offs, msg_inverter_ack): - config_tsun_inv1 + _ = config_tsun_inv1 tracer.setLevel(logging.DEBUG) m = MemoryStream(msg_inverter_ind, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -951,7 +951,7 @@ def test_msg_inv_ind(config_tsun_inv1, msg_inverter_ind, msg_inverter_ind_ts_off m.close() def test_msg_inv_ind1(config_tsun_inv1, msg_inverter_ind2, msg_inverter_ind_ts_offs, msg_inverter_ack): - config_tsun_inv1 + _ = config_tsun_inv1 tracer.setLevel(logging.DEBUG) m = MemoryStream(msg_inverter_ind2, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -975,7 +975,7 @@ def test_msg_inv_ind1(config_tsun_inv1, msg_inverter_ind2, msg_inverter_ind_ts_o m.close() def test_msg_inv_ind2(config_tsun_inv1, msg_inverter_ind_new, msg_inverter_ind_ts_offs, msg_inverter_ack): - config_tsun_inv1 + _ = config_tsun_inv1 tracer.setLevel(logging.DEBUG) m = MemoryStream(msg_inverter_ind_new, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -1003,7 +1003,7 @@ def test_msg_inv_ind2(config_tsun_inv1, msg_inverter_ind_new, msg_inverter_ind_t def test_msg_inv_ind3(config_tsun_inv1, msg_inverter_ind_0w, msg_inverter_ack): '''test that after close the invert_status will be resetted if the grid power is <2W''' - config_tsun_inv1 + _ = config_tsun_inv1 tracer.setLevel(logging.DEBUG) m = MemoryStream(msg_inverter_ind_0w, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -1030,7 +1030,7 @@ def test_msg_inv_ind3(config_tsun_inv1, msg_inverter_ind_0w, msg_inverter_ack): def test_msg_inv_ack(config_tsun_inv1, msg_inverter_ack): - config_tsun_inv1 + _ = config_tsun_inv1 tracer.setLevel(logging.ERROR) m = MemoryStream(msg_inverter_ack, (0,), False) @@ -1050,7 +1050,7 @@ def test_msg_inv_ack(config_tsun_inv1, msg_inverter_ack): m.close() def test_msg_inv_invalid(config_tsun_inv1, msg_inverter_invalid): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_inverter_invalid, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.read() # read complete msg, and dispatch msg @@ -1073,7 +1073,7 @@ def test_msg_inv_invalid(config_tsun_inv1, msg_inverter_invalid): m.close() def test_msg_ota_req(config_tsun_inv1, msg_ota_req): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_ota_req, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['OTA_Start_Msg'] = 0 @@ -1098,7 +1098,7 @@ def test_msg_ota_req(config_tsun_inv1, msg_ota_req): m.close() def test_msg_ota_ack(config_tsun_inv1, msg_ota_ack): - config_tsun_inv1 + _ = config_tsun_inv1 tracer.setLevel(logging.ERROR) m = MemoryStream(msg_ota_ack, (0,), False) @@ -1125,7 +1125,7 @@ def test_msg_ota_ack(config_tsun_inv1, msg_ota_ack): m.close() def test_msg_ota_invalid(config_tsun_inv1, msg_ota_invalid): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_ota_invalid, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['OTA_Start_Msg'] = 0 @@ -1268,7 +1268,7 @@ def test_proxy_counter(): m.close() def test_msg_modbus_req(config_tsun_inv1, msg_modbus_cmd): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(b'') m.id_str = b"R170000000000001" m.state = State.up @@ -1299,7 +1299,7 @@ def test_msg_modbus_req(config_tsun_inv1, msg_modbus_cmd): m.close() def test_msg_modbus_req2(config_tsun_inv1, msg_modbus_cmd): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(b'') m.id_str = b"R170000000000001" @@ -1329,7 +1329,7 @@ def test_msg_modbus_req2(config_tsun_inv1, msg_modbus_cmd): m.close() def test_msg_modbus_req3(config_tsun_inv1, msg_modbus_cmd_crc_err): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(b'') m.id_str = b"R170000000000001" c = m.createClientStream(msg_modbus_cmd_crc_err) @@ -1358,7 +1358,7 @@ def test_msg_modbus_req3(config_tsun_inv1, msg_modbus_cmd_crc_err): def test_msg_modbus_rsp1(config_tsun_inv1, msg_modbus_rsp): '''Modbus response without a valid Modbus request must be dropped''' - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_modbus_rsp) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0 @@ -1379,7 +1379,7 @@ def test_msg_modbus_rsp1(config_tsun_inv1, msg_modbus_rsp): def test_msg_modbus_cloud_rsp(config_tsun_inv1, msg_modbus_rsp): '''Modbus response from TSUN without a valid Modbus request must be dropped''' - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_modbus_rsp, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Msg'] = 0 @@ -1402,7 +1402,7 @@ def test_msg_modbus_cloud_rsp(config_tsun_inv1, msg_modbus_rsp): def test_msg_modbus_rsp2(config_tsun_inv1, msg_modbus_rsp20): '''Modbus response with a valid Modbus request must be forwarded''' - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_modbus_rsp20) m.append_msg(msg_modbus_rsp20) @@ -1432,7 +1432,7 @@ def test_msg_modbus_rsp2(config_tsun_inv1, msg_modbus_rsp20): def test_msg_modbus_rsp3(config_tsun_inv1, msg_modbus_rsp21): '''Modbus response with a valid Modbus request must be forwarded''' - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_modbus_rsp21) m.append_msg(msg_modbus_rsp21) @@ -1461,7 +1461,7 @@ def test_msg_modbus_rsp3(config_tsun_inv1, msg_modbus_rsp21): m.close() def test_msg_modbus_invalid(config_tsun_inv1, msg_modbus_inv): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(msg_modbus_inv, (0,), False) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0 @@ -1481,7 +1481,7 @@ def test_msg_modbus_invalid(config_tsun_inv1, msg_modbus_inv): m.close() def test_msg_modbus_fragment(config_tsun_inv1, msg_modbus_rsp20): - config_tsun_inv1 + _ = config_tsun_inv1 # receive more bytes than expected (7 bytes from the next msg) m = MemoryStream(msg_modbus_rsp20+b'\x00\x00\x00\x45\x10\x52\x31', (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -1513,7 +1513,7 @@ def test_msg_modbus_fragment(config_tsun_inv1, msg_modbus_rsp20): @pytest.mark.asyncio async def test_msg_build_modbus_req(config_tsun_inv1, msg_modbus_cmd): - config_tsun_inv1 + _ = config_tsun_inv1 m = MemoryStream(b'', (0,), True) m.id_str = b"R170000000000001" await m.send_modbus_cmd(Modbus.WRITE_SINGLE_REG, 0x2008, 0, logging.DEBUG) @@ -1539,7 +1539,7 @@ async def test_msg_build_modbus_req(config_tsun_inv1, msg_modbus_cmd): m.close() def test_modbus_no_polling(config_no_modbus_poll, msg_get_time): - config_no_modbus_poll + _ = config_no_modbus_poll m = MemoryStream(msg_get_time, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.modbus_polling = False @@ -1560,7 +1560,7 @@ def test_modbus_no_polling(config_no_modbus_poll, msg_get_time): @pytest.mark.asyncio async def test_modbus_polling(config_tsun_inv1, msg_inverter_ind): - config_tsun_inv1 + _ = config_tsun_inv1 assert asyncio.get_running_loop() m = MemoryStream(msg_inverter_ind, (0,)) @@ -1600,7 +1600,7 @@ async def test_modbus_polling(config_tsun_inv1, msg_inverter_ind): m.close() def test_broken_recv_buf(config_tsun_allow_all, broken_recv_buf): - config_tsun_allow_all + _ = config_tsun_allow_all m = MemoryStream(broken_recv_buf, (0,)) m.db.stat['proxy']['Unknown_Ctrl'] = 0 assert m.db.stat['proxy']['Invalid_Data_Type'] == 0 diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 0000000..a6797c0 --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1 @@ +-r ./app/requirements-test.txt \ No newline at end of file