Esempio n. 1
0
def handle_modbus_request(mqtt_client, userdata, message):
    """Process the modbus request"""
    logging.debug("In handle_modbus_request")
    logging.debug("Payload = %s", message.payload)
    #{
    #   'ModbusHost': modbus.com:5023
    #   'FunctionCode': 5,
    #   'UnitID': 2,
    #   'StartAddress': 2,
    #   'AddressCount': 2,
    #   'Data': [2, 3, 4]
    # }

    logging.debug("message payload = %s", message.payload)
    payload = json.loads(message.payload.replace("'", '"'))

    if validate_modbus_request(mqtt_client, payload):
        modbus_port = payload.get('ModbusPort')
        if modbus_port is None or modbus_port == "":
            logging.info("Modbus port not specified. Defaulting port to %s",
                         Defaults.Port)
            modbus_port = Defaults.Port

        if payload['FunctionCode'] == ModbusFunctionCodes.ReadCoil or \
            payload['FunctionCode'] == ModbusFunctionCodes.ReadDiscreteInput or \
            payload['FunctionCode'] == ModbusFunctionCodes.ReadHoldingRegisters or \
            payload['FunctionCode'] == ModbusFunctionCodes.ReadInputRegisters or \
            payload['FunctionCode'] == ModbusFunctionCodes.WriteSingleCoil or \
            payload['FunctionCode'] == ModbusFunctionCodes.WriteSingleHoldingRegister or \
            payload['FunctionCode'] == ModbusFunctionCodes.WriteMultipleCoils or \
            payload['FunctionCode'] == ModbusFunctionCodes.WriteMultipleHoldingRegisters:

            #Create a Modbus client and send the modbus request
            client = ModbusClient(payload['ModbusHost'], modbus_port)
            client.connect()

            #Send the modbus request
            response = send_modbus_request(client, payload)

            logging.debug("response = %s", response)

            # close the client
            client.close()

            if response is not None and response.get('error') is None:
                # Publish the modbus response
                logging.debug("respData = %s", response)
                mqtt.publish_modbus_response(mqtt_client, CB_CONFIG['adapterTopicRoot'], \
                    create_modbus_response(payload, response))
            else:
                mqtt.publish_modbus_error(mqtt_client, CB_CONFIG['adapterTopicRoot'], \
                    create_modbus_error(payload, response.get('error')))
        else:
            mqtt.publish_modbus_error(mqtt_client, CB_CONFIG['adapterTopicRoot'], \
                create_modbus_error(payload, \
                    "Invalid Modbus function code specified. Unable to process Modbus command."))

    logging.debug("Exit handle_modbus_request")
Esempio n. 2
0
def validate_modbus_request(mqtt_client, payload):
    """Validate the modbus request. Publish any errors if the request is not valid."""
    #{
    #   'ModbusHost': 'localhost',
    #   'ModbusPort': 5023,
    #   'FunctionCode': 5,
    #   'UnitID': 2,
    #   'StartAddress': 2,
    #   'AddressCount': 2,
    #   'Data': [2, 3, 4]
    # }

    logging.debug("In validate_modbus_request")

    #Validate the ModbusHost value
    modbus_host = payload.get('ModbusHost')
    if modbus_host is None or modbus_host == "":
        logging.debug("Invalid ModbusHost")
        mqtt.publish_modbus_error(mqtt_client, CB_CONFIG['adapterTopicRoot'], create_modbus_error(\
            payload, "Modbus host not specified. Unable to process Modbus command."))
        return False

    #Validate the FunctionCode value
    func_code = payload.get('FunctionCode')
    if func_code is None or func_code == "":
        logging.debug("Invalid Modbus FunctionCode")
        mqtt.publish_modbus_error(mqtt_client, CB_CONFIG['adapterTopicRoot'], create_modbus_error(\
            payload, "Modbus function code not specified. Unable to process Modbus command."))
        return False

    #Validate the UnitID value
    unit_id = payload.get('UnitID')
    if unit_id is None or unit_id == "":
        logging.debug("Invalid Modbus UnitID")
        mqtt.publish_modbus_error(mqtt_client, CB_CONFIG['adapterTopicRoot'], create_modbus_error(\
            payload, "Modbus Unit ID not specified. Unable to process Modbus command."))
        return False

    #Validate the StartAddress value
    start_addr = payload.get('StartAddress')
    if start_addr is None or start_addr == "":
        logging.debug("Invalid Modbus StartAddress")
        mqtt.publish_modbus_error(mqtt_client, CB_CONFIG['adapterTopicRoot'], create_modbus_error(\
            payload, "Modbus StartAddress not specified. Unable to process Modbus command."))
        return False

    #Check if a data parameter was specified for write operations
    if payload['FunctionCode'] == ModbusFunctionCodes.WriteSingleCoil or \
        payload['FunctionCode'] == ModbusFunctionCodes.WriteSingleHoldingRegister or \
        payload['FunctionCode'] == ModbusFunctionCodes.WriteMultipleCoils or \
        payload['FunctionCode'] == ModbusFunctionCodes.WriteMultipleHoldingRegisters:

        data = payload.get('Data')
        if data is None or data == "" or len(data) == 0:
            logging.debug("Invalid Modbus Data")
            mqtt.publish_modbus_error(mqtt_client, CB_CONFIG['adapterTopicRoot'], \
                create_modbus_error(\
                payload, "Modbus Data not specified. Unable to process Modbus command."))
            return False
        else:
            # Validate the address count length for the write operations
            # The count length must be specified if the data array length is greater than 1
            addr_count = payload.get('AddressCount')
            if (len(data) > 0 and addr_count != len(data)) or addr_count is None or \
            addr_count == "":
                logging.debug("Invalid Modbus AddressCount")
                mqtt.publish_modbus_error(mqtt_client, CB_CONFIG['adapterTopicRoot'], \
                    create_modbus_error(\
                    payload, "Modbus address count not specified or invalid. \
                        Unable to process Modbus command."                                                          ))
                return False

    logging.debug("Exit validate_modbus_request, returning True")
    return True