import sunspec2.modbus.modbus as modbus_client import pytest import socket import serial import sunspec2.tests.mock_socket as MockSocket import sunspec2.tests.mock_port as MockPort def test_modbus_rtu_client(monkeypatch): monkeypatch.setattr(serial, 'Serial', MockPort.mock_port) c = modbus_client.modbus_rtu_client('COMM2') assert c.baudrate == 9600 assert c.parity == "N" assert modbus_client.modbus_rtu_clients['COMM2'] with pytest.raises(modbus_client.ModbusClientError) as exc1: c2 = modbus_client.modbus_rtu_client('COMM2', baudrate=99) assert 'Modbus client baudrate mismatch' in str(exc1.value) with pytest.raises(modbus_client.ModbusClientError) as exc2: c2 = modbus_client.modbus_rtu_client('COMM2', parity='E') assert 'Modbus client parity mismatch' in str(exc2.value) def test_modbus_rtu_client_remove(monkeypatch): monkeypatch.setattr(serial, 'Serial', MockPort.mock_port) c = modbus_client.modbus_rtu_client('COMM2') assert modbus_client.modbus_rtu_clients['COMM2'] modbus_client.modbus_rtu_client_remove('COMM2') assert modbus_client.modbus_rtu_clients.get('COMM2') is None def test___generate_crc16_table(): pass def test_computeCRC(): pass def test_checkCRC(): pass class TestModbusClientRTU: def test___init__(self, monkeypatch): monkeypatch.setattr(serial, 'Serial', MockPort.mock_port) c = modbus_client.ModbusClientRTU(name="COM2") assert c.name == "COM2" assert c.baudrate == 9600 assert c.parity is None assert c.serial is not None assert c.timeout == .5 assert c.write_timeout == .5 assert not c.devices def test_open(self, monkeypatch): monkeypatch.setattr(serial, 'Serial', MockPort.mock_port) c = modbus_client.ModbusClientRTU(name="COM2") c.open() assert c.serial.connected def test_close(self, monkeypatch): monkeypatch.setattr(serial, 'Serial', MockPort.mock_port) c = modbus_client.ModbusClientRTU(name="COM2") c.open() c.close() assert not c.serial.connected def test_add_device(self, monkeypatch): monkeypatch.setattr(serial, 'Serial', MockPort.mock_port) c = modbus_client.ModbusClientRTU(name="COM2") c.add_device(1, "1") assert c.devices.get(1) is not None assert c.devices[1] == "1" def test_remove_device(self, monkeypatch): monkeypatch.setattr(serial, 'Serial', MockPort.mock_port) c = modbus_client.ModbusClientRTU(name="COM2") c.add_device(1, "1") assert c.devices.get(1) is not None assert c.devices[1] == "1" c.remove_device(1) assert c.devices.get(1) is None def test__read(self): pass def test_read(self, monkeypatch): monkeypatch.setattr(serial, 'Serial', MockPort.mock_port) c = modbus_client.ModbusClientRTU(name="COM2") in_buff = [b'\x01\x03\x8cSu', b'nS\x00\x01\x00BSunSpecTest\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TestDevice-1\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00opt_a_b_c\x00' b'\x00\x00\x00\x00\x00\x001.2.3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'sn-123456789\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\xb7d'] check_req = b'\x01\x03\x9c@\x00F\xeb\xbc' c.open() c.serial._set_buffer(in_buff) check_read = in_buff[0] + in_buff[1] assert c.read(1, 40000, 70) == check_read[3:-2] assert c.serial.request[0] == check_req def test__write(self): pass def test_write(self, monkeypatch): monkeypatch.setattr(serial, 'Serial', MockPort.mock_port) c = modbus_client.ModbusClientRTU(name="COM2") c.open() data_to_write = b'v0.0.0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00sn-000\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' buffer = [b'\x01\x10\x9cl\x00', b'\x18.N'] c.serial._set_buffer(buffer) c.write(1, 40044, data_to_write) check_req = b'\x01\x10\x9cl\x00\x180v0.0.0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00sn-000\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\xad\xff' assert c.serial.request[0] == check_req class TestModbusClientTCP: def test___init__(self): c = modbus_client.ModbusClientTCP() assert c.slave_id == 1 assert c.ipaddr == '127.0.0.1' assert c.ipport == 502 assert c.timeout == 2 assert c.ctx is None assert c.trace_func is None assert c.max_count == 125 def test_close(self, monkeypatch): monkeypatch.setattr(socket, 'socket', MockSocket.mock_socket) c = modbus_client.ModbusClientTCP() c.connect() assert c.socket c.disconnect() assert c.socket is None def test_connect(self, monkeypatch): c = modbus_client.ModbusClientTCP() with pytest.raises(Exception) as exc: c.connect() assert 'Connection error' in str(exc.value) monkeypatch.setattr(socket, 'socket', MockSocket.mock_socket) c.connect() assert c.socket is not None assert c.socket.connected is True assert c.socket.ipaddr == '127.0.0.1' assert c.socket.ipport == 502 assert c.socket.timeout == 2 def test_disconnect(self, monkeypatch): monkeypatch.setattr(socket, 'socket', MockSocket.mock_socket) c = modbus_client.ModbusClientTCP() c.connect() assert c.socket c.disconnect() assert c.socket is None def test__read(self, monkeypatch): pass def test_read(self, monkeypatch): c = modbus_client.ModbusClientTCP() monkeypatch.setattr(socket, 'socket', MockSocket.mock_socket) in_buff = [b'\x00\x00\x00\x00\x00\x8f\x01\x03\x8c', b'SunS\x00\x01\x00BSunSpecTest\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00TestDevice-1\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00opt_a_b_c' b'\x00\x00\x00\x00\x00\x00\x001.2.3\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00sn-123456789\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x01\x00\x00'] check_req = b'\x00\x00\x00\x00\x00\x06\x01\x03\x9c@\x00F' c.connect() c.socket._set_buffer(in_buff) assert c.read(40000, 70) == in_buff[1] assert c.socket.request[0] == check_req def test__write(self, monkeypatch): pass def test_write(self, monkeypatch): c = modbus_client.ModbusClientTCP() monkeypatch.setattr(socket, 'socket', MockSocket.mock_socket) c.connect() data_to_write = b'sn-000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' buffer = [b'\x00\x00\x00\x00\x00\x06\x01\x10\x9c', b't\x00\x10'] c.socket._set_buffer(buffer) c.write(40052, data_to_write) check_req = b"\x00\x00\x00\x00\x00'\x01\x10\x9ct\x00\x10 sn-000\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" assert c.socket.request[0] == check_req def test_write_over_max_size(self, monkeypatch): c = modbus_client.ModbusClientTCP() monkeypatch.setattr(socket, 'socket', MockSocket.mock_socket) c.connect() data_to_write = bytearray((c.max_write_count+1)*2) data_to_write[:6] = b'sn-000' buffer = [b'\x00\x00\x00\x00\x00\x06\x01\x10\x9ct\x00\x7b', b'\x00\x00\x00\x00\x00\x06\x01\x10\x9c\xef\x00\x01'] c.socket._set_buffer(buffer) c.write(40052, data_to_write) check_req0 = b"\x00\x00\x00\x00\x00\xfd\x01" + b"\x10\x9ct\x00{\xf6" + data_to_write[:(c.max_write_count*2)] check_req1 = b"\x00\x00\x00\x00\x00\x09\x01" + b"\x10\x9c\xef\x00\x01\x02\x00\x00" assert c.socket.request[0] == check_req0 assert c.socket.request[1] == check_req1