All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intelligt.modbus.jlibmodbus.msg.ModbusRequestBuilder Maven / Gradle / Ivy

The newest version!
package com.intelligt.modbus.jlibmodbus.msg;

import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.msg.base.AbstractDataRequest;
import com.intelligt.modbus.jlibmodbus.msg.base.AbstractMultipleRequest;
import com.intelligt.modbus.jlibmodbus.msg.base.ModbusFileRecord;
import com.intelligt.modbus.jlibmodbus.msg.base.ModbusRequest;
import com.intelligt.modbus.jlibmodbus.msg.base.mei.ReadDeviceIdentificationCode;
import com.intelligt.modbus.jlibmodbus.msg.request.*;
import com.intelligt.modbus.jlibmodbus.utils.DiagnosticsSubFunctionCode;

import java.util.Arrays;

/*
 * Copyright (C) 2017 Vladislav Y. Kochedykov
 * [https://github.com/kochedykov/jlibmodbus]
 *
 * This file is part of JLibModbus.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Authors: Vladislav Y. Kochedykov, software engineer.
 * email: [email protected]
 */
public class ModbusRequestBuilder {

    static public ModbusRequestBuilder getInstance() {
        return SingletonHolder.instance;
    }

    private ModbusRequest setBaseParameter(ModbusRequest request, int serverAddress) throws ModbusNumberException {
        request.setServerAddress(serverAddress);
        return request;
    }

    private void setSimpleDataRequestParameters(AbstractDataRequest request, int serverAddress, int startAddress) throws ModbusNumberException {
        request.setServerAddress(serverAddress);
        request.setStartAddress(startAddress);
    }

    private void setMultipleDataRequestParameters(AbstractMultipleRequest request, int serverAddress, int startAddress, int quantity) throws ModbusNumberException {
        setSimpleDataRequestParameters(request, serverAddress, startAddress);
        request.setQuantity(quantity);
    }

    public ModbusRequest buildReadCoils(int serverAddress, int startAddress, int quantity) throws ModbusNumberException {
        ReadCoilsRequest request = new ReadCoilsRequest();
        setMultipleDataRequestParameters(request, serverAddress, startAddress, quantity);
        return request;
    }

    public ModbusRequest buildReadDiscreteInputs(int serverAddress, int startAddress, int quantity) throws ModbusNumberException {
        ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest();
        setMultipleDataRequestParameters(request, serverAddress, startAddress, quantity);
        return request;
    }

    public ModbusRequest buildReadInputRegisters(int serverAddress, int startAddress, int quantity) throws ModbusNumberException {
        ReadInputRegistersRequest request = new ReadInputRegistersRequest();
        setMultipleDataRequestParameters(request, serverAddress, startAddress, quantity);
        return request;
    }

    public ModbusRequest buildReadHoldingRegisters(int serverAddress, int startAddress, int quantity) throws ModbusNumberException {
        ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest();
        setMultipleDataRequestParameters(request, serverAddress, startAddress, quantity);
        return request;
    }

    public ModbusRequest buildReadWriteMultipleRegisters(int serverAddress, int readAddress, int readQuantity, int writeAddress, int[] registers) throws ModbusNumberException {
        ReadWriteMultipleRegistersRequest request = new ReadWriteMultipleRegistersRequest();
        request.setServerAddress(serverAddress);
        request.setReadAddress(readAddress);
        request.setReadQuantity(readQuantity);
        request.setWriteAddress(writeAddress);
        request.setWriteRegisters(registers);
        return request;
    }

    public ModbusRequest buildWriteSingleCoil(int serverAddress, int startAddress, boolean coil) throws ModbusNumberException {
        WriteSingleCoilRequest request = new WriteSingleCoilRequest();
        setSimpleDataRequestParameters(request, serverAddress, startAddress);
        request.setCoil(coil);
        return request;
    }

    public ModbusRequest buildWriteMultipleCoils(int serverAddress, int startAddress, boolean[] coils) throws ModbusNumberException {
        WriteMultipleCoilsRequest request = new WriteMultipleCoilsRequest();
        setSimpleDataRequestParameters(request, serverAddress, startAddress);
        request.setCoils(coils);

        return request;
    }

    public ModbusRequest buildWriteMultipleRegisters(int serverAddress, int startAddress, int[] registers) throws ModbusNumberException {
        WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest();
        setSimpleDataRequestParameters(request, serverAddress, startAddress);
        request.setRegisters(registers);
        return request;
    }

    public ModbusRequest buildWriteMultipleRegisters(int serverAddress, int startAddress, byte[] bytes) throws ModbusNumberException {
        WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest();
        setSimpleDataRequestParameters(request, serverAddress, startAddress);
        request.setBytes(bytes);
        return request;
    }

    public ModbusRequest buildWriteSingleRegister(int serverAddress, int startAddress, int register) throws ModbusNumberException {
        WriteSingleRegisterRequest request = new WriteSingleRegisterRequest();
        setSimpleDataRequestParameters(request, serverAddress, startAddress);
        request.setValue(register);
        return request;
    }

    public ModbusRequest buildMaskWriteRegister(int serverAddress, int startAddress, int and, int or) throws ModbusNumberException {
        MaskWriteRegisterRequest request = new MaskWriteRegisterRequest();
        setSimpleDataRequestParameters(request, serverAddress, startAddress);
        request.setMaskAnd(and);
        request.setMaskOr(or);
        return request;
    }

    public ModbusRequest buildReadExceptionStatus(int serverAddress) throws ModbusNumberException {
        return setBaseParameter(new ReadExceptionStatusRequest(), serverAddress);
    }

    public ModbusRequest buildReportSlaveId(int serverAddress) throws ModbusNumberException {
        return setBaseParameter(new ReportSlaveIdRequest(), serverAddress);
    }

    public ModbusRequest buildGetCommEventCounter(int serverAddress) throws ModbusNumberException {
        return setBaseParameter(new GetCommEventCounterRequest(), serverAddress);
    }

    public ModbusRequest buildGetCommEventLog(int serverAddress) throws ModbusNumberException {
        return setBaseParameter(new GetCommEventLogRequest(), serverAddress);
    }

    public ModbusRequest buildReadFifoQueue(int serverAddress, int fifoPointerAddress) throws ModbusNumberException {
        ReadFifoQueueRequest request = new ReadFifoQueueRequest();
        request.setServerAddress(serverAddress);
        request.setStartAddress(fifoPointerAddress);
        return request;
    }

    public ModbusRequest buildReadFileRecord(int serverAddress, ModbusFileRecord[] records) throws ModbusNumberException {
        ReadFileRecordRequest request = new ReadFileRecordRequest();
        request.setServerAddress(serverAddress);
        request.addFileRecords(Arrays.asList(records));
        return request;
    }

    public ModbusRequest buildWriteFileRecord(int serverAddress, ModbusFileRecord record) throws ModbusNumberException {
        WriteFileRecordRequest request = new WriteFileRecordRequest();
        request.setServerAddress(serverAddress);
        request.setFileRecord(record);
        return request;
    }

    /**
     * The function uses a sub-function code field in the query to define the type of test to
     * be performed. The server echoes both the function code and sub-function code in a normal
     * response. Some of the diagnostics cause data to be returned from the remote device in the
     * data field of a normal response.
     *
     * @param subFunctionCode a sub-function code
     * @param serverAddress   a slave address
     * @param data            request data field
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     * @see DiagnosticsRequest
     * @see DiagnosticsSubFunctionCode
     */
    public ModbusRequest buildDiagnostics(DiagnosticsSubFunctionCode subFunctionCode, int serverAddress, int data) throws ModbusNumberException {
        DiagnosticsRequest request = new DiagnosticsRequest();
        request.setServerAddress(serverAddress);
        request.setSubFunctionCode(subFunctionCode);
        request.setSubFunctionData(data);
        return request;
    }

    /**
     * The data passed in the request data field is to be returned (looped back) in the response. The
     * entire response message should be identical to the request.
     *
     * @param serverAddress a slave address
     * @param queryData     request data field
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildReturnQueryData(int serverAddress, int queryData) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RETURN_QUERY_DATA, serverAddress, queryData);
    }

    /**
     * The remote device serial line port must be initialized and restarted, and all of its
     * communications event counters are cleared. If the port is currently in Listen Only Mode, no
     * response is returned. This function is the only one that brings the port out of Listen Only
     * Mode. If the port is not currently in Listen Only Mode, a normal response is returned. This
     * occurs before the restart is executed.
     * When the remote device receives the request, it attempts a restart and executes its power–up
     * confidence tests. Successful completion of the tests will bring the port online.
     * A request data field contents of FF 00 hex causes the port’s Communications Event Log to be
     * cleared also. Contents of 00 00 leave the log as it was prior to the restart.
     *
     * @param serverAddress a slave address
     * @param clearLog      causes the port’s Communications Event Log to be cleared
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildRestartCommunicationsOption(int serverAddress, boolean clearLog) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RESTART_COMMUNICATIONS_OPTION, serverAddress, clearLog ? DiagnosticsRequest.CLEAR_LOG : 0);
    }

    /**
     * Returns the contents of the remote device’s 16–bit diagnostic register are returned in the response.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildReturnDiagnosticRegister(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RETURN_DIAGNOSTIC_REGISTER, serverAddress, 0);
    }

    /**
     * The character passed in the request data field becomes the end of message delimiter
     * for future messages (replacing the default LF character). This function is useful in cases of a
     * Line Feed is not required at the end of ASCII messages.
     *
     * @param serverAddress a slave address
     * @param delimiter     request data field
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildChangeAsciiInputDelimiter(int serverAddress, int delimiter) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.CHANGE_ASCII_INPUT_DELIMITER, serverAddress, delimiter);
    }

    /**
     * Forces the addressed remote device to its Listen Only Mode for MODBUS communications.
     * This isolates it from the other devices on the network, allowing them to continue
     * communicating without interruption from the addressed remote device. No response is
     * returned.
     * When the remote device enters its Listen Only Mode, all active communication controls are
     * turned off. The Ready watchdog timer is allowed to expire, locking the controls off. While the
     * device is in this mode, any MODBUS messages addressed to it or broadcast are monitored,
     * but no actions will be taken and no responses will be sent.
     * The only function that will be processed after the mode is entered will be the Restart
     * Communications Option function (function code 8, sub-function 1).
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildForceListenOnlyMode(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.FORCE_LISTEN_ONLY_MODE, serverAddress, 0);
    }

    /**
     * The goal is to clear all counters and the diagnostic register. Counters are also cleared upon power–up.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildClearCountersAndDiagnosticRegister(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER, serverAddress, 0);
    }

    /**
     * The response data field returns the quantity of messages that the remote device has detected
     * on the communications system since its last restart, clear counters operation, or power–up.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildReturnBusMessageCount(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RETURN_BUS_MESSAGE_COUNT, serverAddress, 0);
    }

    /**
     * The response data field returns the quantity of CRC errors encountered by the remote device
     * since its last restart, clear counters operation, or power–up.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildReturnBusCommunicationErrorCount(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RETURN_BUS_COMMUNICATION_ERROR_COUNT, serverAddress, 0);
    }

    /**
     * The response data field returns the quantity of MODBUS exception responses returned by the
     * remote device since its last restart, clear counters operation, or power–up.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildReturnBusExceptionErrorCount(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RETURN_BUS_EXCEPTION_ERROR_COUNT, serverAddress, 0);
    }

    /**
     * The response data field returns the quantity of messages addressed to the remote device, or
     * broadcast, that the remote device has processed since its last restart, clear counters
     * operation, or power–up.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildReturnSlaveMessageCount(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RETURN_SLAVE_MESSAGE_COUNT, serverAddress, 0);
    }

    /**
     * The response data field returns the quantity of messages addressed to the remote device for
     * which it has returned no response (neither a normal response nor an exception response),
     * since its last restart, clear counters operation, or power–up.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildReturnSlaveNoResponseCount(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RETURN_SLAVE_NO_RESPONSE_COUNT, serverAddress, 0);
    }

    /**
     * The response data field returns the quantity of messages addressed to the remote device for
     * which it returned a Negative Acknowledge (NAK) exception response, since its last restart,
     * clear counters operation, or power–up.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildReturnSlaveNAKCount(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RETURN_SLAVE_NAK_COUNT, serverAddress, 0);
    }

    /**
     * The response data field returns the quantity of messages addressed to the remote device for
     * which it returned a Slave Device Busy exception response, since its last restart, clear
     * counters operation, or power–up.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildReturnSlaveBusyCount(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RETURN_SLAVE_BUSY_COUNT, serverAddress, 0);
    }

    /**
     * The response data field returns the quantity of messages addressed to the remote device that
     * it could not handle due to a character overrun condition, since its last restart, clear counters
     * operation, or power–up. A character overrun is caused by data characters arriving at the port
     * faster than they can be stored, or by the loss of a character due to a hardware malfunction.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildReturnBusCharacterOverrunCount(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.RETURN_BUS_CHARACTER_OVERRUN_COUNT, serverAddress, 0);
    }

    /**
     * Clears the overrun error counter and reset the error flag.
     *
     * @param serverAddress a slave address
     * @return DiagnosticsRequest instance
     * @throws ModbusNumberException if server address is in-valid
     */
    public ModbusRequest buildClearOverrunCounterAndFlag(int serverAddress) throws ModbusNumberException {
        return buildDiagnostics(DiagnosticsSubFunctionCode.CLEAR_OVERRUN_COUNTER_AND_FLAG, serverAddress, 0);
    }

    public ModbusRequest buildReadDeviceIdentification(int serverAddress, int objectId, ReadDeviceIdentificationCode readDeviceId) throws ModbusNumberException {
        ReadDeviceIdentificationRequest request = new ReadDeviceIdentificationRequest();
        request.setServerAddress(serverAddress);
        request.setObjectId(objectId);
        request.setReadDeviceId(readDeviceId);
        return request;
    }

    static private class SingletonHolder {
        final static private ModbusRequestBuilder instance = new ModbusRequestBuilder();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy