send method
Sends the modbus requests. A ModbusResponseCode
is returned as a future.
If request
has its own unitId defined, then it will override this
client unitId (see getUnitId).
If request
has its own responseTimeout defined, then it will override
this client responseTimeout (see getResponseTimeout).
Implementation
@override
Future<ModbusResponseCode> send(ModbusRequest request) async {
var res = await _lock.synchronized(() async {
// Connect if needed
try {
if (connectionMode != ModbusConnectionMode.doNotConnect) {
await connect();
}
if (!isConnected) {
return ModbusResponseCode.connectionFailed;
}
} catch (ex) {
ModbusAppLogger.severe(
"Unexpected exception in sending TCP message", ex);
return ModbusResponseCode.connectionFailed;
}
// Flushes any old pending data
await _socket!.flush();
// Create the new response handler
var transactionId = _getNextTransactionId();
_currentResponse = _TcpResponse(request,
transactionId: transactionId, timeout: getResponseTimeout(request));
// Reset this request in case it was already used before
request.reset();
// Create request data
int pduLen = request.protocolDataUnit.length;
var header = Uint8List(pduLen + 7);
ByteData.view(header.buffer)
..setUint16(0, transactionId) // Transaction ID
..setUint16(2, 0) // Protocol ID = 0
..setUint16(4, pduLen + 1) // PDU Length + Unit ID byte
..setUint8(6, getUnitId(request)); // Unit ID
header.setAll(7, request.protocolDataUnit);
// Send the request data
_socket!.add(header);
// Wait for the response code
return await request.responseCode;
});
// Need to disconnect?
if (connectionMode == ModbusConnectionMode.autoConnectAndDisconnect) {
await disconnect();
}
return res;
}