Sonar qube 3 (#166)

* add unittests for mqtt.py

* add mock

* move test requirements into a file

* fix unit tests

* fix formating

* initial version

* fix SonarQube warning
This commit is contained in:
Stefan Allius
2024-08-23 00:26:01 +02:00
committed by GitHub
parent 54de2aecfe
commit 27045cac6e
10 changed files with 451 additions and 160 deletions

View File

@@ -36,6 +36,15 @@ jobs:
timezoneLinux: "Europe/Berlin" timezoneLinux: "Europe/Berlin"
timezoneMacos: "Europe/Berlin" timezoneMacos: "Europe/Berlin"
timezoneWindows: "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 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
@@ -46,7 +55,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip 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 if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8 - name: Lint with flake8
run: | run: |

View File

@@ -0,0 +1,6 @@
flake8
pytest
pytest-asyncio
pytest-cov
mock
coverage

View File

@@ -177,7 +177,7 @@ class Talent(Message):
return return
self.__build_header(0x70, 0x77) 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 += struct.pack('!B', len(modbus_pdu))
self._send_buffer += modbus_pdu self._send_buffer += modbus_pdu
self.__finish_send_msg() self.__finish_send_msg()

View File

@@ -2,10 +2,16 @@ import asyncio
import logging import logging
import aiomqtt import aiomqtt
import traceback import traceback
from modbus import Modbus if __name__ == "app.src.mqtt":
from messages import Message from app.src.modbus import Modbus
from config import Config from app.src.messages import Message
from singleton import Singleton 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') logger_mqtt = logging.getLogger('mqtt')
@@ -22,6 +28,14 @@ class Mqtt(metaclass=Singleton):
self.task = loop.create_task(self.__loop()) self.task = loop.create_task(self.__loop())
self.ha_restarts = 0 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 @property
def ha_restarts(self): def ha_restarts(self):
return self._ha_restarts return self._ha_restarts
@@ -49,7 +63,6 @@ class Mqtt(metaclass=Singleton):
async def __loop(self) -> None: async def __loop(self) -> None:
mqtt = Config.get('mqtt') mqtt = Config.get('mqtt')
ha = Config.get('ha')
logger_mqtt.info(f'start MQTT: host:{mqtt["host"]} port:' logger_mqtt.info(f'start MQTT: host:{mqtt["host"]} port:'
f'{mqtt["port"]} ' f'{mqtt["port"]} '
f'user:{mqtt["user"]}') f'user:{mqtt["user"]}')
@@ -59,12 +72,6 @@ class Mqtt(metaclass=Singleton):
password=mqtt['passwd']) password=mqtt['passwd'])
interval = 5 # Seconds 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: while True:
try: try:
@@ -74,51 +81,15 @@ class Mqtt(metaclass=Singleton):
if self.__cb_mqtt_is_up: if self.__cb_mqtt_is_up:
await self.__cb_mqtt_is_up() await self.__cb_mqtt_is_up()
# async with self.__client.messages() as messages: await self.__client.subscribe(self.ha_status_topic)
await self.__client.subscribe(ha_status_topic) await self.__client.subscribe(self.mb_rated_topic)
await self.__client.subscribe(mb_rated_topic) await self.__client.subscribe(self.mb_out_coeff_topic)
await self.__client.subscribe(mb_out_coeff_topic) await self.__client.subscribe(self.mb_reads_topic)
await self.__client.subscribe(mb_reads_topic) await self.__client.subscribe(self.mb_inputs_topic)
await self.__client.subscribe(mb_inputs_topic) await self.__client.subscribe(self.mb_at_cmd_topic)
await self.__client.subscribe(mb_at_cmd_topic)
async for message in self.__client.messages: async for message in self.__client.messages:
if message.topic.matches(ha_status_topic): await self.dispatch_msg(message)
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)
except aiomqtt.MqttError: except aiomqtt.MqttError:
if Config.is_default('mqtt'): if Config.is_default('mqtt'):
@@ -142,46 +113,76 @@ class Mqtt(metaclass=Singleton):
f"Exception:\n" f"Exception:\n"
f"{traceback.format_exc()}") 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): def each_inverter(self, message, func_name: str):
topic = str(message.topic) topic = str(message.topic)
node_id = topic.split('/')[1] + '/' node_id = topic.split('/')[1] + '/'
found = False
for m in Message: for m in Message:
if m.server_side and (m.node_id == node_id): if m.server_side and (m.node_id == node_id):
found = True
logger_mqtt.debug(f'Found: {node_id}') logger_mqtt.debug(f'Found: {node_id}')
fnc = getattr(m, func_name, None) fnc = getattr(m, func_name, None)
if callable(fnc): if callable(fnc):
yield fnc yield fnc
else: else:
logger_mqtt.warning(f'Cmd not supported by: {node_id}') 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') logger_mqtt.warning(f'Node_id: {node_id} not found')
async def modbus_cmd(self, message, func, params=0, addr=0, val=0): 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") payload = message.payload.decode("UTF-8")
logger_mqtt.info(f'MODBUS via MQTT: {topic} = {payload}') for fnc in self.each_inverter(message, "send_modbus_cmd"):
for m in Message: res = payload.split(',')
if m.server_side and (m.node_id == node_id): if params > 0 and params != len(res):
logger_mqtt.debug(f'Found: {node_id}') logger_mqtt.error(f'Parameter expected: {params}, '
fnc = getattr(m, "send_modbus_cmd", None) f'got: {len(res)}')
res = payload.split(',') return
if params > 0 and params != len(res): if params == 1:
logger_mqtt.error(f'Parameter expected: {params}, ' val = int(payload)
f'got: {len(res)}') elif params == 2:
return addr = int(res[0], base=16)
val = int(res[1]) # lenght
if callable(fnc): await fnc(func, addr, val, logging.INFO)
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): async def at_cmd(self, message):
payload = message.payload.decode("UTF-8") payload = message.payload.decode("UTF-8")

