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

com.invertor.modbus.ModbusMaster Maven / Gradle / Ivy

There is a newer version: 1.2.9.0
Show newest version
package com.invertor.modbus;

import com.invertor.modbus.data.CommStatus;
import com.invertor.modbus.exception.ModbusIOException;
import com.invertor.modbus.exception.ModbusNumberException;
import com.invertor.modbus.exception.ModbusProtocolException;
import com.invertor.modbus.msg.ModbusRequestFactory;
import com.invertor.modbus.msg.base.ModbusFileRecord;
import com.invertor.modbus.msg.base.ModbusMessage;
import com.invertor.modbus.msg.base.ModbusRequest;
import com.invertor.modbus.msg.base.ModbusResponse;
import com.invertor.modbus.msg.base.mei.MEIReadDeviceIdentification;
import com.invertor.modbus.msg.base.mei.ReadDeviceIdentificationCode;
import com.invertor.modbus.msg.response.*;
import com.invertor.modbus.net.ModbusConnection;
import com.invertor.modbus.net.transport.ModbusTransport;
import com.invertor.modbus.utils.ModbusExceptionCode;

/*
 * Copyright (C) 2016 "Invertor" Factory", JSC
 * [http://www.sbp-invertor.ru]
 *
 * 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]
 */
abstract public class ModbusMaster {

    final protected ModbusRequestFactory requestFactory = ModbusRequestFactory.getInstance();
    private int transactionId = 0;
    private long requestTime = 0;
    private boolean connected = false;

    protected ModbusMaster() {

    }

    public int getTransactionId() {
        return transactionId;
    }

    public void setTransactionId(int transactionId) {
        this.transactionId = Math.min(Math.abs(transactionId), Modbus.TRANSACTION_ID_MAX_VALUE);
    }

    abstract protected ModbusConnection getConnection();

    /**
     * this method allows you to implement your own behavior of connect method.
     *
     * @throws ModbusIOException
     */
    protected void connectImpl() throws ModbusIOException {
        getConnection().open();
    }

    /**
     * this method allows you to implement your own behavior of disconnect method.
     *
     * @throws ModbusIOException
     */
    protected void disconnectImpl() throws ModbusIOException {
        getConnection().close();
    }

    final public void connect() throws ModbusIOException {
        if (!isConnected()) {
            connectImpl();
            setConnected(true);
        }
    }

    final public void disconnect() throws ModbusIOException {
        if (isConnected()) {
            disconnectImpl();
            setConnected(false);
        }
    }

    public boolean isConnected() {
        return connected;
    }

    protected void setConnected(boolean connected) {
        this.connected = connected;
    }

    protected void sendRequest(ModbusMessage msg) throws ModbusIOException {
        ModbusTransport transport = getConnection().getTransport();
        if (transport == null)
            throw new ModbusIOException("transport is null");
        transport.send(msg);
        requestTime = System.currentTimeMillis();
    }

