diff --git a/src/features/uavs/UAVTestsPanel.jsx b/src/features/uavs/UAVTestsPanel.jsx
index 75a98c50..8b12bc01 100644
--- a/src/features/uavs/UAVTestsPanel.jsx
+++ b/src/features/uavs/UAVTestsPanel.jsx
@@ -121,13 +121,13 @@ const UAVTestButton = ({
const [lastExecutionState, execute] = useAsyncFn(async () => {
lastExecutedUavIdRef.current = uavId;
- // TODO(ntamas): use the proper UAV-TEST messages designated for this
- await messageHub.sendCommandRequest(
- {
- uavId,
- command: type === 'test' ? 'test' : 'calib',
- args: [String(component)],
- },
+ await (
+ type === 'calib'
+ ? messageHub.sendComponentCalibrationRequest
+ : messageHub.sendComponentTestRequest
+ ).call(
+ messageHub,
+ { uavId, component },
{ onProgress: (progress) => progressHandler(uavId, progress), timeout }
);
return true;
diff --git a/src/flockwave/builders.ts b/src/flockwave/builders.ts
index af392c99..bcc7c5ec 100644
--- a/src/flockwave/builders.ts
+++ b/src/flockwave/builders.ts
@@ -7,6 +7,8 @@ import type {
Request_OBJCMD,
Request_PRMSET,
Request_PRMSETMANY,
+ Request_UAVCALIB,
+ Request_UAVTEST,
} from '@skybrush/flockwave-spec';
import arrify from 'arrify';
@@ -157,3 +159,43 @@ export function createBulkParameterUploadRequest(
parameters,
};
}
+
+/**
+ * Creates an UAV-CALIB (component calibration) message
+ *
+ * @param uavIds IDs of the UAVs to send the request to
+ * @param component the component to calibrate
+ * @return the message
+ */
+export function createComponentCalibrationRequest(
+ uavIds: ObjectIDs,
+ component: string
+): Request_UAVCALIB {
+ const result: Request_UAVCALIB = {
+ type: 'UAV-CALIB',
+ ids: uavIds,
+ component,
+ };
+
+ return result;
+}
+
+/**
+ * Creates an UAV-TEST (component test) message
+ *
+ * @param uavIds IDs of the UAVs to send the request to
+ * @param component the component to test
+ * @return the message
+ */
+export function createComponentTestRequest(
+ uavIds: ObjectIDs,
+ component: string
+): Request_UAVTEST {
+ const result: Request_UAVTEST = {
+ type: 'UAV-TEST',
+ ids: uavIds,
+ component,
+ };
+
+ return result;
+}
diff --git a/src/flockwave/messages.ts b/src/flockwave/messages.ts
index ca9a30b5..beacc66c 100644
--- a/src/flockwave/messages.ts
+++ b/src/flockwave/messages.ts
@@ -24,6 +24,8 @@ import pTimeout from 'p-timeout';
import {
createCancellationRequest,
createCommandRequest,
+ createComponentCalibrationRequest,
+ createComponentTestRequest,
createResumeRequest,
} from './builders';
import { createOperationExecutor, type OperationExecutor } from './operations';
@@ -1443,6 +1445,104 @@ export default class MessageHub {
);
}
+ /**
+ * Sends a Flockwave component calibration request (UAV-CALIB) with the given
+ * body and returns a promise that resolves or rejects when one of the following
+ * events happen:
+ *
+ *
+ * - The server signals an execution failure in a direct UAV-CALIB
+ * response to the original request. In this case, the promise errors
+ * out with an appropriate human-readable message.
+ * - The server returns the response to the request in a direct UAV-CALIB
+ * message. In this case, the promise resolves normally with the
+ * UAV-CALIB message itself.
+ * - The server signals a timeout or error for the request in a direct UAV-CALIB
+ * message. In this case, the promise errors out with an appropriate
+ * human-readable message.
+ * - Any of the above, but in a separate notification delivered asynchronously
+ * with ASYNC-RESP (for responses and errors) or ASYNC-TIMEOUT (for timeouts).
+ * - A cancellation is delivered to the server in an ASYNC-CANCEL request
+ * and the server acknowledges the cancellation in the corresponding
+ * ASYNC-CANCEL response.
+ *
+ *
+ * @param request.uavId ID of the UAV to send the request to
+ * @param request.component the component to calibrate
+ * @param options additional options to forward to the
+ * `handleMultiAsyncResponseForSingleId()` method of the
+ * AsyncOperationManager. Typical keys to use are `cancelToken`,
+ * `onProgress`, `timeout` and `noThrow`.
+ * @return a promise that resolves to the response of the UAV
+ * to the command or errors out in case of execution errors and
+ * timeouts.
+ */
+ async sendComponentCalibrationRequest(
+ request: {
+ uavId: string;
+ component: string;
+ },
+ options: AsyncResponseHandlerOptions
+ ): Promise {
+ const { uavId, component } = request;
+ const message = createComponentCalibrationRequest([uavId], component);
+ const response = await this.sendMessage(message);
+ return this._asyncOperationManager.handleMultiAsyncResponseForSingleId(
+ response,
+ uavId,
+ options
+ );
+ }
+
+ /**
+ * Sends a Flockwave component test request (UAV-TEST) with the given
+ * body and returns a promise that resolves or rejects when one of the following
+ * events happen:
+ *
+ *
+ * - The server signals an execution failure in a direct UAV-TEST
+ * response to the original request. In this case, the promise errors
+ * out with an appropriate human-readable message.
+ * - The server returns the response to the request in a direct UAV-TEST
+ * message. In this case, the promise resolves normally with the
+ * UAV-TEST message itself.
+ * - The server signals a timeout or error for the request in a direct UAV-TEST
+ * message. In this case, the promise errors out with an appropriate
+ * human-readable message.
+ * - Any of the above, but in a separate notification delivered asynchronously
+ * with ASYNC-RESP (for responses and errors) or ASYNC-TIMEOUT (for timeouts).
+ * - A cancellation is delivered to the server in an ASYNC-CANCEL request
+ * and the server acknowledges the cancellation in the corresponding
+ * ASYNC-CANCEL response.
+ *
+ *
+ * @param request.uavId ID of the UAV to send the request to
+ * @param request.component the component to calibrate
+ * @param options additional options to forward to the
+ * `handleMultiAsyncResponseForSingleId()` method of the
+ * AsyncOperationManager. Typical keys to use are `cancelToken`,
+ * `onProgress`, `timeout` and `noThrow`.
+ * @return a promise that resolves to the response of the UAV
+ * to the command or errors out in case of execution errors and
+ * timeouts.
+ */
+ async sendComponentTestRequest(
+ request: {
+ uavId: string;
+ component: string;
+ },
+ options: AsyncResponseHandlerOptions
+ ): Promise {
+ const { uavId, component } = request;
+ const message = createComponentTestRequest([uavId], component);
+ const response = await this.sendMessage(message);
+ return this._asyncOperationManager.handleMultiAsyncResponseForSingleId(
+ response,
+ uavId,
+ options
+ );
+ }
+
/**
* Sends a Flockwave message with the given body and then return a promise
* that resolves when the server responds to the message.