send method

  1. @override
Future<ModbusResponseCode> send(
  1. ModbusRequest request
)
inherited

Sends a modbus request

Implementation

@override
Future<ModbusResponseCode> send(ModbusRequest request) async {
  Duration resTimeout = getResponseTimeout(request);
  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 connecting to ${serialPort.name}", ex);
      return ModbusResponseCode.connectionFailed;
    }

    // Reset this request in case it was already used before
    request.reset();

    // Start a stopwatch for the request timeout
    final reqStopwatch = Stopwatch()..start();

    // Send the request data
    var unitId = getUnitId(request);
    try {
      // Flush both tx & rx buffers (discard old pending requests & responses)
      await serialPort.flush();

      // Sent the serial telegram
      var reqTxData = _getTxTelegram(request, unitId);
      int txDataCount =
          await serialPort.write(reqTxData, timeout: resTimeout);
      if (txDataCount < reqTxData.length) {
        request.setResponseCode(ModbusResponseCode.requestTimeout);
        return request.responseCode;
      }
    } catch (ex) {
      ModbusAppLogger.severe(
          "Unexpected exception in sending data to ${serialPort.name}", ex);
      request.setResponseCode(ModbusResponseCode.requestTxFailed);
      return request.responseCode;
    }

    // Lets check the response header (i.e.read first bytes only to check if
    // response is normal or has error)
    var response = _ModbusSerialResponse(
        request: request,
        unitId: unitId,
        checksumByteCount: checksumByteCount);
    Duration remainingTime = resTimeout - reqStopwatch.elapsed;
    var responseCode = remainingTime.isNegative
        ? ModbusResponseCode.requestTimeout
        : await _readResponseHeader(response, remainingTime);
    if (responseCode != ModbusResponseCode.requestSucceed) {
      request.setResponseCode(responseCode);
      return request.responseCode;
    }

    // Lets wait the rest of the PDU response
    remainingTime = resTimeout - reqStopwatch.elapsed;
    responseCode = remainingTime.isNegative
        ? ModbusResponseCode.requestTimeout
        : await _readResponsePdu(response, remainingTime);
    if (responseCode != ModbusResponseCode.requestSucceed) {
      request.setResponseCode(responseCode);
      return request.responseCode;
    }

    // Set the request response based on received PDU
    request.setFromPduResponse(response.pdu);

    return request.responseCode;
  });
  // Need to disconnect?
  if (connectionMode == ModbusConnectionMode.autoConnectAndDisconnect) {
    await disconnect();
  }
  return res;
}