async def create(self): properties = self._data.data['properties'] modbus_type = modbus.ModbusType[properties['modbus_type']] if properties['link_type'] == 'TCP': srv = await modbus.create_tcp_server( modbus_type=modbus_type, addr=tcp.Address(properties['tcp_host'], properties['tcp_port']), slave_cb=self._slave_loop, read_cb=self._on_read, write_cb=self._on_write, write_mask_cb=self._on_write_mask) return srv if properties['link_type'] == 'SERIAL': slave = await modbus.create_serial_slave( modbus_type=modbus_type, port=properties['serial_port'], read_cb=self._on_read, write_cb=self._on_write, write_mask_cb=self._on_write_mask, silent_interval=properties['serial_silent_interval']) slave.async_group.spawn(self._slave_loop, slave) return slave raise ValueError('invalid link type')
async def listen( connection_cb: ConnectionCb, addr: Address = Address('0.0.0.0')) -> 'Server': """Create new TPKT listening server""" server = Server() server._connection_cb = connection_cb server._srv = await tcp.listen(server._on_connection, tcp.Address(*addr)) server._addresses = [Address(*i) for i in server._srv.addresses] return server
async def listen( connection_cb: ConnectionCb, addr: Address = Address('0.0.0.0'), interrogate_cb: typing.Optional[InterrogateCb] = None, counter_interrogate_cb: typing. Optional[CounterInterrogateCb] = None, # NOQA command_cb: typing.Optional[CommandCb] = None, response_timeout: float = 15, supervisory_timeout: float = 10, test_timeout: float = 20, send_window_size: int = 12, receive_window_size: int = 8) -> 'Server': """Create new IEC104 slave and listen for incoming connections Args: connection_cb: new connection callback addr: listening socket address interrogate_cb: interrogate callback counter_interrogate_cb: counter interrogate callback command_cb: command callback response_timeout: response timeout (t1) in seconds supervisory_timeout: supervisory timeout (t2) in seconds test_timeout: test timeout (t3) in seconds send_window_size: send window size (k) receive_window_size: receive window size (w) """ server = Server() server._connection_cb = connection_cb server._interrogate_cb = interrogate_cb server._counter_interrogate_cb = counter_interrogate_cb server._command_cb = command_cb server._response_timeout = response_timeout server._supervisory_timeout = supervisory_timeout server._test_timeout = test_timeout server._send_window_size = send_window_size server._receive_window_size = receive_window_size server._srv = await tcp.listen(server._on_connection, tcp.Address(*addr), bind_connections=True) server._addresses = [Address(*i) for i in server._srv.addresses] return server
async def create(self): properties = self._data.data['properties'] modbus_type = modbus.ModbusType[properties['modbus_type']] if properties['link_type'] == 'TCP': self._master = await modbus.create_tcp_master( modbus_type=modbus_type, addr=tcp.Address(properties['tcp_host'], properties['tcp_port'])) return self._master if properties['link_type'] == 'SERIAL': self._master = await modbus.create_serial_master( modbus_type=modbus_type, port=properties['serial_port'], silent_interval=properties['serial_silent_interval']) return self._master raise ValueError('invalid link type')
async def connect(conf: json.Data) -> 'Connection': transport_conf = conf['transport'] modbus_type = modbus.ModbusType[conf['modbus_type']] if transport_conf['type'] == 'TCP': addr = tcp.Address(transport_conf['host'], transport_conf['port']) master = await modbus.create_tcp_master(modbus_type=modbus_type, addr=addr) elif transport_conf['type'] == 'SERIAL': port = transport_conf['port'] baudrate = transport_conf['baudrate'] bytesize = serial.ByteSize[transport_conf['bytesize']] parity = serial.Parity[transport_conf['parity']] stopbits = serial.StopBits[transport_conf['stopbits']] xonxoff = transport_conf['flow_control']['xonxoff'] rtscts = transport_conf['flow_control']['rtscts'] dsrdtr = transport_conf['flow_control']['dsrdtr'] silent_interval = transport_conf['silent_interval'] master = await modbus.create_serial_master( modbus_type=modbus_type, port=port, baudrate=baudrate, bytesize=bytesize, parity=parity, stopbits=stopbits, xonxoff=xonxoff, rtscts=rtscts, dsrdtr=dsrdtr, silent_interval=silent_interval) else: raise ValueError('unsupported link type') conn = Connection() conn._conf = conf conn._master = master conn._request_queue = aio.Queue() conn.async_group.spawn(conn._request_loop) return conn
async def test_example_docs(): addr = tcp.Address('127.0.0.1', util.get_unused_tcp_port()) conn2_future = asyncio.Future() srv = await tcp.listen(conn2_future.set_result, addr) conn1 = await tcp.connect(addr) conn2 = await conn2_future # send from conn1 to conn2 data = b'123' conn1.write(data) result = await conn2.readexactly(len(data)) assert result == data # send from conn2 to conn1 data = b'321' conn2.write(data) result = await conn1.readexactly(len(data)) assert result == data await conn1.async_close() await conn2.async_close() await srv.async_close()
def slave_addr(): return tcp.Address('127.0.0.1', util.get_unused_tcp_port())
async def connect( addr: Address, interrogate_cb: typing.Optional[InterrogateCb] = None, counter_interrogate_cb: typing. Optional[CounterInterrogateCb] = None, # NOQA command_cb: typing.Optional[CommandCb] = None, response_timeout: float = 15, supervisory_timeout: float = 10, test_timeout: float = 20, send_window_size: int = 12, receive_window_size: int = 8) -> 'Connection': """Connect to remote device Args: addr: remote server's address interrogate_cb: interrogate callback counter_interrogate_cb: counter interrogate callback command_cb: command callback response_timeout: response timeout (t1) in seconds supervisory_timeout: supervisory timeout (t2) in seconds test_timeout: test timeout (t3) in seconds send_window_size: send window size (k) receive_window_size: receive window size (w) """ def write_apdu(apdu): _iec104.write_apdu(conn, apdu) async def wait_startdt_con(): while True: apdu = await _iec104.read_apdu(conn) if not isinstance(apdu, _iec104.APDUU): continue if apdu.function == _iec104.ApduFunction.STARTDT_CON: return if apdu.function == _iec104.ApduFunction.TESTFR_ACT: write_apdu(_iec104.APDUU(_iec104.ApduFunction.TESTFR_CON)) conn = await tcp.connect(tcp.Address(*addr)) try: write_apdu(_iec104.APDUU(_iec104.ApduFunction.STARTDT_ACT)) await aio.wait_for(wait_startdt_con(), response_timeout) except Exception: await aio.uncancellable(conn.async_close()) raise transport = _iec104.Transport(conn=conn, always_enabled=True, response_timeout=response_timeout, supervisory_timeout=supervisory_timeout, test_timeout=test_timeout, send_window_size=send_window_size, receive_window_size=receive_window_size) return _create_connection(transport=transport, interrogate_cb=interrogate_cb, counter_interrogate_cb=counter_interrogate_cb, command_cb=command_cb)
async def connect(addr: Address) -> 'Connection': """Create new TPKT connection""" conn = await tcp.connect(tcp.Address(*addr)) return Connection(conn)