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 if requested (i.e. discard old pending
      // requests & responses)
      if (flushOnRequest) {
        await serialPort.flush();
      }

      // Send the serial telegram
      var reqTxData = _getTxTelegram(request, unitId);
      int txDataCount =
          await serialPort.write(reqTxData, timeout: resTimeout);

      if (txDataCount < reqTxData.length) {
        ModbusAppLogger.finest(
            "Error sending data: sent $txDataCount of ${reqTxData.length} bytes");
        request.setResponseCode(ModbusResponseCode.requestTimeout);
        return request.responseCode;
      }
      ModbusAppLogger.finest(
          "Sent data: ${ModbusAppLogger.toHex(reqTxData)}");
    } 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 = ModbusResponseCode.requestTimeout;
    if (!remainingTime.isNegative) {
      ModbusAppLogger.finest("Receiving header...");
      responseCode = 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;

    if (!remainingTime.isNegative) {
      ModbusAppLogger.finest("Receiving PDU...");
      responseCode = await _readResponsePdu(response, remainingTime);
    } else {
      responseCode = ModbusResponseCode.requestTimeout;
    }

    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;
}