Esempio n. 1
0
    def setUp(self):
        ''' Initializes the test environment '''
        self.client = ClientDecoder()
        self.server = ServerDecoder()
        self.request = (
                (0x01, '\x01\x00\x01\x00\x01'),                       # read coils
                (0x02, '\x02\x00\x01\x00\x01'),                       # read discrete inputs
                (0x03, '\x03\x00\x01\x00\x01'),                       # read holding registers
                (0x04, '\x04\x00\x01\x00\x01'),                       # read input registers
                (0x05, '\x05\x00\x01\x00\x01'),                       # write single coil
                (0x06, '\x06\x00\x01\x00\x01'),                       # write single register
                (0x07, '\x07'),                                       # read exception status
                (0x08, '\x08\x00\x00\x00\x00'),                       # read diagnostic
                (0x0b, '\x0b'),                                       # get comm event counters
                (0x0c, '\x0c'),                                       # get comm event log
                (0x0f, '\x0f\x00\x01\x00\x08\x01\x00\xff'),           # write multiple coils
                (0x10, '\x10\x00\x01\x00\x02\x04\0xff\xff'),          # write multiple registers
                (0x11, '\x11'),                                       # report slave id
                (0x14, '\x14\x0e\x06\x00\x04\x00\x01\x00\x02' \
                       '\x06\x00\x03\x00\x09\x00\x02'),               # read file record
                (0x15, '\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \
                       '\x06\xaf\x04\xbe\x10\x0d'),                   # write file record
                (0x16, '\x16\x00\x01\x00\xff\xff\x00'),               # mask write register
                (0x17, '\x17\x00\x01\x00\x01\x00\x01\x00\x01\x02\x12\x34'),# read/write multiple registers
                (0x18, '\x18\x00\x01'),                               # read fifo queue
                (0x2b, '\x2b\x0e\x01\x00'),                           # read device identification
        )

        self.response = (
                (0x01, '\x01\x01\x01'),                               # read coils
                (0x02, '\x02\x01\x01'),                               # read discrete inputs
                (0x03, '\x03\x02\x01\x01'),                           # read holding registers
                (0x04, '\x04\x02\x01\x01'),                           # read input registers
                (0x05, '\x05\x00\x01\x00\x01'),                       # write single coil
                (0x06, '\x06\x00\x01\x00\x01'),                       # write single register
                (0x07, '\x07\x00'),                                   # read exception status
                (0x08, '\x08\x00\x00\x00\x00'),                       # read diagnostic
                (0x0b, '\x0b\x00\x00\x00\x00'),                       # get comm event counters
                (0x0c, '\x0c\x08\x00\x00\x01\x08\x01\x21\x20\x00'),   # get comm event log
                (0x0f, '\x0f\x00\x01\x00\x08'),                       # write multiple coils
                (0x10, '\x10\x00\x01\x00\x02'),                       # write multiple registers
                (0x11, '\x11\x03\x05\x01\x54'),                       # report slave id (device specific)
                (0x14, '\x14\x0c\x05\x06\x0d\xfe\x00\x20\x05' \
                       '\x06\x33\xcd\x00\x40'),                       # read file record
                (0x15, '\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \
                       '\x06\xaf\x04\xbe\x10\x0d'),                   # write file record
                (0x16, '\x16\x00\x01\x00\xff\xff\x00'),               # mask write register
                (0x17, '\x17\x02\x12\x34'),                           # read/write multiple registers
                (0x18, '\x18\x00\x01\x00\x01\x00\x00'),               # read fifo queue
                (0x2b, '\x2b\x0e\x01\x01\x00\x00\x01\x00\x01\x77'),   # read device identification
        )

        self.bad = (
            (0x80, '\x80\x00\x00\x00'),  # Unknown Function
            (0x81, '\x81\x00\x00\x00'),  # error message
        )
Esempio n. 2
0
 def __init__(self, framer=None, **kwargs):
     self._connected = False
     self.framer = framer or ModbusSocketFramer(ClientDecoder())
     if isinstance(self.framer, type):
         # Framer class not instance
         self.framer = self.framer(ClientDecoder(), client=None)
     if isinstance(self.framer, ModbusSocketFramer):
         self.transaction = DictTransactionManager(self, **kwargs)
     else:
         self.transaction = FifoTransactionManager(self, **kwargs)
Esempio n. 3
0
    def __implementation(method):
        ''' Returns the requested framer

        :method: The serial framer to instantiate
        :returns: The requested serial framer
        '''
        method = method.lower()
        if method == 'ascii': return ModbusAsciiFramer(ClientDecoder())
        elif method == 'rtu': return ModbusRtuFramer(ClientDecoder())
        elif method == 'binary': return ModbusBinaryFramer(ClientDecoder())
        raise ParameterException("Invalid framer method requested")
Esempio n. 4
0
 def _framer(method):
     if method == "ascii":
         framer = ModbusAsciiFramer(ClientDecoder())
     elif method == "rtu":
         framer = ModbusRtuFramer(ClientDecoder())
     elif method == "binary":
         framer = ModbusBinaryFramer(ClientDecoder())
     elif method == "socket":
         framer = ModbusSocketFramer(ClientDecoder())
     else:
         framer = None
     return framer
Esempio n. 5
0
    def __init__(self, framer=None, **kwargs):
        ''' Initializes the framer module

        :param framer: The framer to use for the protocol
        '''
        self._connected = False
        self.framer = framer or ModbusSocketFramer(ClientDecoder())
        if isinstance(self.framer, type):
            # Framer class not instance
            self.framer = self.framer(ClientDecoder(), client=None)
        if isinstance(self.framer, ModbusSocketFramer):
            self.transaction = DictTransactionManager(self, **kwargs)
        else:
            self.transaction = FifoTransactionManager(self, **kwargs)
Esempio n. 6
0
 def __init__(self, client, timeout=2):
     self.client = client
     self.decoder = ClientDecoder()
     self.framer = ModbusSocketFramer(self.decoder, client=self)
     self._ack_waiter: Optional[asyncio.Future[None]] = None
     self.transaction = DictTransactionManager(self)
     self.timeout = timeout
Esempio n. 7
0
    def __init__(self, framer=None):
        ''' Initializes the framer module

        :param framer: The framer to use for the protocol
        '''
        self.framer = framer or ModbusSocketFramer(ClientDecoder())
        self._requests = deque()  # link queue to tid
Esempio n. 8
0
def main():    
    """ The main runner function """
    options = get_options()

    if options.debug:
        try:
            log.setLevel(logging.DEBUG)
            logging.basicConfig()
        except Exception as ex:
            print("Logging is not supported on this system")

    # split the query into a starting and ending range
    query = [int(p) for p in options.query.split(':')]

    try:
        log.debug("Initializing the client")
        framer  = ModbusSocketFramer(ClientDecoder())
        reader  = LoggingContextReader(options.output)
        factory = ScraperFactory(framer, reader, query)

        # how to connect based on TCP vs Serial clients
        if isinstance(framer, ModbusSocketFramer):
            reactor.connectTCP(options.host, options.port, factory)
        else:
            SerialModbusClient(factory, options.port, reactor)

        log.debug("Starting the client")
        reactor.run()
        log.debug("Finished scraping the client")
    except Exception as ex:
        print(ex)
Esempio n. 9
0
    def decode(self, message):
        """ Attempt to decode the supplied message

        :param message: The messge to decode
        """
        if IS_PYTHON3:
            value = message if self.encode else c.encode(message, 'hex_codec')
        else:
            value = message if self.encode else message.encode('hex')
        print("=" * 80)
        print("Decoding Message %s" % value)
        print("=" * 80)
        decoders = [
            self.framer(ServerDecoder(), client=None),
            self.framer(ClientDecoder(), client=None)
        ]
        for decoder in decoders:
            print("%s" % decoder.decoder.__class__.__name__)
            print("-" * 80)
            try:
                decoder.addToFrame(message)
                if decoder.checkFrame():
                    unit = decoder._header.get("uid", 0x00)
                    decoder.advanceFrame()
                    decoder.processIncomingPacket(message, self.report, unit)
                else:
                    self.check_errors(decoder, message)
            except Exception as ex:
                self.check_errors(decoder, message)
Esempio n. 10
0
    def decode(self, message):
        ''' Attempt to decode the supplied message

        :param message: The messge to decode
        '''
        value = message if self.encode else message.encode('hex')
        print("=" * 80)
        print("Decoding Message %s" % value)
        print("=" * 80)
        decoders = [
            self.framer(ServerDecoder()),
            self.framer(ClientDecoder()),
        ]
        for decoder in decoders:
            print("%s" % decoder.decoder.__class__.__name__)
            print("-" * 80)
            try:
                decoder.addToFrame(message.encode())
                if decoder.checkFrame():
                    decoder.advanceFrame()
                    decoder.processIncomingPacket(message, self.report)
                else:
                    self.check_errors(decoder, message)
            except Exception as ex:
                self.check_errors(decoder, message)
Esempio n. 11
0
class ModbusTcpClientProtocol(ModbusClientProtocol):
    """
    Async TCP Client protocol based on twisted.
    
    Default framer: ModbusSocketFramer
    """
    framer = ModbusSocketFramer(ClientDecoder())
Esempio n. 12
0
    def __init__(self, framer=ModbusSocketFramer(ClientDecoder())):
        ''' Initializes the framer module

        :param framer: The framer to use for the protocol
        '''
        self.done = False
        self.framer = framer
Esempio n. 13
0
    def __init__(self, framer=None):
        ''' Initializes the framer module

        :param framer: The framer to use for the protocol
        '''
        self.framer = framer or ModbusSocketFramer(ClientDecoder())
        serial = not isinstance(framer, ModbusSocketFramer)
        self.transaction = ModbusTransactionManager(self, serial)
Esempio n. 14
0
    def __init__(self, factory, *args, **kwargs):
        """ Setup the client and start listening on the serial port

        :param factory: The factory to build clients with
        """
        protocol = factory.buildProtocol(None)
        self.decoder = ClientDecoder()
        serialport.SerialPort.__init__(self, protocol, *args, **kwargs)
Esempio n. 15
0
 def __init__(self, port, baud=9600):
     self.port = port
     self.baud = baud
     self.connection = serial.Serial(
         port,
         baud,
         timeout=float(self.kByteLength * self.kMaxReadSize) / baud)
     self.client_framer = ModbusRtuFramer(decoder=ClientDecoder())
     self.server_framer = ModbusRtuFramer(decoder=ServerDecoder())
Esempio n. 16
0
def main():
    log.debug("Initializing the client")
    framer = ModbusFramer(ClientDecoder(), client=None)
    reader = LoggingLineReader()
    factory = ExampleFactory(framer, reader)
    SerialModbusClient(factory, SERIAL_PORT, reactor)
    # factory = reactor.connectTCP("localhost", 502, factory)
    log.debug("Starting the client")
    reactor.run()
Esempio n. 17
0
    def _framer(cls, method):
        """
        Returns the requested framer

        :method: The serial framer to instantiate
        :returns: The requested serial framer
        """
        method = method.lower()
        if method == 'ascii':
            return ModbusAsciiFramer(ClientDecoder())
        elif method == 'rtu':
            return ModbusRtuFramer(ClientDecoder())
        elif method == 'binary':
            return ModbusBinaryFramer(ClientDecoder())
        elif method == 'socket':
            return ModbusSocketFramer(ClientDecoder())

        raise ParameterException("Invalid framer method requested")
Esempio n. 18
0
        def __init__(self, framer, *args, **kwargs):
            ''' Setup the client and start listening on the serial port

            :param factory: The factory to build clients with
            '''
            self.decoder = ClientDecoder()
            proto_cls = kwargs.pop("proto_cls", None)
            proto = SerialClientFactory(framer, proto_cls).buildProtocol()
            SerialPort.__init__(self, proto, *args, **kwargs)
Esempio n. 19
0
    def setUp(self):
        ''' Initializes the test environment '''
        self.client  = ClientDecoder()
        self.server  = ServerDecoder()
        self.request = (
                (0x01, '\x01\x00\x01\x00\x01'),                       # read coils
                (0x02, '\x02\x00\x01\x00\x01'),                       # read discrete inputs
                (0x03, '\x03\x00\x01\x00\x01'),                       # read holding registers
                (0x04, '\x04\x00\x01\x00\x01'),                       # read input registers
                (0x05, '\x05\x00\x01\x00\x01'),                       # write single coil
                (0x06, '\x06\x00\x01\x00\x01'),                       # write single register
                (0x07, '\x07'),                                       # read exception status
                (0x08, '\x08\x00\x00\x00\x00'),                       # read diagnostic
                (0x0b, '\x0b'),                                       # get comm event counters
                (0x0c, '\x0c'),                                       # get comm event log
                (0x0f, '\x0f\x00\x01\x00\x08\x01\x00\xff'),           # write multiple coils
                (0x10, '\x10\x00\x01\x00\x02\x04\0xff\xff'),          # write multiple registers
                (0x11, '\x11'),                                       # report slave id
                (0x14, '\x14\x0e\x06\x00\x04\x00\x01\x00\x02' \
                       '\x06\x00\x03\x00\x09\x00\x02'),               # read file record
                (0x15, '\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \
                       '\x06\xaf\x04\xbe\x10\x0d'),                   # write file record
                (0x16, '\x16\x00\x01\x00\xff\xff\x00'),               # mask write register
                (0x17, '\x17\x00\x01\x00\x01\x00\x01\x00\x01\x02\x12\x34'),# read/write multiple registers
                (0x18, '\x18\x00\x01'),                               # read fifo queue
                (0x2b, '\x2b\x0e\x01\x00'),                           # read device identification
        )

        self.response = (
                (0x01, '\x01\x01\x01'),                               # read coils
                (0x02, '\x02\x01\x01'),                               # read discrete inputs
                (0x03, '\x03\x02\x01\x01'),                           # read holding registers
                (0x04, '\x04\x02\x01\x01'),                           # read input registers
                (0x05, '\x05\x00\x01\x00\x01'),                       # write single coil
                (0x06, '\x06\x00\x01\x00\x01'),                       # write single register
                (0x07, '\x07\x00'),                                   # read exception status
                (0x08, '\x08\x00\x00\x00\x00'),                       # read diagnostic
                (0x0b, '\x0b\x00\x00\x00\x00'),                       # get comm event counters
                (0x0c, '\x0c\x08\x00\x00\x01\x08\x01\x21\x20\x00'),   # get comm event log
                (0x0f, '\x0f\x00\x01\x00\x08'),                       # write multiple coils
                (0x10, '\x10\x00\x01\x00\x02'),                       # write multiple registers
                (0x11, '\x11\x03\x05\x01\x54'),                       # report slave id (device specific)
                (0x14, '\x14\x0c\x05\x06\x0d\xfe\x00\x20\x05' \
                       '\x06\x33\xcd\x00\x40'),                       # read file record
                (0x15, '\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \
                       '\x06\xaf\x04\xbe\x10\x0d'),                   # write file record
                (0x16, '\x16\x00\x01\x00\xff\xff\x00'),               # mask write register
                (0x17, '\x17\x02\x12\x34'),                           # read/write multiple registers
                (0x18, '\x18\x00\x01\x00\x01\x00\x00'),               # read fifo queue
                (0x2b, '\x2b\x0e\x01\x01\x00\x00\x01\x00\x01\x77'),   # read device identification
        )

        self.bad = (
                (0x80, '\x80\x00\x00\x00'),                           # Unknown Function
                (0x81, '\x81\x00\x00\x00'),                           # error message
        )
Esempio n. 20
0
    def __init__(self, framer=None):
        ''' Initializes the framer module

        :param framer: The framer to use for the protocol
        '''
        self.framer = framer or ModbusSocketFramer(ClientDecoder())
        if isinstance(self.framer, ModbusSocketFramer):
            self.transaction = DictTransactionManager(self)
        else:
            self.transaction = FifoTransactionManager(self)
Esempio n. 21
0
    def __implementation(method):
        """ Returns the requested framer

        :method: The serial framer to instantiate
        :returns: The requested serial framer
        """
        method = method.lower()
        if method == 'rtu':
            return ModbusRtuFramer(ClientDecoder())
        raise ParameterException("Invalid framer method requested")
Esempio n. 22
0
    def __init__(self, host='127.0.0.1', port=Defaults.Port):
        ''' Initialize a client instance

        :param host: The host to connect to (default 127.0.0.1)
        :param port: The modbus port to connect to (default 502)
        '''
        self.host = host
        self.port = port
        self.socket = None
        BaseModbusClient.__init__(self, ModbusSocketFramer(ClientDecoder()))
Esempio n. 23
0
 def testSerialClientConnect(self, mock_serial, mock_seriostream, mock_ioloop):
     """ Test the tornado serial client client connect """
     client = AsyncModbusSerialClient(ioloop=schedulers.IO_LOOP,
                                      framer=ModbusRtuFramer(
                                          ClientDecoder()),
                                      port=SERIAL_PORT)
     self.assertTrue(client.port, SERIAL_PORT)
     self.assertFalse(client._connected)
     client.connect()
     self.assertTrue(client._connected)
     client.close()
Esempio n. 24
0
    def __init__(self, framer=None, **kwargs):
        """ Initializes the framer module

        :param framer: The framer to use for the protocol
        """
        deprecated(self.__class__.__name__)
        self.framer = framer or ModbusSocketFramer(ClientDecoder())
        if isinstance(self.framer, ModbusSocketFramer):
            self.transaction = DictTransactionManager(self, **kwargs)
        else:
            self.transaction = FifoTransactionManager(self, **kwargs)
Esempio n. 25
0
    def __init__(self, framer=None, **kwargs):
        """ Initializes the framer module

        :param framer: The framer to use for the protocol. Default:
        ModbusSocketFramer
        :type framer: pymodbus.transaction.ModbusSocketFramer
        """
        self._connected = False

        super(BaseAsyncModbusClient,
              self).__init__(framer or ModbusSocketFramer(ClientDecoder()),
                             **kwargs)
    def testSerialClientInit(self):
        """ Test the tornado serial client client initialize """
        client = AsyncModbusSerialClient(ioloop=schedulers.IO_LOOP,
                                         framer=ModbusRtuFramer(
                                             ClientDecoder()),
                                         port=SERIAL_PORT)
        self.assertEqual(0, len(list(client.transaction)))
        self.assertTrue(isinstance(client.framer, ModbusRtuFramer))

        framer = object()
        client = AsyncModbusSerialClient(framer=framer)
        self.assertTrue(framer is client.framer)
Esempio n. 27
0
    def testClientProtocolDataReceived(self):
        ''' Test the client protocol data received '''
        protocol = ModbusClientProtocol(ModbusSocketFramer(ClientDecoder()))
        protocol.connectionMade()
        out = []
        data = b'\x00\x00\x12\x34\x00\x06\xff\x01\x01\x02\x00\x04'

        # setup existing request
        d = protocol._buildResponse(0x00)
        d.addCallback(lambda v: out.append(v))

        protocol.dataReceived(data)
        self.assertTrue(isinstance(out[0], ReadCoilsResponse))
Esempio n. 28
0
    def __init__(self,
                 host='127.0.0.1',
                 port=Defaults.Port,
                 framer=ModbusSocketFramer,
                 **kwargs):
        """ Initialize a client instance

        :param host: The host to connect to (default 127.0.0.1)
        :param port: The modbus port to connect to (default 502)
        :param source_address: The source address tuple to bind to (default ('', 0))
        :param timeout: The timeout to use for this socket (default Defaults.Timeout)
        :param framer: The modbus framer to use (default ModbusSocketFramer)

        .. note:: The host argument will accept ipv4 and ipv6 hosts
        """
        self.host = host
        self.port = port
        self.source_address = kwargs.get('source_address', ('', 0))
        self.socket = None
        self.timeout = kwargs.get('timeout', Defaults.Timeout)
        self.transaction_id = kwargs.get('transaction', Defaults.TransactionId)
        self.protocol_id = kwargs.get('protocol', Defaults.ProtocolId)
        self.unit_id = kwargs.get('unit', Defaults.UnitId)
        Defaults.UnitId = 0x05
        self.skip_encode = kwargs.get('skip_encode', False)

        serverCertFile = './servercert.pem'
        serverKeyFile = './serverkey.pem'
        caCertFile = './servercert.pem'
        deviceCertFile = './conf-/devicecert.pem'
        deviceKeyFile = './conf-/devicekey.pem'
        sslIntervalSeconds = 6

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        logger.debug(
            "using caCertFile={0}, deviceCertFile={1}, deviceKeyFile={2}".
            format(caCertFile, deviceCertFile, deviceKeyFile))
        sslSocket = ssl.wrap_socket(sock,
                                    ca_certs=caCertFile,
                                    cert_reqs=ssl.CERT_REQUIRED,
                                    certfile=deviceCertFile,
                                    keyfile=deviceKeyFile,
                                    ssl_version=ssl.PROTOCOL_TLSv1_2,
                                    do_handshake_on_connect=True,
                                    ciphers='ECDHE-RSA-AES256-SHA')

        self.sslSocket = sslSocket

        BaseModbusClient.__init__(self, framer(ClientDecoder(), self),
                                  **kwargs)
Esempio n. 29
0
    def __init__(self, host='127.0.0.1', port=Defaults.Port,
                 framer=ModbusSocketFramer, **kwargs):
        """ Initialize a client instance

        :param host: The host to connect to (default 127.0.0.1)
        :param port: The modbus port to connect to (default 502)
        :param framer: The modbus framer to use (default ModbusSocketFramer)
        :param timeout: The timeout to use for this socket (default None)
        """
        self.host = host
        self.port = port
        self.socket = None
        self.timeout = kwargs.get('timeout', None)
        BaseModbusClient.__init__(self, framer(ClientDecoder(), self), **kwargs)
Esempio n. 30
0
    def testSerialClientExecute(self, mock_serial, mock_seriostream, mock_ioloop):
        """ Test the tornado serial client client execute method """
        client = AsyncModbusSerialClient(ioloop=schedulers.IO_LOOP,
                                         framer=ModbusRtuFramer(
                                             ClientDecoder()),
                                         port=SERIAL_PORT)
        client.connect()
        client.stream = Mock()
        client.stream.write = Mock()

        request = ReadCoilsRequest(1, 1)
        d = client.execute(request)
        tid = request.transaction_id
        self.assertEqual(d, client.transaction.getTransaction(tid))
Esempio n. 31
0
 def testClientProtocolConnectionMade(self, protocol):
     """
     Test the client protocol close
     :return:
     """
     protocol = protocol(ModbusSocketFramer(ClientDecoder()))
     transport = mock.MagicMock()
     factory = mock.MagicMock()
     if isinstance(protocol, ModbusUdpClientProtocol):
         protocol.factory = factory
     protocol.connection_made(transport)
     assert protocol.transport == transport
     assert protocol.connected
     if isinstance(protocol, ModbusUdpClientProtocol):
         assert protocol.factory.protocol_made_connection.call_count == 1
Esempio n. 32
0
class SimpleFactoryTest(unittest.TestCase):
    '''
    This is the unittest for the pymod.exceptions module
    '''

    def setUp(self):
        ''' Initializes the test environment '''
        self.client  = ClientDecoder()
        self.server  = ServerDecoder()
        self.request = (
                (0x01, b'\x01\x00\x01\x00\x01'),                       # read coils
                (0x02, b'\x02\x00\x01\x00\x01'),                       # read discrete inputs
                (0x03, b'\x03\x00\x01\x00\x01'),                       # read holding registers
                (0x04, b'\x04\x00\x01\x00\x01'),                       # read input registers
                (0x05, b'\x05\x00\x01\x00\x01'),                       # write single coil
                (0x06, b'\x06\x00\x01\x00\x01'),                       # write single register
                (0x07, b'\x07'),                                       # read exception status
                (0x08, b'\x08\x00\x00\x00\x00'),                       # read diagnostic
                (0x0b, b'\x0b'),                                       # get comm event counters
                (0x0c, b'\x0c'),                                       # get comm event log
                (0x0f, b'\x0f\x00\x01\x00\x08\x01\x00\xff'),           # write multiple coils
                (0x10, b'\x10\x00\x01\x00\x02\x04\0xff\xff'),          # write multiple registers
                (0x11, b'\x11'),                                       # report slave id
                (0x14, b'\x14\x0e\x06\x00\x04\x00\x01\x00\x02' \
                       b'\x06\x00\x03\x00\x09\x00\x02'),               # read file record
                (0x15, b'\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \
                       b'\x06\xaf\x04\xbe\x10\x0d'),                   # write file record
                (0x16, b'\x16\x00\x01\x00\xff\xff\x00'),               # mask write register
                (0x17, b'\x17\x00\x01\x00\x01\x00\x01\x00\x01\x02\x12\x34'),# read/write multiple registers
                (0x18, b'\x18\x00\x01'),                               # read fifo queue
                (0x2b, b'\x2b\x0e\x01\x00'),                           # read device identification
        )

        self.response = (
                (0x01, b'\x01\x01\x01'),                               # read coils
                (0x02, b'\x02\x01\x01'),                               # read discrete inputs
                (0x03, b'\x03\x02\x01\x01'),                           # read holding registers
                (0x04, b'\x04\x02\x01\x01'),                           # read input registers
                (0x05, b'\x05\x00\x01\x00\x01'),                       # write single coil
                (0x06, b'\x06\x00\x01\x00\x01'),                       # write single register
                (0x07, b'\x07\x00'),                                   # read exception status
                (0x08, b'\x08\x00\x00\x00\x00'),                       # read diagnostic
                (0x0b, b'\x0b\x00\x00\x00\x00'),                       # get comm event counters
                (0x0c, b'\x0c\x08\x00\x00\x01\x08\x01\x21\x20\x00'),   # get comm event log
                (0x0f, b'\x0f\x00\x01\x00\x08'),                       # write multiple coils
                (0x10, b'\x10\x00\x01\x00\x02'),                       # write multiple registers
                (0x11, b'\x11\x03\x05\x01\x54'),                       # report slave id (device specific)
                (0x14, b'\x14\x0c\x05\x06\x0d\xfe\x00\x20\x05' \
                       b'\x06\x33\xcd\x00\x40'),                       # read file record
                (0x15, b'\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \
                       b'\x06\xaf\x04\xbe\x10\x0d'),                   # write file record
                (0x16, b'\x16\x00\x01\x00\xff\xff\x00'),               # mask write register
                (0x17, b'\x17\x02\x12\x34'),                           # read/write multiple registers
                (0x18, b'\x18\x00\x01\x00\x01\x00\x00'),               # read fifo queue
                (0x2b, b'\x2b\x0e\x01\x01\x00\x00\x01\x00\x01\x77'),   # read device identification
        )

        self.exception = (
                (0x81, b'\x81\x01\xd0\x50'),                           # illegal function exception
                (0x82, b'\x82\x02\x90\xa1'),                           # illegal data address exception
                (0x83, b'\x83\x03\x50\xf1'),                           # illegal data value exception
                (0x84, b'\x84\x04\x13\x03'),                           # skave device failure exception
                (0x85, b'\x85\x05\xd3\x53'),                           # acknowledge exception
                (0x86, b'\x86\x06\x93\xa2'),                           # slave device busy exception
                (0x87, b'\x87\x08\x53\xf2'),                           # memory parity exception
                (0x88, b'\x88\x0a\x16\x06'),                           # gateway path unavailable exception
                (0x89, b'\x89\x0b\xd6\x56'),                           # gateway target failed exception
        )

        self.bad = (
                (0x80, b'\x80\x00\x00\x00'),                           # Unknown Function
                (0x81, b'\x81\x00\x00\x00'),                           # error message
        )

    def tearDown(self):
        ''' Cleans up the test environment '''
        del self.bad
        del self.request
        del self.response

    def testExceptionLookup(self):
        ''' Test that we can look up exception messages '''
        for func, _ in self.exception:
            response = self.client.lookupPduClass(func)
            self.assertNotEqual(response, None)

        for func, _ in self.exception:
            response = self.server.lookupPduClass(func)
            self.assertNotEqual(response, None)

    def testResponseLookup(self):
        ''' Test a working response factory lookup '''
        for func, _ in self.response:
            response = self.client.lookupPduClass(func)
            self.assertNotEqual(response, None)

    def testRequestLookup(self):
        ''' Test a working request factory lookup '''
        for func, _ in self.request:
            request = self.client.lookupPduClass(func)
            self.assertNotEqual(request, None)

    def testResponseWorking(self):
        ''' Test a working response factory decoders '''
        for func, msg in self.response:
            try:
                self.client.decode(msg)
            except ModbusException:
                self.fail("Failed to Decode Response Message", func)

    def testResponseErrors(self):
        ''' Test a response factory decoder exceptions '''
        self.assertRaises(ModbusException, self.client._helper, self.bad[0][1])
        self.assertEqual(self.client.decode(self.bad[1][1]).function_code, self.bad[1][0],
                "Failed to decode error PDU")

    def testRequestsWorking(self):
        ''' Test a working request factory decoders '''
        for func, msg in self.request:
            try:
                self.server.decode(msg)
            except ModbusException:
                self.fail("Failed to Decode Request Message", func)

    def testClientFactoryFails(self):
        ''' Tests that a client factory will fail to decode a bad message '''
        self.client._helper = _raise_exception
        actual = self.client.decode(None)
        self.assertEqual(actual, None)

    def testServerFactoryFails(self):
        ''' Tests that a server factory will fail to decode a bad message '''
        self.server._helper = _raise_exception
        actual = self.server.decode(None)
        self.assertEqual(actual, None)

    def testServerRegisterCustomRequest(self):
        class CustomRequest(ModbusRequest):
            function_code = 0xff
        self.server.register(CustomRequest)
        assert self.client.lookupPduClass(CustomRequest.function_code)
        CustomRequest.sub_function_code = 0xff
        self.server.register(CustomRequest)
        assert self.server.lookupPduClass(CustomRequest.function_code)

    def testClientRegisterCustomResponse(self):
        class CustomResponse(ModbusResponse):
            function_code = 0xff
        self.client.register(CustomResponse)
        assert self.client.lookupPduClass(CustomResponse.function_code)
        CustomResponse.sub_function_code = 0xff
        self.client.register(CustomResponse)
        assert self.client.lookupPduClass(CustomResponse.function_code)
#---------------------------------------------------------------------------#
# I don't actually know what is supposed to be returned here, I assume that
# since the high bit is set, it will simply echo the resulting message
#---------------------------------------------------------------------------#
    def testRequestErrors(self):
        ''' Test a request factory decoder exceptions '''
        for func, msg in self.bad:
            result = self.server.decode(msg)
            self.assertEqual(result.ErrorCode, 1,
                    "Failed to decode invalid requests")
            self.assertEqual(result.execute(None).function_code, func,
                    "Failed to create correct response message")
Esempio n. 33
0
    def setUp(self):
        ''' Initializes the test environment '''
        self.client  = ClientDecoder()
        self.server  = ServerDecoder()
        self.request = (
                (0x01, b'\x01\x00\x01\x00\x01'),                       # read coils
                (0x02, b'\x02\x00\x01\x00\x01'),                       # read discrete inputs
                (0x03, b'\x03\x00\x01\x00\x01'),                       # read holding registers
                (0x04, b'\x04\x00\x01\x00\x01'),                       # read input registers
                (0x05, b'\x05\x00\x01\x00\x01'),                       # write single coil
                (0x06, b'\x06\x00\x01\x00\x01'),                       # write single register
                (0x07, b'\x07'),                                       # read exception status
                (0x08, b'\x08\x00\x00\x00\x00'),                       # read diagnostic
                (0x0b, b'\x0b'),                                       # get comm event counters
                (0x0c, b'\x0c'),                                       # get comm event log
                (0x0f, b'\x0f\x00\x01\x00\x08\x01\x00\xff'),           # write multiple coils
                (0x10, b'\x10\x00\x01\x00\x02\x04\0xff\xff'),          # write multiple registers
                (0x11, b'\x11'),                                       # report slave id
                (0x14, b'\x14\x0e\x06\x00\x04\x00\x01\x00\x02' \
                       b'\x06\x00\x03\x00\x09\x00\x02'),               # read file record
                (0x15, b'\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \
                       b'\x06\xaf\x04\xbe\x10\x0d'),                   # write file record
                (0x16, b'\x16\x00\x01\x00\xff\xff\x00'),               # mask write register
                (0x17, b'\x17\x00\x01\x00\x01\x00\x01\x00\x01\x02\x12\x34'),# read/write multiple registers
                (0x18, b'\x18\x00\x01'),                               # read fifo queue
                (0x2b, b'\x2b\x0e\x01\x00'),                           # read device identification
        )

        self.response = (
                (0x01, b'\x01\x01\x01'),                               # read coils
                (0x02, b'\x02\x01\x01'),                               # read discrete inputs
                (0x03, b'\x03\x02\x01\x01'),                           # read holding registers
                (0x04, b'\x04\x02\x01\x01'),                           # read input registers
                (0x05, b'\x05\x00\x01\x00\x01'),                       # write single coil
                (0x06, b'\x06\x00\x01\x00\x01'),                       # write single register
                (0x07, b'\x07\x00'),                                   # read exception status
                (0x08, b'\x08\x00\x00\x00\x00'),                       # read diagnostic
                (0x0b, b'\x0b\x00\x00\x00\x00'),                       # get comm event counters
                (0x0c, b'\x0c\x08\x00\x00\x01\x08\x01\x21\x20\x00'),   # get comm event log
                (0x0f, b'\x0f\x00\x01\x00\x08'),                       # write multiple coils
                (0x10, b'\x10\x00\x01\x00\x02'),                       # write multiple registers
                (0x11, b'\x11\x03\x05\x01\x54'),                       # report slave id (device specific)
                (0x14, b'\x14\x0c\x05\x06\x0d\xfe\x00\x20\x05' \
                       b'\x06\x33\xcd\x00\x40'),                       # read file record
                (0x15, b'\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \
                       b'\x06\xaf\x04\xbe\x10\x0d'),                   # write file record
                (0x16, b'\x16\x00\x01\x00\xff\xff\x00'),               # mask write register
                (0x17, b'\x17\x02\x12\x34'),                           # read/write multiple registers
                (0x18, b'\x18\x00\x01\x00\x01\x00\x00'),               # read fifo queue
                (0x2b, b'\x2b\x0e\x01\x01\x00\x00\x01\x00\x01\x77'),   # read device identification
        )

        self.exception = (
                (0x81, b'\x81\x01\xd0\x50'),                           # illegal function exception
                (0x82, b'\x82\x02\x90\xa1'),                           # illegal data address exception
                (0x83, b'\x83\x03\x50\xf1'),                           # illegal data value exception
                (0x84, b'\x84\x04\x13\x03'),                           # skave device failure exception
                (0x85, b'\x85\x05\xd3\x53'),                           # acknowledge exception
                (0x86, b'\x86\x06\x93\xa2'),                           # slave device busy exception
                (0x87, b'\x87\x08\x53\xf2'),                           # memory parity exception
                (0x88, b'\x88\x0a\x16\x06'),                           # gateway path unavailable exception
                (0x89, b'\x89\x0b\xd6\x56'),                           # gateway target failed exception
        )

        self.bad = (
                (0x80, b'\x80\x00\x00\x00'),                           # Unknown Function
                (0x81, b'\x81\x00\x00\x00'),                           # error message
        )
Esempio n. 34
0
class SimpleFactoryTest(unittest.TestCase):
    '''
    This is the unittest for the pymod.exceptions module
    '''

    def setUp(self):
        ''' Initializes the test environment '''
        self.client  = ClientDecoder()
        self.server  = ServerDecoder()
        self.request = (
                (0x01, '\x01\x00\x01\x00\x01'),                       # read coils
                (0x02, '\x02\x00\x01\x00\x01'),                       # read discrete inputs
                (0x03, '\x03\x00\x01\x00\x01'),                       # read holding registers
                (0x04, '\x04\x00\x01\x00\x01'),                       # read input registers
                (0x05, '\x05\x00\x01\x00\x01'),                       # write single coil
                (0x06, '\x06\x00\x01\x00\x01'),                       # write single register
                (0x07, '\x07'),                                       # read exception status
                (0x08, '\x08\x00\x00\x00\x00'),                       # read diagnostic
                (0x0b, '\x0b'),                                       # get comm event counters
                (0x0c, '\x0c'),                                       # get comm event log
                (0x0f, '\x0f\x00\x01\x00\x08\x01\x00\xff'),           # write multiple coils
                (0x10, '\x10\x00\x01\x00\x02\x04\0xff\xff'),          # write multiple registers
                (0x11, '\x11'),                                       # report slave id
                (0x14, '\x14\x0e\x06\x00\x04\x00\x01\x00\x02' \
                       '\x06\x00\x03\x00\x09\x00\x02'),               # read file record
                (0x15, '\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \
                       '\x06\xaf\x04\xbe\x10\x0d'),                   # write file record
                (0x16, '\x16\x00\x01\x00\xff\xff\x00'),               # mask write register
                (0x17, '\x17\x00\x01\x00\x01\x00\x01\x00\x01\x02\x12\x34'),# read/write multiple registers
                (0x18, '\x18\x00\x01'),                               # read fifo queue
                (0x2b, '\x2b\x0e\x01\x00'),                           # read device identification
        )

        self.response = (
                (0x01, '\x01\x01\x01'),                               # read coils
                (0x02, '\x02\x01\x01'),                               # read discrete inputs
                (0x03, '\x03\x02\x01\x01'),                           # read holding registers
                (0x04, '\x04\x02\x01\x01'),                           # read input registers
                (0x05, '\x05\x00\x01\x00\x01'),                       # write single coil
                (0x06, '\x06\x00\x01\x00\x01'),                       # write single register
                (0x07, '\x07\x00'),                                   # read exception status
                (0x08, '\x08\x00\x00\x00\x00'),                       # read diagnostic
                (0x0b, '\x0b\x00\x00\x00\x00'),                       # get comm event counters
                (0x0c, '\x0c\x08\x00\x00\x01\x08\x01\x21\x20\x00'),   # get comm event log
                (0x0f, '\x0f\x00\x01\x00\x08'),                       # write multiple coils
                (0x10, '\x10\x00\x01\x00\x02'),                       # write multiple registers
                (0x11, '\x11\x03\x05\x01\x54'),                       # report slave id (device specific)
                (0x14, '\x14\x0c\x05\x06\x0d\xfe\x00\x20\x05' \
                       '\x06\x33\xcd\x00\x40'),                       # read file record
                (0x15, '\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \
                       '\x06\xaf\x04\xbe\x10\x0d'),                   # write file record
                (0x16, '\x16\x00\x01\x00\xff\xff\x00'),               # mask write register
                (0x17, '\x17\x02\x12\x34'),                           # read/write multiple registers
                (0x18, '\x18\x00\x01\x00\x01\x00\x00'),               # read fifo queue
                (0x2b, '\x2b\x0e\x01\x01\x00\x00\x01\x00\x01\x77'),   # read device identification
        )

        self.bad = (
                (0x80, '\x80\x00\x00\x00'),                           # Unknown Function
                (0x81, '\x81\x00\x00\x00'),                           # error message
        )

    def tearDown(self):
        ''' Cleans up the test environment '''
        del self.bad
        del self.request
        del self.response

    def testResponseLookup(self):
        ''' Test a working response factory lookup '''
        for func, _ in self.response:
            response = self.client.lookupPduClass(func)
            self.assertNotEqual(response, None)

    def testRequestLookup(self):
        ''' Test a working request factory lookup '''
        for func, _ in self.request:
            request = self.client.lookupPduClass(func)
            self.assertNotEqual(request, None)

    def testResponseWorking(self):
        ''' Test a working response factory decoders '''
        for func, msg in self.response:
            try:
                self.client.decode(msg)
            except ModbusException:
                self.fail("Failed to Decode Response Message", func)

    def testResponseErrors(self):
        ''' Test a response factory decoder exceptions '''
        self.assertRaises(ModbusException, self.client._helper, self.bad[0][1])
        self.assertEqual(self.client.decode(self.bad[1][1]).function_code, self.bad[1][0],
                "Failed to decode error PDU")

    def testRequestsWorking(self):
        ''' Test a working request factory decoders '''
        for func, msg in self.request:
            try:
                self.server.decode(msg)
            except ModbusException:
                self.fail("Failed to Decode Request Message", func)

    def testClientFactoryFails(self):
        ''' Tests that a client factory will fail to decode a bad message '''
        self.client._helper = _raise_exception
        actual = self.client.decode(None)
        self.assertEquals(actual, None)

    def testServerFactoryFails(self):
        ''' Tests that a server factory will fail to decode a bad message '''
        self.server._helper = _raise_exception
        actual = self.server.decode(None)
        self.assertEquals(actual, None)

#---------------------------------------------------------------------------#
# I don't actually know what is supposed to be returned here, I assume that
# since the high bit is set, it will simply echo the resulting message
#---------------------------------------------------------------------------#
    def testRequestErrors(self):
        ''' Test a request factory decoder exceptions '''
        for func, msg in self.bad:
            result = self.server.decode(msg)
            self.assertEqual(result.ErrorCode, 1,
                    "Failed to decode invalid requests")
            self.assertEqual(result.execute(None).function_code, func,
                    "Failed to create correct response message")