use of com.ghgande.j2mod.modbus.ModbusIOException in project OpenMUC by isc-konstanz.
the class ModbusConnection method performModbusTCPReadTransactionWithRetry.
// FIXME concept with retry is not working after a java.net.SocketTimeoutException: Read timed out
// Problem is that the Transaction.excecute() increments the Transaction ID with each execute. Example: Request is
// sent with Transaction ID 30, then a timeout happens, when using the retry mechanism below it will resend the
// request. the jamod increases the transaction id again to 31 but then it receives the response for id 30. From the
// time a timeout happened the response id will be always smaller than the request id, since the jamod doesn't
// provide a method to read a response without sending a request.
@SuppressWarnings("unused")
private ModbusResponse performModbusTCPReadTransactionWithRetry() throws ModbusException {
ModbusResponse response = null;
// NOTE: see comments about max retries in setTransaction()
int retries = 0;
while (retries < MAX_RETRIES_FOR_DRIVER) {
// +1 because id is incremented within transaction execution
// int requestId = transaction.getTransactionID() + 1;
printRequestTraceMsg();
try {
transaction.execute();
} catch (ModbusIOException e) {
// logger.trace("caught ModbusIOException, probably timeout, retry");
retries++;
checkRetryCondition(retries);
continue;
}
if (isTransactionIdMatching()) {
response = transaction.getResponse();
break;
} else {
retries++;
checkRetryCondition(retries);
}
}
return response;
}
use of com.ghgande.j2mod.modbus.ModbusIOException in project OpenMUC by isc-konstanz.
the class ModbusRTUTCPConnection method write.
@Override
public Object write(List<ChannelValueContainer> containers, Object containerListHandle) throws UnsupportedOperationException, ConnectionException {
for (ChannelValueContainer container : containers) {
ModbusChannel channel = getModbusChannel(container.getChannelAddress(), EAccess.WRITE);
try {
writeChannel(channel, container.getValue());
container.setFlag(Flag.VALID);
} catch (ModbusIOException e) {
logger.error("ModbusIOException while writing channel:" + channel.getChannelAddress(), e);
disconnect();
throw new ConnectionException("Try to solve issue with reconnect.");
} catch (ModbusException e) {
logger.error("ModbusException while writing channel: " + channel.getChannelAddress(), e);
container.setFlag(Flag.DRIVER_ERROR_CHANNEL_NOT_ACCESSIBLE);
} catch (Exception e) {
logger.error("Exception while writing channel: " + channel.getChannelAddress(), e);
container.setFlag(Flag.UNKNOWN_ERROR);
}
}
return null;
}
use of com.ghgande.j2mod.modbus.ModbusIOException in project OpenMUC by isc-konstanz.
the class ModbusRTUTCPTransaction method execute.
// setRetries
@Override
public void execute() throws ModbusIOException, ModbusSlaveException, ModbusException {
if (m_Request == null || m_Connection == null) {
throw new ModbusException("Invalid request or connection");
}
/*
* Automatically re-connect if disconnected.
*/
if (!m_Connection.isConnected()) {
try {
m_Connection.connect();
} catch (Exception ex) {
throw new ModbusIOException("Connection failed.");
}
}
/*
* Try sending the message up to m_Retries time. Note that the message is read immediately after being written,
* with no flushing of buffers.
*/
int retryCounter = 0;
int retryLimit = (m_Retries > 0 ? m_Retries : 1);
while (retryCounter < retryLimit) {
try {
synchronized (m_IO) {
if (Modbus.debug) {
System.err.println("request transaction ID = " + m_Request.getTransactionID());
}
m_IO.writeMessage(m_Request);
m_Response = null;
do {
m_Response = m_IO.readResponse();
if (Modbus.debug) {
System.err.println("response transaction ID = " + m_Response.getTransactionID());
if (m_Response.getTransactionID() != m_Request.getTransactionID()) {
System.err.println("expected " + m_Request.getTransactionID() + ", got " + m_Response.getTransactionID());
}
}
} while (m_Response != null && (!isCheckingValidity() || (m_Request.getTransactionID() != 0 && m_Request.getTransactionID() != m_Response.getTransactionID())) && ++retryCounter < retryLimit);
if (retryCounter >= retryLimit) {
throw new ModbusIOException("Executing transaction failed (tried " + m_Retries + " times)");
}
/*
* Both methods were successful, so the transaction must have been executed.
*/
break;
}
} catch (ModbusIOException ex) {
if (!m_Connection.isConnected()) {
try {
m_Connection.connect();
} catch (Exception e) {
/*
* Nope, fail this transaction.
*/
throw new ModbusIOException("Connection lost.");
}
}
retryCounter++;
if (retryCounter >= retryLimit) {
throw new ModbusIOException("Executing transaction failed (tried " + m_Retries + " times)");
}
}
}
/*
* The slave may have returned an exception -- check for that.
*/
if (m_Response instanceof ExceptionResponse) {
throw new ModbusSlaveException(((ExceptionResponse) m_Response).getExceptionCode());
}
/*
* Close the connection if it isn't supposed to stick around.
*/
if (isReconnecting()) {
m_Connection.close();
}
/*
* See if packets require validity checking.
*/
if (isCheckingValidity() && m_Request != null && m_Response != null) {
checkValidity();
}
incrementTransactionID();
}
use of com.ghgande.j2mod.modbus.ModbusIOException in project OpenMUC by isc-konstanz.
the class ModbusTCPConnection method write.
@Override
public Object write(List<ChannelValueContainer> containers, Object containerListHandle) throws UnsupportedOperationException, ConnectionException {
for (ChannelValueContainer container : containers) {
ModbusChannel channel = getModbusChannel(container.getChannelAddress(), EAccess.WRITE);
try {
writeChannel(channel, container.getValue());
container.setFlag(Flag.VALID);
} catch (ModbusIOException e) {
logger.error("ModbusIOException while writing channel:" + channel.getChannelAddress(), e);
disconnect();
throw new ConnectionException("Try to solve issue with reconnect.");
} catch (ModbusException e) {
logger.error("ModbusException while writing channel: " + channel.getChannelAddress(), e);
container.setFlag(Flag.DRIVER_ERROR_CHANNEL_NOT_ACCESSIBLE);
} catch (Exception e) {
logger.error("Exception while writing channel: " + channel.getChannelAddress(), e);
container.setFlag(Flag.UNKNOWN_ERROR);
}
}
return null;
}
use of com.ghgande.j2mod.modbus.ModbusIOException in project OpenMUC by isc-konstanz.
the class ModbusTCPConnection method read.
@Override
public Object read(List<ChannelRecordContainer> containers, Object containerListHandle, String samplingGroup) throws UnsupportedOperationException, ConnectionException {
// reads channels one by one
if (samplingGroup.isEmpty()) {
for (ChannelRecordContainer container : containers) {
// TODO consider retries in sampling timeout (e.g. one time 12000 ms or three times 4000 ms)
// FIXME quite inconvenient/complex to get the timeout from config, since the driver doesn't know the
// device id!
long receiveTime = System.currentTimeMillis();
ModbusChannel channel = getModbusChannel(container.getChannelAddress(), EAccess.READ);
Value value;
try {
value = readChannel(channel);
if (logger.isTraceEnabled()) {
logger.trace("Value of response: {}", value.toString());
}
container.setRecord(new Record(value, receiveTime));
} catch (ModbusIOException e) {
logger.error("ModbusIOException while reading channel:" + channel.getChannelAddress() + " used timeout: " + timeoutMs + " ms", e);
disconnect();
throw new ConnectionException("Try to solve issue with reconnect.");
} catch (ModbusException e) {
logger.error("ModbusException while reading channel: " + channel.getChannelAddress(), e);
container.setRecord(new Record(Flag.DRIVER_ERROR_CHANNEL_NOT_ACCESSIBLE));
} catch (Exception e) {
// catch all possible exceptions and provide info about the channel
logger.error("Exception while reading channel: " + channel.getChannelAddress(), e);
container.setRecord(new Record(Flag.UNKNOWN_ERROR));
}
if (!connection.isConnected()) {
throw new ConnectionException("Lost connection.");
}
}
} else // reads whole samplingGroup at once
{
readChannelGroupHighLevel(containers, containerListHandle, samplingGroup);
if (!connection.isConnected()) {
throw new ConnectionException("Lost connection.");
}
}
return null;
}
Aggregations