    protected ModbusMessage readResponse() throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
        return getConnection().getTransport().readResponse();
    }

    /**
     * this function allows you to process your own ModbusRequest.
     * Each request class has a compliant response class for instance ReadHoldingRegistersRequest and ReadHoldingRegistersResponse.
     * If you process an instance of ReadHoldingRegistersRequest this function exactly either returns a ReadHoldingRegistersResponse instance or throws an exception.
     *
     * @param request an instance of ModbusRequest.
     * @return an instance of ModbusResponse.
     * @throws ModbusProtocolException if
     * @throws ModbusNumberException
     * @throws ModbusIOException
     * @see ModbusRequestFactory
     * @see ModbusRequest
     * @see ModbusResponse
     * @see com.invertor.modbus.msg.response
     * @see com.invertor.modbus.msg.request
     */
    public ModbusResponse processRequest(ModbusRequest request) throws ModbusProtocolException,
            ModbusNumberException, ModbusIOException {
        sendRequest(request);
        ModbusResponse msg;
        do {
            try {
                msg = (ModbusResponse) readResponse();
                request.validateResponse(msg);
                /*
                 * if you have received an ACKNOWLEDGE,
                 * it means that operation is in processing and you should be waiting for the answer
                 */
                if (msg.getModbusExceptionCode() != ModbusExceptionCode.ACKNOWLEDGE) {
                    if (msg.isException())
                        throw new ModbusProtocolException(msg.getModbusExceptionCode());
                    return msg;
                }
            } catch (ModbusNumberException mne) {
                Modbus.log().warning(mne.getLocalizedMessage());
            }
        } while (System.currentTimeMillis() - requestTime < getConnection().getReadTimeout());
        /*
         * throw an exception if there is a response timeout
         */
        throw new ModbusIOException("Response timeout.");
    }

    /**
     * ModbusMaster will block for only this amount of time.
     * If the timeout expires, a ModbusTransportException is raised, though the ModbusMaster is still valid.
     *
     * @param timeout the specified timeout, in milliseconds.
     */
    public void setResponseTimeout(int timeout) {
        try {
            getConnection().setReadTimeout(timeout);
        } catch (Exception e) {
            Modbus.log().warning(e.getLocalizedMessage());
        }
    }

    /**
     * This function code is used to read the contents of a contiguous block of holding registers in a
     * remote device. The Request PDU specifies the starting register address and the number of
     * registers. In the PDU Registers are addressed starting at zero. Therefore registers numbered
     * 1-16 are addressed as 0-15.
     *
     * @param serverAddress a slave address
     * @param startAddress  starting register address
     * @param quantity      the number of registers
     * @return the register data
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public int[] readHoldingRegisters(int serverAddress, int startAddress, int quantity) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        ModbusRequest request = requestFactory.createReadHoldingRegisters(serverAddress, startAddress, quantity);
        ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) processRequest(request);
        return response.getRegisters();
    }

    /**
     * This function code is used to read from 1 to 125 contiguous input registers in a remote
     * device. The Request PDU specifies the starting register address and the number of registers.
     * In the PDU Registers are addressed starting at zero. Therefore input registers numbered 1-16
     * are addressed as 0-15.
     *
     * @param serverAddress a slave address
     * @param startAddress  starting register address
     * @param quantity      the number of registers
     * @return the register data
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public int[] readInputRegisters(int serverAddress, int startAddress, int quantity) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        ModbusRequest request = requestFactory.createReadInputRegisters(serverAddress, startAddress, quantity);
        ReadHoldingRegistersResponse response = (ReadInputRegistersResponse) processRequest(request);
        return response.getRegisters();
    }

    /**
     * This function code is used to read from 1 to 2000 contiguous status of coils in a remote
     * device. The Request PDU specifies the starting address, i.e. the address of the first coil
     * specified, and the number of coils. In the PDU Coils are addressed starting at zero. Therefore
     * coils numbered 1-16 are addressed as 0-15.
     * If the returned output quantity is not a multiple of eight, the remaining coils in the final boolean array
     * will be padded with FALSE.
     *
     * @param serverAddress a slave address
     * @param startAddress  the address of the first coil
     * @param quantity      the number of coils
     * @return the coils
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public boolean[] readCoils(int serverAddress, int startAddress, int quantity) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        ModbusRequest request = requestFactory.createReadCoils(serverAddress, startAddress, quantity);
        ReadCoilsResponse response = (ReadCoilsResponse) processRequest(request);
        return response.getCoils();
    }

    /**
     * This function code is used to read from 1 to 2000 contiguous status of discrete inputs in a
     * remote device. The Request PDU specifies the starting address, i.e. the address of the first
     * input specified, and the number of inputs. In the PDU Discrete Inputs are addressed starting
     * at zero. Therefore Discrete inputs numbered 1-16 are addressed as 0-15.
     * If the returned input quantity is not a multiple of eight, the remaining inputs in the final boolean array
     * will be padded with FALSE.
     *
     * @param serverAddress a slave address
     * @param startAddress  the address of the first input
     * @param quantity      the number of inputs
     * @return the discrete inputs
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public boolean[] readDiscreteInputs(int serverAddress, int startAddress, int quantity) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        ModbusRequest request = requestFactory.createReadDiscreteInputs(serverAddress, startAddress, quantity);
        ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) processRequest(request);
        return response.getCoils();
    }

    /**
     * This function code is used to write a single output to either ON or OFF in a remote device.
     * The requested ON/OFF state is specified by a constant in the request data field. A value of
     * TRUE requests the output to be ON. A value of FALSE requests it to be OFF.
     * The Request PDU specifies the address of the coil to be forced. Coils are addressed starting
     * at zero. Therefore coil numbered 1 is addressed as 0.
     *
     * @param serverAddress a slave address
     * @param startAddress  the address of the coil to be forced
     * @param flag          the request data field
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public void writeSingleCoil(int serverAddress, int startAddress, boolean flag) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        processRequest(requestFactory.createWriteSingleCoil(serverAddress, startAddress, flag));
    }

    /**
     * This function code is used to write a single holding register in a remote device.
     * The Request PDU specifies the address of the register to be written. Registers are addressed
     * starting at zero. Therefore register numbered 1 is addressed as 0.
     *
     * @param serverAddress a slave address
     * @param startAddress  the address of the register to be written
     * @param register      value
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public void writeSingleRegister(int serverAddress, int startAddress, int register) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        processRequest(requestFactory.createWriteSingleRegister(serverAddress, startAddress, register));
    }

    /**
     * This function code is used to force each coil in a sequence of coils to either ON or OFF in a
     * remote device. The Request PDU specifies the coil references to be forced. Coils are
     * addressed starting at zero. Therefore coil numbered 1 is addressed as 0.
     * The requested ON/OFF states are specified by contents of the request array of boolean. A logical 'true'
     * in position of the array requests the corresponding output to be ON. A logical 'false' requests
     * it to be OFF.
     *
     * @param serverAddress a slave address
     * @param startAddress  the address of the coils to be written
     * @param coils         the coils
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public void writeMultipleCoils(int serverAddress, int startAddress, boolean[] coils) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        processRequest(requestFactory.createWriteMultipleCoils(serverAddress, startAddress, coils));
    }

    /**
     * This function code is used to write a block of contiguous registers (1 to 123 registers) in a
     * remote device.
     * The requested written values are specified in the request data field. Data is packed as two
     * bytes per register.
     *
     * @param serverAddress a slave address
     * @param startAddress  the address of the registers to be written
     * @param registers     the register data
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public void writeMultipleRegisters(int serverAddress, int startAddress, int[] registers) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        processRequest(requestFactory.createWriteMultipleRegisters(serverAddress, startAddress, registers));
    }

    /**
     * This function code performs a combination of one read operation and one write operation in a
     * single MODBUS transaction. The write operation is performed before the read.
     * Holding registers are addressed starting at zero. Therefore holding registers 1-16 are
     * addressed in the PDU as 0-15.
     * The request specifies the starting address and number of holding registers to be read as well
     * as the starting address, number of holding registers, and the data to be written.
     *
     * @param serverAddress a slave address
     * @param readAddress   the address of the registers to be read
     * @param readQuantity  the number of registers to be read
     * @param writeAddress  the address of the registers to be written
     * @param registers     the number of registers to be written
     * @return the register value
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public int[] readWriteMultipleRegisters(int serverAddress, int readAddress, int readQuantity, int writeAddress, int[] registers) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        ModbusRequest request = requestFactory.createReadWriteMultipleRegisters(serverAddress, readAddress, readQuantity, writeAddress, registers);
        ReadWriteMultipleRegistersResponse response = (ReadWriteMultipleRegistersResponse) processRequest(request);
        return response.getRegisters();
    }

    /**
     * This function code allows to read the contents of a First-In-First-Out (FIFO) queue of register
     * in a remote device. The function returns the queued data.
     * Up to 31 queue data registers can be read.
     * The function reads the queue contents, but does not clear them.
     * If the queue count exceeds 31, an exception response is returned with an error code of 03
     * (Illegal Data Value).
     *
     * @param serverAddress      a slave address
     * @param fifoPointerAddress address of a fifo pointer register
     * @return the data register value
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public int[] readFifoQueue(int serverAddress, int fifoPointerAddress) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        ModbusRequest request = requestFactory.createReadFifoQueue(serverAddress, fifoPointerAddress);
        ReadFifoQueueResponse response = (ReadFifoQueueResponse) processRequest(request);
        return response.getFifoValueRegister();
    }

    /**
     * This function code is used to perform a file record read.
     * A file is an organization of records. Each file contains 10000 records, addressed 0000 to
     * 9999 decimal or 0X0000 to 0X270F. For example, record 12 is addressed as 12.
     * The function can read multiple groups of references.
     *
     * @param serverAddress a slave address
     * @param records       array of ModbusFileRecord
     * @return array of ModbusFileRecord has been read
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public ModbusFileRecord[] readFileRecord(int serverAddress, ModbusFileRecord[] records) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        ModbusRequest request = requestFactory.createReadFileRecord(serverAddress, records);
        ReadFileRecordResponse response = (ReadFileRecordResponse) processRequest(request);
        return response.getFileRecords();
    }

    /**
     * This function code is used to perform a file record write. All Request Data Lengths are
     * provided in terms of number of bytes and all Record Lengths are provided in terms of the
     * number of 16-bit words.
     * A file is an organization of records. Each file contains 10000 records, addressed 0000 to
     * 9999 decimal or 0X0000 to 0X270F. For example, record 12 is addressed as 12.
     * The function can write multiple groups of references.
     *
     * @param serverAddress a server address
     * @param record        the ModbusFileRecord to be written
     * @throws ModbusProtocolException if modbus-exception is received
     * @throws ModbusNumberException   if response is invalid
     * @throws ModbusIOException       if remote slave is unavailable
     */
    final synchronized public void writeFileRecord(int serverAddress, ModbusFileRecord record) throws
            ModbusProtocolException, ModbusNumberException, ModbusIOException {
        processRequest(requestFactory.createWriteFileRecord(serverAddress, record));
    }

    /**
     * This function code is used to modify the contents of a specified holding register using a
     * combination of an AND mask, an OR mask, and the register's current contents. The function
     * can be used to set or clear individual bits in the register.
     * The request specifies the holding register to be written, the data to be used as the AND
     * mask, and the data to be used as the OR mask. Registers are addressed starting at zero.
     * Therefore registers 1-16 are addressed as 0-15.
     * The function’s algorithm is:
     * Result = (Current Contents AND And_Mask) OR (Or_Mask AND (NOT And_Mask))
     * For example:
     * Hex Binary
     * Current Contents=    12  0001 0010
     * And_Mask =           F2  1111 0010
     * Or_Mask =            25  0010 0101
     * 

* (NOT And_Mask)= 0D 0000 1101 *

* Result = 17 0001 0111 *

* Note: * y If the Or_Mask value is zero, the result is simply the logical ANDing of the current contents and * And_Mask. If the And_Mask value is zero, the result is equal to the Or_Mask value. * y The contents of the register can be read with the Read Holding Registers function (function code 03). * They could, however, be changed subsequently as the controller scans its user logic program. * * @param serverAddress slave id * @param startAddress reference address * @param and the AND mask * @param or the OR mask * @throws ModbusProtocolException if modbus-exception is received * @throws ModbusNumberException if response is invalid * @throws ModbusIOException if remote slave is unavailable */ final synchronized public void maskWriteRegister(int serverAddress, int startAddress, int and, int or) throws ModbusProtocolException, ModbusNumberException, ModbusIOException { processRequest(requestFactory.createMaskWriteRegister(serverAddress, startAddress, and, or)); } /** * This function code is used to read the contents of eight Exception Status outputs in a remote * device. * The function provides a simple method for accessing this information, because the Exception * Output references are known (no output reference is needed in the function). * The normal response contains the status of the eight Exception Status outputs. The outputs * are packed into one data byte, with one bit per output. The status of the lowest output * reference is contained in the least significant bit of the byte. * The contents of the eight Exception Status outputs are device specific. * * @param serverAddress a slave address * @return the eight Exception Status outputs * @throws ModbusProtocolException if modbus-exception is received * @throws ModbusNumberException if response is invalid * @throws ModbusIOException if remote slave is unavailable */ abstract public int readExceptionStatus(int serverAddress) throws ModbusProtocolException, ModbusNumberException, ModbusIOException; /** * This function code is used to read the description of the type, the current status, and other * information specific to a remote device. * The data contents are specific to each type of device. * * @param serverAddress slave address * @return a byte array of the device's specific data * @throws ModbusProtocolException if modbus-exception is received * @throws ModbusNumberException if response is invalid * @throws ModbusIOException if remote slave is unavailable */ abstract public byte[] reportSlaveId(int serverAddress) throws ModbusProtocolException, ModbusNumberException, ModbusIOException; /** * This function code is used to get a status word and an event count from the remote device's * communication event counter. * By fetching the current count before and after a series of messages, a client can determine * whether the messages were handled normally by the remote device. * The device’s event counter is incremented once for each successful message completion. It * is not incremented for exception responses, poll commands, or fetch event counter * commands. * The event counter can be reset by means of the Diagnostics function (code 08), with a subfunction of Restart Communications Option (code 00 01) or Clear Counters and Diagnostic * Register (code 00 0A). * * @param serverAddress a slave address * @return the CommStatus instance * @throws ModbusProtocolException if modbus-exception is received * @throws ModbusNumberException if response is invalid * @throws ModbusIOException if remote slave is unavailable * @see com.invertor.modbus.data.CommStatus */ abstract public CommStatus getCommEventCounter(int serverAddress) throws ModbusProtocolException, ModbusNumberException, ModbusIOException; /** * This function code is used to get a status word, event count, message count, and a field of * event bytes from the remote device. * The status word and event counts are identical to that returned by the Get Communications * Event Counter function (11, 0B hex). * The message counter contains the quantity of messages processed by the remote device * since its last restart, clear counters operation, or power–up. This count is identical to that * returned by the Diagnostic function (code 08), sub-function Return Bus Message Count (code * 11, 0B hex). * The event bytes field contains 0-64 bytes, with each byte corresponding to the status of one * MODBUS send or receive operation for the remote device. The remote device enters the * events into the field in chronological order. Byte 0 is the most recent event. Each new byte * flushes the oldest byte from the field. * * @param serverAddress a slave address * @return the CommStatus instance * @throws ModbusProtocolException if modbus-exception is received * @throws ModbusNumberException if response is invalid * @throws ModbusIOException if remote slave is unavailable * @see com.invertor.modbus.data.CommStatus */ abstract public CommStatus getCommEventLog(int serverAddress) throws ModbusProtocolException, ModbusNumberException, ModbusIOException; /** * 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 * @throws ModbusNumberException if server address is in-valid */ abstract public void diagnosticsReturnQueryData(int serverAddress, int queryData) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 * @throws ModbusNumberException if server address is in-valid */ abstract public void diagnosticsRestartCommunicationsOption(int serverAddress, boolean clearLog) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * Returns the contents of the remote device’s 16–bit diagnostic register are returned in the response. * * @param serverAddress a slave address * @return 16–bit diagnostic register * @throws ModbusNumberException if server address is in-valid */ abstract public int diagnosticsReturnDiagnosticRegister(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 * @throws ModbusNumberException if server address is in-valid */ abstract public void diagnosticsChangeAsciiInputDelimiter(int serverAddress, int delimiter) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 * @throws ModbusNumberException if server address is in-valid */ abstract public void diagnosticsForceListenOnlyMode(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * The goal is to clear all counters and the diagnostic register. Counters are also cleared upon power–up. * * @param serverAddress a slave address * @throws ModbusNumberException if server address is in-valid */ abstract public void diagnosticsClearCountersAndDiagnosticRegister(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 bus message count * @throws ModbusNumberException if server address is in-valid */ abstract public int diagnosticsReturnBusMessageCount(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 CRC error count * @throws ModbusNumberException if server address is in-valid */ abstract public int diagnosticsReturnBusCommunicationErrorCount(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 MODBUS exception response count * @throws ModbusNumberException if server address is in-valid */ abstract public int diagnosticsReturnBusExceptionErrorCount(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 count of messages has been processed * @throws ModbusNumberException if server address is in-valid */ abstract public int diagnosticsReturnSlaveMessageCount(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 no-response count * @throws ModbusNumberException if server address is in-valid */ abstract public int diagnosticsReturnSlaveNoResponseCount(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 NAK count * @throws ModbusNumberException if server address is in-valid */ abstract public int diagnosticsReturnSlaveNAKCount(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 Slave Device Busy exception response count * @throws ModbusNumberException if server address is in-valid */ abstract public int diagnosticsReturnSlaveBusyCount(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * 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 character overrun count * @throws ModbusNumberException if server address is in-valid */ abstract public int diagnosticsReturnBusCharacterOverrunCount(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * Clears the overrun error counter and reset the error flag. * * @param serverAddress a slave address * @throws ModbusNumberException if server address is in-valid */ abstract public void diagnosticsClearOverrunCounterAndFlag(int serverAddress) throws ModbusNumberException, ModbusProtocolException, ModbusIOException; /** * This function code allows reading the identification and additional information relative to the * physical and functional description of a remote device, only. * The Read Device Identification interface is modeled as an address space composed of a set * of addressable data elements. The data elements are called objects and an object Id * identifies them. * The interface consists of 3 categories of objects : * ƒ Basic Device Identification. All objects of this category are mandatory : VendorName, * Product code, and revision number. * ƒ Regular Device Identification. In addition to Basic data objects, the device provides * additional and optional identification and description data objects. All of the objects of * this category are defined in the standard but their implementation is optional . * ƒ Extended Device Identification. In addition to regular data objects, the device provides * additional and optional identification and description private data about the physical * device itself. All of these data are device dependent. * ObjectId ObjectName/Description Type M/O category * 0x00 VendorName ASCII String Mandatory Basic * 0x01 ProductCode ASCII String Mandatory Basic * 0x02 MajorMinorRevision ASCII String Mandatory Basic * 0x03 VendorUrl ASCII String Optional Regular * 0x04 ProductName ASCII String Optional Regular * 0x05 ModelName ASCII String Optional Regular * 0x06 UserApplicationName ASCII String Optional Regular * 0x07 Reserved Optional Optional Regular * … * 0x7F * 0x80 Private objects may be optionally device Optional Extended * … defined. The range [0x80 – 0xFF] dependant * 0xFF is Product dependant. */ final public MEIReadDeviceIdentification readDeviceIdentification(int serverAddress, int objectId, ReadDeviceIdentificationCode readDeviceId) throws ModbusProtocolException, ModbusNumberException, ModbusIOException { EncapsulatedInterfaceTransportResponse response = (EncapsulatedInterfaceTransportResponse) processRequest(requestFactory.createReadDeviceIdentification(serverAddress, objectId, readDeviceId)); return (MEIReadDeviceIdentification) response.getMei(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy