Exemple #1
0
    def handle_request(self, request_pdu, broadcast=False):
        """
        parse the request pdu, makes the corresponding action
        and returns the response pdu
        """

        logger.debug("Slave (ID: %d) is handling request" % self._id)

        with self._data_lock:  # thread-safe
            try:
                # get the function code
                (self.function_code, ) = struct.unpack(">B", request_pdu[:1])

                # check if the function code is valid. If not returns error response
                if not self.function_code in self._fn_code_map:
                    raise ModbusError(defines.ILLEGAL_FUNCTION)

                can_broadcast = [
                    defines.WRITE_MULTIPLE_COILS,
                    defines.WRITE_MULTIPLE_REGISTERS,
                    defines.WRITE_SINGLE_COIL,
                    defines.WRITE_SINGLE_REGISTER,
                ]
                if broadcast and (self.function_code not in can_broadcast):
                    raise ModbusInvalidRequestError(
                        "Function %d can not be broadcasted" %
                        self.function_code)

                # execute the corresponding function
                try:
                    response_pdu = self._fn_code_map[self.function_code](
                        request_pdu)
                except struct.error:
                    raise ModbusError(exception_code=3)
                if response_pdu:
                    if broadcast:
                        # not really sure whats going on here - better log it!
                        logger.info("Modbus broadcast: %s" %
                                    (utils.get_log_buffer("!!", response_pdu)))
                        return ""
                    else:
                        return struct.pack(">B",
                                           self.function_code) + response_pdu
                raise Exception("No response for function %d" %
                                self.function_code)

            except ModbusError as e:
                logger.error(
                    "Exception caught: %s. (A proper response will be sent to the peer)",
                    e,
                )
                return struct.pack(">BB", self.function_code + 128,
                                   e.get_exception_code())
Exemple #2
0
def test_raise_modbus_json_rpc_error(modbus_code, json_rpc_exception,
                                     expected):
    func = Mock(side_effect=ModbusError(modbus_code))
    func.__name__ = 'function_name'
    decorated_func = json_rpc_error(func)

    with pytest.raises(json_rpc_exception) as exinfo:
        decorated_func()

    assert str(exinfo.value) == expected
Exemple #3
0
    def handle_request(self, request_pdu, broadcast=False):
        """
        parse the request pdu, makes the corresponding action
        and returns the response pdu
        """
        with self._data_lock:  # thread-safe
            try:
                # get the function code
                (self.function_code, ) = struct.unpack(">B", request_pdu[0])

                # check if the function code is valid. If not returns error response
                if not self.function_code in self._fn_code_map:
                    raise ModbusError(defines.ILLEGAL_FUNCTION)

                # if read query is broadcasted raises an error
                cant_be_broadcasted = (defines.READ_COILS,
                                       defines.READ_DISCRETE_INPUTS,
                                       defines.READ_INPUT_REGISTERS,
                                       defines.READ_HOLDING_REGISTERS)
                if broadcast and (self.function_code in cant_be_broadcasted):
                    raise ModbusInvalidRequestError(
                        "Function %d can not be broadcasted" %
                        self.function_code)

                # execute the corresponding function
                response_pdu = self._fn_code_map[self.function_code](
                    request_pdu)
                if response_pdu:
                    if broadcast:
                        #not really sure whats going on here - better log it!
                        logger.info("broadcast: %s" %
                                    (utils.get_log_buffer("!!", response_pdu)))
                        return ""
                    else:
                        return struct.pack(">B",
                                           self.function_code) + response_pdu
                raise Exception("No response for function %d" %
                                self.function_code)

            except ModbusError as e:
                logger.error(
                    'Exception caught: {0}. (A proper response will be sent to the peer)'
                    .format(e))
                return struct.pack(">BB", self.function_code + 128,
                                   e.get_exception_code())