View File

@@ -1,9 +1,14 @@
from weakref import WeakValueDictionary
class Singleton(type): class Singleton(type):
_instances = {} _instances = WeakValueDictionary()
def __call__(cls, *args, **kwargs): def __call__(cls, *args, **kwargs):
# logger_mqtt.debug('singleton: __call__') # logger_mqtt.debug('singleton: __call__')
if cls not in cls._instances: if cls not in cls._instances:
cls._instances[cls] = super(Singleton, instance = super(Singleton,
cls).__call__(*args, **kwargs) cls).__call__(*args, **kwargs)
cls._instances[cls] = instance
return cls._instances[cls] return cls._instances[cls]

250
app/tests/test_mqtt.py Normal file
View File

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

View File

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

View File

@@ -8,7 +8,7 @@ from app.src.gen3plus.solarman_v5 import SolarmanV5
from app.src.config import Config from app.src.config import Config
from app.src.infos import Infos, Register from app.src.infos import Infos, Register
from app.src.modbus import Modbus from app.src.modbus import Modbus
from app.src.messages import State from app.src.messages import State, Message
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)
@@ -773,7 +773,7 @@ def test_invalid_checksum(invalid_checksum, device_ind_msg):
m.close() m.close()
def test_read_message_twice(config_no_tsun_inv1, device_ind_msg, device_rsp_msg): 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 = MemoryStream(device_ind_msg, (0,))
m.append_msg(device_ind_msg) m.append_msg(device_ind_msg)
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
@@ -815,7 +815,7 @@ def test_read_message_in_chunks(device_ind_msg):
m.close() m.close()
def test_read_message_in_chunks2(config_tsun_inv1, device_ind_msg): 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 = MemoryStream(device_ind_msg, (4,10,0))
m.read() # read 4 bytes, header incomplere m.read() # read 4 bytes, header incomplere
assert not m.header_valid assert not m.header_valid
@@ -840,7 +840,7 @@ def test_read_message_in_chunks2(config_tsun_inv1, device_ind_msg):
m.close() m.close()
def test_read_two_messages(config_tsun_allow_all, device_ind_msg, device_rsp_msg, inverter_ind_msg, inverter_rsp_msg): 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 = MemoryStream(device_ind_msg, (0,))
m.append_msg(inverter_ind_msg) m.append_msg(inverter_ind_msg)
assert 0 == m.sensor_list 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() 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): 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 = MemoryStream(inverter_ind_msg, (0,))
m.append_msg(inverter_ind_msg_81) m.append_msg(inverter_ind_msg_81)
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_unkown_message(config_tsun_inv1, unknown_msg): def test_unkown_message(config_tsun_inv1, unknown_msg):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(unknown_msg, (0,)) m = MemoryStream(unknown_msg, (0,))
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed 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() m.close()
def test_device_rsp(config_tsun_inv1, device_rsp_msg): def test_device_rsp(config_tsun_inv1, device_rsp_msg):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(device_rsp_msg, (0,), False) m = MemoryStream(device_rsp_msg, (0,), False)
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed 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() m.close()
def test_inverter_rsp(config_tsun_inv1, inverter_rsp_msg): def test_inverter_rsp(config_tsun_inv1, inverter_rsp_msg):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(inverter_rsp_msg, (0,), False) m = MemoryStream(inverter_rsp_msg, (0,), False)
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed 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() m.close()
def test_heartbeat_ind(config_tsun_inv1, heartbeat_ind_msg, heartbeat_rsp_msg): 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 = MemoryStream(heartbeat_ind_msg, (0,))
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed 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() m.close()
def test_heartbeat_ind2(config_tsun_inv1, heartbeat_ind_msg, heartbeat_rsp_msg): 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 = MemoryStream(heartbeat_ind_msg, (0,))
m.no_forwarding = True m.no_forwarding = True
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_heartbeat_rsp(config_tsun_inv1, heartbeat_rsp_msg): def test_heartbeat_rsp(config_tsun_inv1, heartbeat_rsp_msg):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(heartbeat_rsp_msg, (0,), False) m = MemoryStream(heartbeat_rsp_msg, (0,), False)
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed 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() m.close()
def test_sync_start_ind(config_tsun_inv1, sync_start_ind_msg, sync_start_rsp_msg, sync_start_fwd_msg): 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 = MemoryStream(sync_start_ind_msg, (0,))
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed 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() m.close()
def test_sync_start_rsp(config_tsun_inv1, sync_start_rsp_msg): 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 = MemoryStream(sync_start_rsp_msg, (0,), False)
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed 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() m.close()
def test_sync_end_ind(config_tsun_inv1, sync_end_ind_msg, sync_end_rsp_msg): 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 = MemoryStream(sync_end_ind_msg, (0,))
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed 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() m.close()
def test_sync_end_rsp(config_tsun_inv1, sync_end_rsp_msg): 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 = MemoryStream(sync_end_rsp_msg, (0,), False)
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed 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() m.close()
def test_build_modell_600(config_tsun_allow_all, inverter_ind_msg): 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,)) m = MemoryStream(inverter_ind_msg, (0,))
assert 0 == m.sensor_list assert 0 == m.sensor_list
assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0) 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() m.close()
def test_build_modell_1600(config_tsun_allow_all, inverter_ind_msg1600): 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,)) m = MemoryStream(inverter_ind_msg1600, (0,))
assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0) assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0)
assert None == m.db.get_db_value(Register.RATED_POWER, None) 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() m.close()
def test_build_modell_1800(config_tsun_allow_all, inverter_ind_msg1800): 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,)) m = MemoryStream(inverter_ind_msg1800, (0,))
assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0) assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0)
assert None == m.db.get_db_value(Register.RATED_POWER, None) 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() m.close()
def test_build_modell_2000(config_tsun_allow_all, inverter_ind_msg2000): 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,)) m = MemoryStream(inverter_ind_msg2000, (0,))
assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0) assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0)
assert None == m.db.get_db_value(Register.RATED_POWER, None) 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() m.close()
def test_build_modell_800(config_tsun_allow_all, inverter_ind_msg800): 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,)) m = MemoryStream(inverter_ind_msg800, (0,))
assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0) assert 0 == m.db.get_db_value(Register.MAX_DESIGNED_POWER, 0)
assert None == m.db.get_db_value(Register.RATED_POWER, None) 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() m.close()
def test_build_logger_modell(config_tsun_allow_all, device_ind_msg): 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,)) m = MemoryStream(device_ind_msg, (0,))
assert 0 == m.db.get_db_value(Register.COLLECTOR_FW_VERSION, 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) 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() m.close()
def test_msg_iterator(): def test_msg_iterator():
Message._registry.clear()
m1 = SolarmanV5(server_side=True, client_mode=False) m1 = SolarmanV5(server_side=True, client_mode=False)
m2 = SolarmanV5(server_side=True, client_mode=False) m2 = SolarmanV5(server_side=True, client_mode=False)
m3 = 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 @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): 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 = MemoryStream(device_ind_msg, (0,), True)
m.read() m.read()
assert m.control == 0x4110 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 @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): 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 = MemoryStream(device_ind_msg, (0,), True)
m.read() # read device ind m.read() # read device ind
assert m.control == 0x4110 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 @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): 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 = MemoryStream(device_ind_msg, (0,), True)
m.read() m.read()
assert m.control == 0x4110 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() m.close()
def test_at_cmd_ind(config_tsun_inv1, at_command_ind_msg): 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 = MemoryStream(at_command_ind_msg, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['AT_Command'] = 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() m.close()
def test_at_cmd_ind_block(config_tsun_inv1, at_command_ind_msg_block): 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 = MemoryStream(at_command_ind_msg_block, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['AT_Command'] = 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() m.close()
def test_msg_at_command_rsp1(config_tsun_inv1, at_command_rsp_msg): 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 = MemoryStream(at_command_rsp_msg)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['Modbus_Command'] = 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() m.close()
def test_msg_at_command_rsp2(config_tsun_inv1, at_command_rsp_msg): 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 = MemoryStream(at_command_rsp_msg)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['Modbus_Command'] = 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() m.close()
def test_msg_modbus_req(config_tsun_inv1, msg_modbus_cmd, msg_modbus_cmd_fwd): 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 = MemoryStream(b'')
m.snr = get_sn_int() m.snr = get_sn_int()
m.sensor_list = 0x2b0 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() m.close()
def test_msg_modbus_req2(config_tsun_inv1, msg_modbus_cmd_crc_err): def test_msg_modbus_req2(config_tsun_inv1, msg_modbus_cmd_crc_err):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(b'') m = MemoryStream(b'')
m.snr = get_sn_int() m.snr = get_sn_int()
m.state = State.up m.state = State.up
@@ -1477,7 +1478,7 @@ def test_msg_modbus_req2(config_tsun_inv1, msg_modbus_cmd_crc_err):
m.close() m.close()
def test_msg_unknown_cmd_req(config_tsun_inv1, msg_unknown_cmd): 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 = MemoryStream(msg_unknown_cmd, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['AT_Command'] = 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): def test_msg_modbus_rsp1(config_tsun_inv1, msg_modbus_rsp):
'''Modbus response without a valid Modbus request must be dropped''' '''Modbus response without a valid Modbus request must be dropped'''
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(msg_modbus_rsp) m = MemoryStream(msg_modbus_rsp)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['Modbus_Command'] = 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): def test_msg_modbus_rsp2(config_tsun_inv1, msg_modbus_rsp):
'''Modbus response with a valid Modbus request must be forwarded''' '''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 = MemoryStream(msg_modbus_rsp)
m.mb.rsp_handler = m._SolarmanV5__forward_msg 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): def test_msg_modbus_rsp3(config_tsun_inv1, msg_modbus_rsp):
'''Modbus response with a valid Modbus request must be forwarded''' '''Modbus response with a valid Modbus request must be forwarded'''
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(msg_modbus_rsp) m = MemoryStream(msg_modbus_rsp)
m.mb.rsp_handler = m._SolarmanV5__forward_msg 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() m.close()
def test_msg_unknown_rsp(config_tsun_inv1, msg_unknown_cmd_rsp): 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 = MemoryStream(msg_unknown_cmd_rsp)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['Modbus_Command'] = 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() m.close()
def test_msg_modbus_invalid(config_tsun_inv1, msg_modbus_invalid): 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 = MemoryStream(msg_modbus_invalid, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['Modbus_Command'] = 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() m.close()
def test_msg_modbus_fragment(config_tsun_inv1, msg_modbus_rsp): 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) # 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 = MemoryStream(msg_modbus_rsp+b'\x00\x00\x00\x45\x10\x52\x31', (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 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 @pytest.mark.asyncio
async def test_modbus_polling(config_tsun_inv1, heartbeat_ind_msg, heartbeat_rsp_msg): 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() assert asyncio.get_running_loop()
m = MemoryStream(heartbeat_ind_msg, (0,)) m = MemoryStream(heartbeat_ind_msg, (0,))
assert asyncio.get_running_loop() == m.mb_timer.loop 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 @pytest.mark.asyncio
async def test_start_client_mode(config_tsun_inv1): async def test_start_client_mode(config_tsun_inv1):
config_tsun_inv1 _ = config_tsun_inv1
assert asyncio.get_running_loop() assert asyncio.get_running_loop()
m = MemoryStream(b'') m = MemoryStream(b'')
assert m.state == State.init assert m.state == State.init

View File

@@ -541,7 +541,7 @@ def test_read_message(msg_contact_info):
m.close() m.close()
def test_read_message_twice(config_no_tsun_inv1, msg_inverter_ind): 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 = MemoryStream(msg_inverter_ind, (0,))
m.append_msg(msg_inverter_ind) m.append_msg(msg_inverter_ind)
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
@@ -622,7 +622,7 @@ def test_read_message_in_chunks2(msg_contact_info):
m.close() m.close()
def test_read_two_messages(config_tsun_allow_all, msg2_contact_info,msg_contact_rsp,msg_contact_rsp2): 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 = MemoryStream(msg2_contact_info, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_contact_resp(config_tsun_inv1, msg_contact_rsp): 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 = MemoryStream(msg_contact_rsp, (0,), False)
m.await_conn_resp_cnt = 1 m.await_conn_resp_cnt = 1
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
@@ -672,7 +672,7 @@ def test_msg_contact_resp(config_tsun_inv1, msg_contact_rsp):
m.close() m.close()
def test_msg_contact_resp_2(config_tsun_inv1, msg_contact_rsp): 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 = MemoryStream(msg_contact_rsp, (0,), False)
m.await_conn_resp_cnt = 0 m.await_conn_resp_cnt = 0
m.db.stat['proxy']['Unknown_Ctrl'] = 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() m.close()
def test_msg_contact_resp_3(config_tsun_inv1, msg_contact_rsp): 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 = MemoryStream(msg_contact_rsp, (0,), True)
m.await_conn_resp_cnt = 0 m.await_conn_resp_cnt = 0
m.db.stat['proxy']['Unknown_Ctrl'] = 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() m.close()
def test_msg_contact_invalid(config_tsun_inv1, msg_contact_invalid): def test_msg_contact_invalid(config_tsun_inv1, msg_contact_invalid):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(msg_contact_invalid, (0,)) m = MemoryStream(msg_contact_invalid, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_get_time(config_tsun_inv1, msg_get_time): def test_msg_get_time(config_tsun_inv1, msg_get_time):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(msg_get_time, (0,)) m = MemoryStream(msg_get_time, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_get_time_autark(config_no_tsun_inv1, msg_get_time): 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 = MemoryStream(msg_get_time, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_time_resp(config_tsun_inv1, msg_time_rsp): 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 = MemoryStream(msg_time_rsp, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_time_resp_autark(config_no_tsun_inv1, msg_time_rsp): 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 = MemoryStream(msg_time_rsp, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_time_inv_resp(config_tsun_inv1, msg_time_rsp_inv): 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 = MemoryStream(msg_time_rsp_inv, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_time_invalid(config_tsun_inv1, msg_time_invalid): 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 = MemoryStream(msg_time_invalid, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_time_invalid_autark(config_no_tsun_inv1, msg_time_invalid): 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 = MemoryStream(msg_time_invalid, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_cntrl_ind(config_tsun_inv1, msg_controller_ind, msg_controller_ind_ts_offs, msg_controller_ack): 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 = MemoryStream(msg_controller_ind, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_cntrl_ack(config_tsun_inv1, msg_controller_ack): 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 = MemoryStream(msg_controller_ack, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_cntrl_invalid(config_tsun_inv1, msg_controller_invalid): def test_msg_cntrl_invalid(config_tsun_inv1, msg_controller_invalid):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(msg_controller_invalid, (0,)) m = MemoryStream(msg_controller_invalid, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_inv_ind(config_tsun_inv1, msg_inverter_ind, msg_inverter_ind_ts_offs, msg_inverter_ack): 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) tracer.setLevel(logging.DEBUG)
m = MemoryStream(msg_inverter_ind, (0,)) m = MemoryStream(msg_inverter_ind, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 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() m.close()
def test_msg_inv_ind1(config_tsun_inv1, msg_inverter_ind2, msg_inverter_ind_ts_offs, msg_inverter_ack): 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) tracer.setLevel(logging.DEBUG)
m = MemoryStream(msg_inverter_ind2, (0,)) m = MemoryStream(msg_inverter_ind2, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 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() m.close()
def test_msg_inv_ind2(config_tsun_inv1, msg_inverter_ind_new, msg_inverter_ind_ts_offs, msg_inverter_ack): 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) tracer.setLevel(logging.DEBUG)
m = MemoryStream(msg_inverter_ind_new, (0,)) m = MemoryStream(msg_inverter_ind_new, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 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): 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''' '''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) tracer.setLevel(logging.DEBUG)
m = MemoryStream(msg_inverter_ind_0w, (0,)) m = MemoryStream(msg_inverter_ind_0w, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 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): def test_msg_inv_ack(config_tsun_inv1, msg_inverter_ack):
config_tsun_inv1 _ = config_tsun_inv1
tracer.setLevel(logging.ERROR) tracer.setLevel(logging.ERROR)
m = MemoryStream(msg_inverter_ack, (0,), False) m = MemoryStream(msg_inverter_ack, (0,), False)
@@ -1050,7 +1050,7 @@ def test_msg_inv_ack(config_tsun_inv1, msg_inverter_ack):
m.close() m.close()
def test_msg_inv_invalid(config_tsun_inv1, msg_inverter_invalid): 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 = MemoryStream(msg_inverter_invalid, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.read() # read complete msg, and dispatch msg 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() m.close()
def test_msg_ota_req(config_tsun_inv1, msg_ota_req): 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 = MemoryStream(msg_ota_req, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['OTA_Start_Msg'] = 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() m.close()
def test_msg_ota_ack(config_tsun_inv1, msg_ota_ack): def test_msg_ota_ack(config_tsun_inv1, msg_ota_ack):
config_tsun_inv1 _ = config_tsun_inv1
tracer.setLevel(logging.ERROR) tracer.setLevel(logging.ERROR)
m = MemoryStream(msg_ota_ack, (0,), False) m = MemoryStream(msg_ota_ack, (0,), False)
@@ -1125,7 +1125,7 @@ def test_msg_ota_ack(config_tsun_inv1, msg_ota_ack):
m.close() m.close()
def test_msg_ota_invalid(config_tsun_inv1, msg_ota_invalid): 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 = MemoryStream(msg_ota_invalid, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['OTA_Start_Msg'] = 0 m.db.stat['proxy']['OTA_Start_Msg'] = 0
@@ -1268,7 +1268,7 @@ def test_proxy_counter():
m.close() m.close()
def test_msg_modbus_req(config_tsun_inv1, msg_modbus_cmd): def test_msg_modbus_req(config_tsun_inv1, msg_modbus_cmd):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(b'') m = MemoryStream(b'')
m.id_str = b"R170000000000001" m.id_str = b"R170000000000001"
m.state = State.up m.state = State.up
@@ -1299,7 +1299,7 @@ def test_msg_modbus_req(config_tsun_inv1, msg_modbus_cmd):
m.close() m.close()
def test_msg_modbus_req2(config_tsun_inv1, msg_modbus_cmd): def test_msg_modbus_req2(config_tsun_inv1, msg_modbus_cmd):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(b'') m = MemoryStream(b'')
m.id_str = b"R170000000000001" m.id_str = b"R170000000000001"
@@ -1329,7 +1329,7 @@ def test_msg_modbus_req2(config_tsun_inv1, msg_modbus_cmd):
m.close() m.close()
def test_msg_modbus_req3(config_tsun_inv1, msg_modbus_cmd_crc_err): def test_msg_modbus_req3(config_tsun_inv1, msg_modbus_cmd_crc_err):
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(b'') m = MemoryStream(b'')
m.id_str = b"R170000000000001" m.id_str = b"R170000000000001"
c = m.createClientStream(msg_modbus_cmd_crc_err) 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): def test_msg_modbus_rsp1(config_tsun_inv1, msg_modbus_rsp):
'''Modbus response without a valid Modbus request must be dropped''' '''Modbus response without a valid Modbus request must be dropped'''
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(msg_modbus_rsp) m = MemoryStream(msg_modbus_rsp)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['Modbus_Command'] = 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): def test_msg_modbus_cloud_rsp(config_tsun_inv1, msg_modbus_rsp):
'''Modbus response from TSUN without a valid Modbus request must be dropped''' '''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 = MemoryStream(msg_modbus_rsp, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['Unknown_Msg'] = 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): def test_msg_modbus_rsp2(config_tsun_inv1, msg_modbus_rsp20):
'''Modbus response with a valid Modbus request must be forwarded''' '''Modbus response with a valid Modbus request must be forwarded'''
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(msg_modbus_rsp20) m = MemoryStream(msg_modbus_rsp20)
m.append_msg(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): def test_msg_modbus_rsp3(config_tsun_inv1, msg_modbus_rsp21):
'''Modbus response with a valid Modbus request must be forwarded''' '''Modbus response with a valid Modbus request must be forwarded'''
config_tsun_inv1 _ = config_tsun_inv1
m = MemoryStream(msg_modbus_rsp21) m = MemoryStream(msg_modbus_rsp21)
m.append_msg(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() m.close()
def test_msg_modbus_invalid(config_tsun_inv1, msg_modbus_inv): 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 = MemoryStream(msg_modbus_inv, (0,), False)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['Modbus_Command'] = 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() m.close()
def test_msg_modbus_fragment(config_tsun_inv1, msg_modbus_rsp20): 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) # 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 = MemoryStream(msg_modbus_rsp20+b'\x00\x00\x00\x45\x10\x52\x31', (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 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 @pytest.mark.asyncio
async def test_msg_build_modbus_req(config_tsun_inv1, msg_modbus_cmd): 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 = MemoryStream(b'', (0,), True)
m.id_str = b"R170000000000001" m.id_str = b"R170000000000001"
await m.send_modbus_cmd(Modbus.WRITE_SINGLE_REG, 0x2008, 0, logging.DEBUG) 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() m.close()
def test_modbus_no_polling(config_no_modbus_poll, msg_get_time): 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 = MemoryStream(msg_get_time, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.modbus_polling = False m.modbus_polling = False
@@ -1560,7 +1560,7 @@ def test_modbus_no_polling(config_no_modbus_poll, msg_get_time):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_modbus_polling(config_tsun_inv1, msg_inverter_ind): async def test_modbus_polling(config_tsun_inv1, msg_inverter_ind):
config_tsun_inv1 _ = config_tsun_inv1
assert asyncio.get_running_loop() assert asyncio.get_running_loop()
m = MemoryStream(msg_inverter_ind, (0,)) m = MemoryStream(msg_inverter_ind, (0,))
@@ -1600,7 +1600,7 @@ async def test_modbus_polling(config_tsun_inv1, msg_inverter_ind):
m.close() m.close()
def test_broken_recv_buf(config_tsun_allow_all, broken_recv_buf): 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 = MemoryStream(broken_recv_buf, (0,))
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
assert m.db.stat['proxy']['Invalid_Data_Type'] == 0 assert m.db.stat['proxy']['Invalid_Data_Type'] == 0

1
requirements-test.txt Normal file
View File

@@ -0,0 +1 @@
-r ./app/requirements-test.txt