Beispiel #1
0
    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')
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
    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')
Beispiel #5
0
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
Beispiel #6
0
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()
Beispiel #7
0
def slave_addr():
    return tcp.Address('127.0.0.1', util.get_unused_tcp_port())
Beispiel #8
0
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)
Beispiel #9
0
async def connect(addr: Address) -> 'Connection':
    """Create new TPKT connection"""
    conn = await tcp.connect(tcp.Address(*addr))
    return Connection(conn)