From 090dd9bd66c51df85702c2b3924db52bb8871a1d Mon Sep 17 00:00:00 2001 From: Aaron Chong Date: Wed, 10 Jul 2024 00:30:29 +0800 Subject: [PATCH] Hammer/generic alerts (#948) * First iteration of generic alerts Signed-off-by: Aaron Chong * Route for unresponded alerts Signed-off-by: Aaron Chong * Basic location complete post route for task Signed-off-by: Aaron Chong * Tests for alert routes Signed-off-by: Aaron Chong * Test for location complete route Signed-off-by: Aaron Chong * Lint and tests Signed-off-by: Aaron Chong * Basic implementation Signed-off-by: Aaron Chong * Basic task based alerts working as expected Signed-off-by: Aaron Chong * Only display and list alerts that have display true Signed-off-by: Aaron Chong * Add doc to location_complete route about instability Signed-off-by: Aaron Chong * Refactored alert db interactions to repository, with lru cache for location alerts checking Signed-off-by: Aaron Chong * Regenerated docs and return early on gateway last location checking Signed-off-by: Aaron Chong * Lint and better typing with static methods Signed-off-by: Aaron Chong * Hammer/generic alerts without location (#951) * First round of cleanup Signed-off-by: Aaron Chong * Regenerate API Signed-off-by: Aaron Chong --------- Signed-off-by: Aaron Chong * Hammer/demo tasks (#925) * Moved custom deliveries to separate file naively and import naively Signed-off-by: Aaron Chong * Moved patrol Signed-off-by: Aaron Chong * Moved custom-compose Signed-off-by: Aaron Chong * Added clean and delivery Signed-off-by: Aaron Chong * Added delivery, renamed to SimpleDelivery Signed-off-by: Aaron Chong * Clean task added Signed-off-by: Aaron Chong * Moved delivery-custom tests, added return type for forms Signed-off-by: Aaron Chong * Configurable supported tasks and name remapping Signed-off-by: Aaron Chong * Changed directory to types, since it doesn't just handle descriptions Signed-off-by: Aaron Chong * Fix test imports Signed-off-by: Aaron Chong * Using temporary task definition Signed-off-by: Aaron Chong * Refactoring new rename changes Signed-off-by: Aaron Chong * Clean up Signed-off-by: Aaron Chong * Removed problematic and unsused component and test Signed-off-by: Aaron Chong * Lint Signed-off-by: Aaron Chong * Updating pnpm version in github workflow Signed-off-by: Aaron Chong * Reverting update to pnpm version Signed-off-by: Aaron Chong * Fix build now that we use key value strings for labels Signed-off-by: Aaron Chong * Refactored last parts of hard coding categories and rendering forms Signed-off-by: Aaron Chong * Refactor callback names and error handling for misconfigs Signed-off-by: Aaron Chong * Display error as well Signed-off-by: Aaron Chong * Fixed more checks and failures Signed-off-by: Aaron Chong * Split configuration and definition, only handle configurations in resource manager level Signed-off-by: Aaron Chong * Lint Signed-off-by: Aaron Chong * Not using object as a type Signed-off-by: Aaron Chong * Address feedback Signed-off-by: Aaron Chong * Render using validTasks instead Signed-off-by: Aaron Chong * Use useMemo Signed-off-by: Aaron Chong --------- Signed-off-by: Aaron Chong * Update ros2 pydantic messages, fix tests Signed-off-by: Aaron Chong * Revert update of pnpm lock file Signed-off-by: Aaron Chong * Lint Signed-off-by: Aaron Chong * Use specific exceptions and more clean up Signed-off-by: Aaron Chong * Port CI fixes from #955 but targeting ubuntu 22 and ROS 2 Humble Signed-off-by: Aaron Chong * Revert "Port CI fixes from #955 but targeting ubuntu 22 and ROS 2 Humble" This reverts commit 1fd22eec62c8601ee1b6cbae3c7ed96833ea47ba. Signed-off-by: Aaron Chong * Update pnpm version Signed-off-by: Aaron Chong * Setup pnpm and node manually Signed-off-by: Aaron Chong * Using HOME env var of runner Signed-off-by: Aaron Chong * workflow Signed-off-by: Aaron Chong * workflow Signed-off-by: Aaron Chong * Workflow Signed-off-by: Aaron Chong * Address feedback on frontend Signed-off-by: Aaron Chong * Address comments that don't break behavior Signed-off-by: Aaron Chong * Started generic exceptions Signed-off-by: Aaron Chong * Proper db schema for alert request and response Signed-off-by: Aaron Chong * Updated alerts model, frontend tweaks for subscription, using pagination for unackw query, updated API Signed-off-by: Aaron Chong * Attempt to setup minimal RMF during bootstrap step Signed-off-by: Aaron Chong * Fix mistake on ci path Signed-off-by: Aaron Chong * Fix workflow Signed-off-by: Aaron Chong * Revert CI changes Signed-off-by: Aaron Chong * Updated API, renamed event to pushAlert, filter before Signed-off-by: Aaron Chong --------- Signed-off-by: Aaron Chong --- packages/api-client/lib/index.ts | 13 +- packages/api-client/lib/openapi/api.ts | 929 ++++++++++++++---- packages/api-client/lib/version.ts | 2 +- packages/api-client/schema/index.ts | 337 +++++-- packages/api-server/api_server/app.py | 4 +- packages/api-server/api_server/exceptions.py | 16 + packages/api-server/api_server/gateway.py | 89 +- .../api-server/api_server/models/__init__.py | 5 +- .../api-server/api_server/models/alerts.py | 69 ++ .../rmf_fleet_msgs/ChargingAssignment.py | 29 + .../rmf_fleet_msgs/ChargingAssignments.py | 25 + .../rmf_fleet_msgs/DeliveryAlertCategory.py | 2 + .../rmf_fleet_msgs/InterruptRequest.py | 35 + .../ros_pydantic/rmf_fleet_msgs/LaneStates.py | 33 + .../rmf_fleet_msgs/MutexGroupAssignment.py | 37 + .../rmf_fleet_msgs/MutexGroupManualRelease.py | 34 + .../rmf_fleet_msgs/MutexGroupRequest.py | 50 + .../rmf_fleet_msgs/MutexGroupStates.py | 23 + .../ros_pydantic/rmf_fleet_msgs/RobotMode.py | 12 + .../rmf_fleet_msgs/SpeedLimitRequest.py | 33 + .../rmf_fleet_msgs/SpeedLimitedLane.py | 26 + .../ros_pydantic/rmf_fleet_msgs/__init__.py | 10 + .../ros_pydantic/rmf_task_msgs/Alert.py | 65 ++ .../rmf_task_msgs/AlertParameter.py | 24 + .../rmf_task_msgs/AlertResponse.py | 27 + .../ros_pydantic/rmf_task_msgs/ApiRequest.py | 27 + .../ros_pydantic/rmf_task_msgs/ApiResponse.py | 47 + .../rmf_task_msgs/ApiService_Request.py | 23 + .../rmf_task_msgs/ApiService_Response.py | 23 + .../ros_pydantic/rmf_task_msgs/Assignment.py | 26 + .../ros_pydantic/rmf_task_msgs/BidNotice.py | 14 +- .../ros_pydantic/rmf_task_msgs/BidProposal.py | 15 +- .../ros_pydantic/rmf_task_msgs/BidResponse.py | 38 + .../ros_pydantic/rmf_task_msgs/DispatchAck.py | 16 +- .../rmf_task_msgs/DispatchCommand.py | 49 + .../rmf_task_msgs/DispatchRequest.py | 39 - .../rmf_task_msgs/DispatchState.py | 39 + .../rmf_task_msgs/DispatchStates.py | 30 + ...equest.py => GetDispatchStates_Request.py} | 13 +- .../GetDispatchStates_Response.py | 28 + .../rmf_task_msgs/GetTaskList_Response.py | 31 - .../ros_pydantic/rmf_task_msgs/__init__.py | 17 +- .../api_server/models/ros_pydantic/version.py | 2 +- .../models/tortoise_models/alerts.py | 43 +- .../api_server/repositories/alerts.py | 147 ++- .../api_server/repositories/tasks.py | 59 -- .../api_server/rmf_io/book_keeper.py | 70 +- .../api-server/api_server/rmf_io/events.py | 3 +- .../api-server/api_server/routes/alerts.py | 122 ++- .../api-server/api_server/routes/internal.py | 95 +- .../api_server/routes/test_alerts.py | 226 +++++ .../api-server/api_server/test/test_data.py | 18 +- packages/api-server/generate-models.sh | 2 +- .../src/components/alert-manager.tsx | 361 +++++++ .../dashboard/src/components/alert-store.tsx | 78 -- .../dashboard/src/components/app-base.tsx | 4 +- .../dashboard/src/components/app-events.ts | 13 +- packages/dashboard/src/components/appbar.tsx | 78 +- .../src/components/rmf-app/rmf-ingress.ts | 13 +- .../src/components/tasks/task-alert.tsx | 303 ------ .../components/tasks/task-cancellation.tsx | 18 +- 61 files changed, 2971 insertions(+), 1088 deletions(-) create mode 100644 packages/api-server/api_server/exceptions.py create mode 100644 packages/api-server/api_server/models/alerts.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/ChargingAssignment.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/ChargingAssignments.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/InterruptRequest.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/LaneStates.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupAssignment.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupManualRelease.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupRequest.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupStates.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/SpeedLimitRequest.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/SpeedLimitedLane.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/Alert.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/AlertParameter.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/AlertResponse.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiRequest.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiResponse.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiService_Request.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiService_Response.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/Assignment.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidResponse.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchCommand.py delete mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchRequest.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchState.py create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchStates.py rename packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/{GetTaskList_Request.py => GetDispatchStates_Request.py} (57%) create mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetDispatchStates_Response.py delete mode 100644 packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetTaskList_Response.py create mode 100644 packages/api-server/api_server/routes/test_alerts.py create mode 100644 packages/dashboard/src/components/alert-manager.tsx delete mode 100644 packages/dashboard/src/components/alert-store.tsx delete mode 100644 packages/dashboard/src/components/tasks/task-alert.tsx diff --git a/packages/api-client/lib/index.ts b/packages/api-client/lib/index.ts index ae2c21d85..3c79e343b 100644 --- a/packages/api-client/lib/index.ts +++ b/packages/api-client/lib/index.ts @@ -1,7 +1,8 @@ import Debug from 'debug'; import { io, Socket } from 'socket.io-client'; import { - ApiServerModelsTortoiseModelsAlertsAlertLeaf, + AlertRequest, + AlertResponse, ApiServerModelsTortoiseModelsBeaconsBeaconStateLeaf as BeaconState, BuildingMap, DeliveryAlert, @@ -19,8 +20,6 @@ import { TaskState, } from './openapi'; -type Alert = ApiServerModelsTortoiseModelsAlertsAlertLeaf; - const debug = Debug('rmf-client'); // https://stackoverflow.com/questions/52667959/what-is-the-purpose-of-bivariancehack-in-typescript-types @@ -102,8 +101,12 @@ export class SioClient { return this.subscribe(`/tasks/${taskId}/log`, listener); } - subscribeAlerts(listener: Listener): Subscription { - return this.subscribe(`/alerts`, listener); + subscribeAlertRequests(listener: Listener): Subscription { + return this.subscribe(`/alerts/requests`, listener); + } + + subscribeAlertResponses(listener: Listener): Subscription { + return this.subscribe(`/alerts/responses`, listener); } subscribeDeliveryAlerts(listener: Listener): Subscription { diff --git a/packages/api-client/lib/openapi/api.ts b/packages/api-client/lib/openapi/api.ts index ddfa3647a..4b57dad19 100644 --- a/packages/api-client/lib/openapi/api.ts +++ b/packages/api-client/lib/openapi/api.ts @@ -154,6 +154,132 @@ export interface AffineImage { */ data: string; } +/** + * + * @export + * @interface AlertParameter + */ +export interface AlertParameter { + /** + * + * @type {string} + * @memberof AlertParameter + */ + name: string; + /** + * + * @type {string} + * @memberof AlertParameter + */ + value: string; +} +/** + * + * @export + * @interface AlertRequest + */ +export interface AlertRequest { + /** + * + * @type {string} + * @memberof AlertRequest + */ + id: string; + /** + * + * @type {number} + * @memberof AlertRequest + */ + unix_millis_alert_time: number; + /** + * + * @type {string} + * @memberof AlertRequest + */ + title: string; + /** + * + * @type {string} + * @memberof AlertRequest + */ + subtitle: string; + /** + * + * @type {string} + * @memberof AlertRequest + */ + message: string; + /** + * + * @type {boolean} + * @memberof AlertRequest + */ + display: boolean; + /** + * + * @type {ApiServerModelsAlertsAlertRequestTier} + * @memberof AlertRequest + */ + tier: ApiServerModelsAlertsAlertRequestTier; + /** + * + * @type {Array} + * @memberof AlertRequest + */ + responses_available: Array; + /** + * + * @type {Array} + * @memberof AlertRequest + */ + alert_parameters: Array; + /** + * + * @type {string} + * @memberof AlertRequest + */ + task_id?: string; +} +/** + * + * @export + * @interface AlertResponse + */ +export interface AlertResponse { + /** + * + * @type {string} + * @memberof AlertResponse + */ + id: string; + /** + * + * @type {number} + * @memberof AlertResponse + */ + unix_millis_response_time: number; + /** + * + * @type {string} + * @memberof AlertResponse + */ + response: string; +} +/** + * An enumeration. + * @export + * @enum {string} + */ + +export const ApiServerModelsAlertsAlertRequestTier = { + Info: 'info', + Warning: 'warning', + Error: 'error', +} as const; + +export type ApiServerModelsAlertsAlertRequestTier = + typeof ApiServerModelsAlertsAlertRequestTier[keyof typeof ApiServerModelsAlertsAlertRequestTier]; + /** * An enumeration. * @export @@ -271,49 +397,6 @@ export type ApiServerModelsRmfApiTokenResponseFailure = false; */ export type ApiServerModelsRmfApiTokenResponseSuccess = true; -/** - * General alert that can be triggered by events. - * @export - * @interface ApiServerModelsTortoiseModelsAlertsAlertLeaf - */ -export interface ApiServerModelsTortoiseModelsAlertsAlertLeaf { - /** - * - * @type {string} - * @memberof ApiServerModelsTortoiseModelsAlertsAlertLeaf - */ - id: string; - /** - * - * @type {string} - * @memberof ApiServerModelsTortoiseModelsAlertsAlertLeaf - */ - original_id: string; - /** - * Default: default
Task: task
Fleet: fleet
Robot: robot - * @type {string} - * @memberof ApiServerModelsTortoiseModelsAlertsAlertLeaf - */ - category: string; - /** - * - * @type {number} - * @memberof ApiServerModelsTortoiseModelsAlertsAlertLeaf - */ - unix_millis_created_time: number; - /** - * - * @type {string} - * @memberof ApiServerModelsTortoiseModelsAlertsAlertLeaf - */ - acknowledged_by?: string | null; - /** - * - * @type {number} - * @memberof ApiServerModelsTortoiseModelsAlertsAlertLeaf - */ - unix_millis_acknowledged_time?: number | null; -} /** * * @export @@ -1755,6 +1838,31 @@ export interface MutexGroups { */ requesting?: Array; } +/** + * + * @export + * @interface Pagination + */ +export interface Pagination { + /** + * + * @type {number} + * @memberof Pagination + */ + limit: number; + /** + * + * @type {number} + * @memberof Pagination + */ + offset: number; + /** + * + * @type {Array} + * @memberof Pagination + */ + order_by: Array; +} /** * * @export @@ -2109,6 +2217,31 @@ export interface ResumedBy { */ labels: Array; } +/** + * + * @export + * @interface Rio + */ +export interface Rio { + /** + * + * @type {string} + * @memberof Rio + */ + id: string; + /** + * + * @type {string} + * @memberof Rio + */ + type: string; + /** + * + * @type {object} + * @memberof Rio + */ + data: object; +} /** * * @export @@ -4774,19 +4907,64 @@ export class AdminApi extends BaseAPI { export const AlertsApiAxiosParamCreator = function (configuration?: Configuration) { return { /** - * - * @summary Acknowledge Alert + * Creates a new alert. + * @summary Create New Alert + * @param {AlertRequest} alertRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createNewAlertAlertsRequestPost: async ( + alertRequest: AlertRequest, + options: AxiosRequestConfig = {}, + ): Promise => { + // verify required parameter 'alertRequest' is not null or undefined + assertParamExists('createNewAlertAlertsRequestPost', 'alertRequest', alertRequest); + const localVarPath = `/alerts/request`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options }; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = { + ...localVarHeaderParameter, + ...headersFromBaseOptions, + ...options.headers, + }; + localVarRequestOptions.data = serializeDataIfNeeded( + alertRequest, + localVarRequestOptions, + configuration, + ); + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Gets an alert based on the alert ID. + * @summary Get Alert * @param {string} alertId * @param {*} [options] Override http request option. * @throws {RequiredError} */ - acknowledgeAlertAlertsAlertIdPost: async ( + getAlertAlertsRequestAlertIdGet: async ( alertId: string, options: AxiosRequestConfig = {}, ): Promise => { // verify required parameter 'alertId' is not null or undefined - assertParamExists('acknowledgeAlertAlertsAlertIdPost', 'alertId', alertId); - const localVarPath = `/alerts/{alert_id}`.replace( + assertParamExists('getAlertAlertsRequestAlertIdGet', 'alertId', alertId); + const localVarPath = `/alerts/request/{alert_id}`.replace( `{${'alert_id'}}`, encodeURIComponent(String(alertId)), ); @@ -4797,7 +4975,7 @@ export const AlertsApiAxiosParamCreator = function (configuration?: Configuratio baseOptions = configuration.baseOptions; } - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options }; + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options }; const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; @@ -4815,23 +4993,22 @@ export const AlertsApiAxiosParamCreator = function (configuration?: Configuratio }; }, /** - * - * @summary Create Alert + * Gets the response to the alert based on the alert ID. + * @summary Get Alert Response * @param {string} alertId - * @param {string} category * @param {*} [options] Override http request option. * @throws {RequiredError} */ - createAlertAlertsPost: async ( + getAlertResponseAlertsRequestAlertIdResponseGet: async ( alertId: string, - category: string, options: AxiosRequestConfig = {}, ): Promise => { // verify required parameter 'alertId' is not null or undefined - assertParamExists('createAlertAlertsPost', 'alertId', alertId); - // verify required parameter 'category' is not null or undefined - assertParamExists('createAlertAlertsPost', 'category', category); - const localVarPath = `/alerts`; + assertParamExists('getAlertResponseAlertsRequestAlertIdResponseGet', 'alertId', alertId); + const localVarPath = `/alerts/request/{alert_id}/response`.replace( + `{${'alert_id'}}`, + encodeURIComponent(String(alertId)), + ); // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); let baseOptions; @@ -4839,16 +5016,55 @@ export const AlertsApiAxiosParamCreator = function (configuration?: Configuratio baseOptions = configuration.baseOptions; } - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options }; + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options }; const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; - if (alertId !== undefined) { - localVarQueryParameter['alert_id'] = alertId; + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = { + ...localVarHeaderParameter, + ...headersFromBaseOptions, + ...options.headers, + }; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Returns all the alerts associated to a task ID. Provides the option to only return alerts that have not been responded to yet. + * @summary Get Alerts Of Task + * @param {string} taskId + * @param {boolean} [unresponded] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAlertsOfTaskAlertsRequestsTaskTaskIdGet: async ( + taskId: string, + unresponded?: boolean, + options: AxiosRequestConfig = {}, + ): Promise => { + // verify required parameter 'taskId' is not null or undefined + assertParamExists('getAlertsOfTaskAlertsRequestsTaskTaskIdGet', 'taskId', taskId); + const localVarPath = `/alerts/requests/task/{task_id}`.replace( + `{${'task_id'}}`, + encodeURIComponent(String(taskId)), + ); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; } - if (category !== undefined) { - localVarQueryParameter['category'] = category; + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options }; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (unresponded !== undefined) { + localVarQueryParameter['unresponded'] = unresponded; } setSearchParams(localVarUrlObj, localVarQueryParameter); @@ -4865,22 +5081,17 @@ export const AlertsApiAxiosParamCreator = function (configuration?: Configuratio }; }, /** - * - * @summary Get Alert - * @param {string} alertId + * Returns the list of alert IDs that have yet to be responded to, while a response was required. + * @summary Get Unresponded Alerts + * @param {Pagination} [pagination] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getAlertAlertsAlertIdGet: async ( - alertId: string, + getUnrespondedAlertsAlertsUnrespondedRequestsGet: async ( + pagination?: Pagination, options: AxiosRequestConfig = {}, ): Promise => { - // verify required parameter 'alertId' is not null or undefined - assertParamExists('getAlertAlertsAlertIdGet', 'alertId', alertId); - const localVarPath = `/alerts/{alert_id}`.replace( - `{${'alert_id'}}`, - encodeURIComponent(String(alertId)), - ); + const localVarPath = `/alerts/unresponded_requests`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); let baseOptions; @@ -4892,6 +5103,8 @@ export const AlertsApiAxiosParamCreator = function (configuration?: Configuratio const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; + localVarHeaderParameter['Content-Type'] = 'application/json'; + setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = { @@ -4899,6 +5112,11 @@ export const AlertsApiAxiosParamCreator = function (configuration?: Configuratio ...headersFromBaseOptions, ...options.headers, }; + localVarRequestOptions.data = serializeDataIfNeeded( + pagination, + localVarRequestOptions, + configuration, + ); return { url: toPathString(localVarUrlObj), @@ -4906,13 +5124,26 @@ export const AlertsApiAxiosParamCreator = function (configuration?: Configuratio }; }, /** - * - * @summary Get Alerts + * Responds to an existing alert. The response must be one of the available responses listed in the alert. + * @summary Respond To Alert + * @param {string} alertId + * @param {string} response * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getAlertsAlertsGet: async (options: AxiosRequestConfig = {}): Promise => { - const localVarPath = `/alerts`; + respondToAlertAlertsRequestAlertIdRespondPost: async ( + alertId: string, + response: string, + options: AxiosRequestConfig = {}, + ): Promise => { + // verify required parameter 'alertId' is not null or undefined + assertParamExists('respondToAlertAlertsRequestAlertIdRespondPost', 'alertId', alertId); + // verify required parameter 'response' is not null or undefined + assertParamExists('respondToAlertAlertsRequestAlertIdRespondPost', 'response', response); + const localVarPath = `/alerts/request/{alert_id}/respond`.replace( + `{${'alert_id'}}`, + encodeURIComponent(String(alertId)), + ); // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); let baseOptions; @@ -4920,10 +5151,14 @@ export const AlertsApiAxiosParamCreator = function (configuration?: Configuratio baseOptions = configuration.baseOptions; } - const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options }; + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options }; const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; + if (response !== undefined) { + localVarQueryParameter['response'] = response; + } + setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = { @@ -4948,89 +5183,115 @@ export const AlertsApiFp = function (configuration?: Configuration) { const localVarAxiosParamCreator = AlertsApiAxiosParamCreator(configuration); return { /** - * - * @summary Acknowledge Alert - * @param {string} alertId + * Creates a new alert. + * @summary Create New Alert + * @param {AlertRequest} alertRequest * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async acknowledgeAlertAlertsAlertIdPost( - alertId: string, + async createNewAlertAlertsRequestPost( + alertRequest: AlertRequest, options?: AxiosRequestConfig, - ): Promise< - ( - axios?: AxiosInstance, - basePath?: string, - ) => AxiosPromise - > { - const localVarAxiosArgs = await localVarAxiosParamCreator.acknowledgeAlertAlertsAlertIdPost( - alertId, + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createNewAlertAlertsRequestPost( + alertRequest, options, ); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** - * - * @summary Create Alert + * Gets an alert based on the alert ID. + * @summary Get Alert * @param {string} alertId - * @param {string} category * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async createAlertAlertsPost( + async getAlertAlertsRequestAlertIdGet( alertId: string, - category: string, options?: AxiosRequestConfig, - ): Promise< - ( - axios?: AxiosInstance, - basePath?: string, - ) => AxiosPromise - > { - const localVarAxiosArgs = await localVarAxiosParamCreator.createAlertAlertsPost( + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAlertAlertsRequestAlertIdGet( alertId, - category, options, ); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** - * - * @summary Get Alert - * @param {string} alertId + * Gets the response to the alert based on the alert ID. + * @summary Get Alert Response + * @param {string} alertId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAlertResponseAlertsRequestAlertIdResponseGet( + alertId: string, + options?: AxiosRequestConfig, + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = + await localVarAxiosParamCreator.getAlertResponseAlertsRequestAlertIdResponseGet( + alertId, + options, + ); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * Returns all the alerts associated to a task ID. Provides the option to only return alerts that have not been responded to yet. + * @summary Get Alerts Of Task + * @param {string} taskId + * @param {boolean} [unresponded] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAlertsOfTaskAlertsRequestsTaskTaskIdGet( + taskId: string, + unresponded?: boolean, + options?: AxiosRequestConfig, + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = + await localVarAxiosParamCreator.getAlertsOfTaskAlertsRequestsTaskTaskIdGet( + taskId, + unresponded, + options, + ); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * Returns the list of alert IDs that have yet to be responded to, while a response was required. + * @summary Get Unresponded Alerts + * @param {Pagination} [pagination] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async getAlertAlertsAlertIdGet( - alertId: string, + async getUnrespondedAlertsAlertsUnrespondedRequestsGet( + pagination?: Pagination, options?: AxiosRequestConfig, - ): Promise< - ( - axios?: AxiosInstance, - basePath?: string, - ) => AxiosPromise - > { - const localVarAxiosArgs = await localVarAxiosParamCreator.getAlertAlertsAlertIdGet( - alertId, - options, - ); + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = + await localVarAxiosParamCreator.getUnrespondedAlertsAlertsUnrespondedRequestsGet( + pagination, + options, + ); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** - * - * @summary Get Alerts + * Responds to an existing alert. The response must be one of the available responses listed in the alert. + * @summary Respond To Alert + * @param {string} alertId + * @param {string} response * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async getAlertsAlertsGet( + async respondToAlertAlertsRequestAlertIdRespondPost( + alertId: string, + response: string, options?: AxiosRequestConfig, - ): Promise< - ( - axios?: AxiosInstance, - basePath?: string, - ) => AxiosPromise> - > { - const localVarAxiosArgs = await localVarAxiosParamCreator.getAlertsAlertsGet(options); + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = + await localVarAxiosParamCreator.respondToAlertAlertsRequestAlertIdRespondPost( + alertId, + response, + options, + ); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, }; @@ -5048,62 +5309,95 @@ export const AlertsApiFactory = function ( const localVarFp = AlertsApiFp(configuration); return { /** - * - * @summary Acknowledge Alert - * @param {string} alertId + * Creates a new alert. + * @summary Create New Alert + * @param {AlertRequest} alertRequest * @param {*} [options] Override http request option. * @throws {RequiredError} */ - acknowledgeAlertAlertsAlertIdPost( - alertId: string, + createNewAlertAlertsRequestPost( + alertRequest: AlertRequest, options?: any, - ): AxiosPromise { + ): AxiosPromise { return localVarFp - .acknowledgeAlertAlertsAlertIdPost(alertId, options) + .createNewAlertAlertsRequestPost(alertRequest, options) .then((request) => request(axios, basePath)); }, /** - * - * @summary Create Alert + * Gets an alert based on the alert ID. + * @summary Get Alert * @param {string} alertId - * @param {string} category * @param {*} [options] Override http request option. * @throws {RequiredError} */ - createAlertAlertsPost( - alertId: string, - category: string, - options?: any, - ): AxiosPromise { + getAlertAlertsRequestAlertIdGet(alertId: string, options?: any): AxiosPromise { return localVarFp - .createAlertAlertsPost(alertId, category, options) + .getAlertAlertsRequestAlertIdGet(alertId, options) .then((request) => request(axios, basePath)); }, /** - * - * @summary Get Alert + * Gets the response to the alert based on the alert ID. + * @summary Get Alert Response * @param {string} alertId * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getAlertAlertsAlertIdGet( + getAlertResponseAlertsRequestAlertIdResponseGet( alertId: string, options?: any, - ): AxiosPromise { + ): AxiosPromise { return localVarFp - .getAlertAlertsAlertIdGet(alertId, options) + .getAlertResponseAlertsRequestAlertIdResponseGet(alertId, options) .then((request) => request(axios, basePath)); }, /** - * - * @summary Get Alerts + * Returns all the alerts associated to a task ID. Provides the option to only return alerts that have not been responded to yet. + * @summary Get Alerts Of Task + * @param {string} taskId + * @param {boolean} [unresponded] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAlertsOfTaskAlertsRequestsTaskTaskIdGet( + taskId: string, + unresponded?: boolean, + options?: any, + ): AxiosPromise> { + return localVarFp + .getAlertsOfTaskAlertsRequestsTaskTaskIdGet(taskId, unresponded, options) + .then((request) => request(axios, basePath)); + }, + /** + * Returns the list of alert IDs that have yet to be responded to, while a response was required. + * @summary Get Unresponded Alerts + * @param {Pagination} [pagination] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUnrespondedAlertsAlertsUnrespondedRequestsGet( + pagination?: Pagination, + options?: any, + ): AxiosPromise> { + return localVarFp + .getUnrespondedAlertsAlertsUnrespondedRequestsGet(pagination, options) + .then((request) => request(axios, basePath)); + }, + /** + * Responds to an existing alert. The response must be one of the available responses listed in the alert. + * @summary Respond To Alert + * @param {string} alertId + * @param {string} response * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getAlertsAlertsGet( + respondToAlertAlertsRequestAlertIdRespondPost( + alertId: string, + response: string, options?: any, - ): AxiosPromise> { - return localVarFp.getAlertsAlertsGet(options).then((request) => request(axios, basePath)); + ): AxiosPromise { + return localVarFp + .respondToAlertAlertsRequestAlertIdRespondPost(alertId, response, options) + .then((request) => request(axios, basePath)); }, }; }; @@ -5116,58 +5410,102 @@ export const AlertsApiFactory = function ( */ export class AlertsApi extends BaseAPI { /** - * - * @summary Acknowledge Alert - * @param {string} alertId + * Creates a new alert. + * @summary Create New Alert + * @param {AlertRequest} alertRequest * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AlertsApi */ - public acknowledgeAlertAlertsAlertIdPost(alertId: string, options?: AxiosRequestConfig) { + public createNewAlertAlertsRequestPost(alertRequest: AlertRequest, options?: AxiosRequestConfig) { return AlertsApiFp(this.configuration) - .acknowledgeAlertAlertsAlertIdPost(alertId, options) + .createNewAlertAlertsRequestPost(alertRequest, options) .then((request) => request(this.axios, this.basePath)); } /** - * - * @summary Create Alert + * Gets an alert based on the alert ID. + * @summary Get Alert * @param {string} alertId - * @param {string} category * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AlertsApi */ - public createAlertAlertsPost(alertId: string, category: string, options?: AxiosRequestConfig) { + public getAlertAlertsRequestAlertIdGet(alertId: string, options?: AxiosRequestConfig) { return AlertsApiFp(this.configuration) - .createAlertAlertsPost(alertId, category, options) + .getAlertAlertsRequestAlertIdGet(alertId, options) .then((request) => request(this.axios, this.basePath)); } /** - * - * @summary Get Alert + * Gets the response to the alert based on the alert ID. + * @summary Get Alert Response * @param {string} alertId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AlertsApi */ - public getAlertAlertsAlertIdGet(alertId: string, options?: AxiosRequestConfig) { + public getAlertResponseAlertsRequestAlertIdResponseGet( + alertId: string, + options?: AxiosRequestConfig, + ) { return AlertsApiFp(this.configuration) - .getAlertAlertsAlertIdGet(alertId, options) + .getAlertResponseAlertsRequestAlertIdResponseGet(alertId, options) .then((request) => request(this.axios, this.basePath)); } /** - * - * @summary Get Alerts + * Returns all the alerts associated to a task ID. Provides the option to only return alerts that have not been responded to yet. + * @summary Get Alerts Of Task + * @param {string} taskId + * @param {boolean} [unresponded] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlertsApi + */ + public getAlertsOfTaskAlertsRequestsTaskTaskIdGet( + taskId: string, + unresponded?: boolean, + options?: AxiosRequestConfig, + ) { + return AlertsApiFp(this.configuration) + .getAlertsOfTaskAlertsRequestsTaskTaskIdGet(taskId, unresponded, options) + .then((request) => request(this.axios, this.basePath)); + } + + /** + * Returns the list of alert IDs that have yet to be responded to, while a response was required. + * @summary Get Unresponded Alerts + * @param {Pagination} [pagination] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlertsApi + */ + public getUnrespondedAlertsAlertsUnrespondedRequestsGet( + pagination?: Pagination, + options?: AxiosRequestConfig, + ) { + return AlertsApiFp(this.configuration) + .getUnrespondedAlertsAlertsUnrespondedRequestsGet(pagination, options) + .then((request) => request(this.axios, this.basePath)); + } + + /** + * Responds to an existing alert. The response must be one of the available responses listed in the alert. + * @summary Respond To Alert + * @param {string} alertId + * @param {string} response * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AlertsApi */ - public getAlertsAlertsGet(options?: AxiosRequestConfig) { + public respondToAlertAlertsRequestAlertIdRespondPost( + alertId: string, + response: string, + options?: AxiosRequestConfig, + ) { return AlertsApiFp(this.configuration) - .getAlertsAlertsGet(options) + .respondToAlertAlertsRequestAlertIdRespondPost(alertId, response, options) .then((request) => request(this.axios, this.basePath)); } } @@ -5904,7 +6242,7 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati }; }, /** - * # NOTE: This endpoint is here for documentation purposes only, this is _not_ a REST endpoint. ## About This exposes a minimal pubsub system built on top of socket.io. It works similar to a normal socket.io endpoint, except that are 2 special rooms which control subscriptions. ## Rooms ### subscribe Clients must send a message to this room to start receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### unsubscribe Clients can send a message to this room to stop receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### /alerts ``` { \"title\": \"Alert\", \"description\": \"General alert that can be triggered by events.\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"original_id\": { \"title\": \"Original Id\", \"maxLength\": 255, \"type\": \"string\" }, \"category\": { \"title\": \"Category\", \"description\": \"Default: default
Task: task
Fleet: fleet
Robot: robot\", \"maxLength\": 7, \"type\": \"string\" }, \"unix_millis_created_time\": { \"title\": \"Unix Millis Created Time\", \"minimum\": -9223372036854775808, \"maximum\": 9223372036854775807, \"type\": \"integer\" }, \"acknowledged_by\": { \"title\": \"Acknowledged By\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"unix_millis_acknowledged_time\": { \"title\": \"Unix Millis Acknowledged Time\", \"minimum\": -9223372036854775808, \"maximum\": 9223372036854775807, \"nullable\": true, \"type\": \"integer\" } }, \"required\": [ \"id\", \"original_id\", \"category\", \"unix_millis_created_time\" ], \"additionalProperties\": false } ``` ### /beacons ``` { \"title\": \"BeaconState\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"online\": { \"title\": \"Online\", \"type\": \"boolean\" }, \"category\": { \"title\": \"Category\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"activated\": { \"title\": \"Activated\", \"type\": \"boolean\" }, \"level\": { \"title\": \"Level\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" } }, \"required\": [ \"id\", \"online\", \"activated\" ], \"additionalProperties\": false } ``` ### /building_map ``` { \"title\": \"BuildingMap\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Level\" } }, \"lifts\": { \"title\": \"Lifts\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Lift\" } } }, \"required\": [ \"name\", \"levels\", \"lifts\" ], \"definitions\": { \"AffineImage\": { \"title\": \"AffineImage\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x_offset\": { \"title\": \"X Offset\", \"default\": 0, \"type\": \"number\" }, \"y_offset\": { \"title\": \"Y Offset\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"scale\": { \"title\": \"Scale\", \"default\": 0, \"type\": \"number\" }, \"encoding\": { \"title\": \"Encoding\", \"default\": \"\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"string\" } }, \"required\": [ \"name\", \"x_offset\", \"y_offset\", \"yaw\", \"scale\", \"encoding\", \"data\" ] }, \"Place\": { \"title\": \"Place\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"position_tolerance\": { \"title\": \"Position Tolerance\", \"default\": 0, \"type\": \"number\" }, \"yaw_tolerance\": { \"title\": \"Yaw Tolerance\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"x\", \"y\", \"yaw\", \"position_tolerance\", \"yaw_tolerance\" ] }, \"Door\": { \"title\": \"Door\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"v1_x\": { \"title\": \"V1 X\", \"default\": 0, \"type\": \"number\" }, \"v1_y\": { \"title\": \"V1 Y\", \"default\": 0, \"type\": \"number\" }, \"v2_x\": { \"title\": \"V2 X\", \"default\": 0, \"type\": \"number\" }, \"v2_y\": { \"title\": \"V2 Y\", \"default\": 0, \"type\": \"number\" }, \"door_type\": { \"title\": \"Door Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_range\": { \"title\": \"Motion Range\", \"default\": 0, \"type\": \"number\" }, \"motion_direction\": { \"title\": \"Motion Direction\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" } }, \"required\": [ \"name\", \"v1_x\", \"v1_y\", \"v2_x\", \"v2_y\", \"door_type\", \"motion_range\", \"motion_direction\" ] }, \"Param\": { \"title\": \"Param\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"value_int\": { \"title\": \"Value Int\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"value_float\": { \"title\": \"Value Float\", \"default\": 0, \"type\": \"number\" }, \"value_string\": { \"title\": \"Value String\", \"default\": \"\", \"type\": \"string\" }, \"value_bool\": { \"title\": \"Value Bool\", \"default\": false, \"type\": \"boolean\" } }, \"required\": [ \"name\", \"type\", \"value_int\", \"value_float\", \"value_string\", \"value_bool\" ] }, \"GraphNode\": { \"title\": \"GraphNode\", \"type\": \"object\", \"properties\": { \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"x\", \"y\", \"name\", \"params\" ] }, \"GraphEdge\": { \"title\": \"GraphEdge\", \"type\": \"object\", \"properties\": { \"v1_idx\": { \"title\": \"V1 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"v2_idx\": { \"title\": \"V2 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } }, \"edge_type\": { \"title\": \"Edge Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" } }, \"required\": [ \"v1_idx\", \"v2_idx\", \"params\", \"edge_type\" ] }, \"Graph\": { \"title\": \"Graph\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"vertices\": { \"title\": \"Vertices\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphNode\" } }, \"edges\": { \"title\": \"Edges\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphEdge\" } }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"name\", \"vertices\", \"edges\", \"params\" ] }, \"Level\": { \"title\": \"Level\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"elevation\": { \"title\": \"Elevation\", \"default\": 0, \"type\": \"number\" }, \"images\": { \"title\": \"Images\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AffineImage\" } }, \"places\": { \"title\": \"Places\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Place\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"nav_graphs\": { \"title\": \"Nav Graphs\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Graph\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] } }, \"required\": [ \"name\", \"elevation\", \"images\", \"places\", \"doors\", \"nav_graphs\", \"wall_graph\" ] }, \"Lift\": { \"title\": \"Lift\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] }, \"ref_x\": { \"title\": \"Ref X\", \"default\": 0, \"type\": \"number\" }, \"ref_y\": { \"title\": \"Ref Y\", \"default\": 0, \"type\": \"number\" }, \"ref_yaw\": { \"title\": \"Ref Yaw\", \"default\": 0, \"type\": \"number\" }, \"width\": { \"title\": \"Width\", \"default\": 0, \"type\": \"number\" }, \"depth\": { \"title\": \"Depth\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"levels\", \"doors\", \"wall_graph\", \"ref_x\", \"ref_y\", \"ref_yaw\", \"width\", \"depth\" ] } } } ``` ### /building_map/fire_alarm_trigger ``` { \"title\": \"FireAlarmTriggerState\", \"type\": \"object\", \"properties\": { \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"trigger\": { \"title\": \"Trigger\", \"type\": \"boolean\" } }, \"required\": [ \"unix_millis_time\", \"trigger\" ] } ``` ### /delivery_alerts ``` { \"title\": \"DeliveryAlert\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"action\": { \"$ref\": \"#/definitions/Action\" }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" } }, \"required\": [ \"id\", \"category\", \"tier\", \"action\", \"task_id\", \"message\" ], \"definitions\": { \"Category\": { \"title\": \"Category\", \"description\": \"An enumeration.\", \"enum\": [ \"missing\", \"wrong\", \"obstructed\", \"cancelled\" ], \"type\": \"string\" }, \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"warning\", \"error\" ], \"type\": \"string\" }, \"Action\": { \"title\": \"Action\", \"description\": \"An enumeration.\", \"enum\": [ \"waiting\", \"cancelled\", \"override\", \"resume\" ], \"type\": \"string\" } } } ``` ### /doors/{door_name}/state ``` { \"title\": \"DoorState\", \"type\": \"object\", \"properties\": { \"door_time\": { \"title\": \"Door Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"door_name\": { \"title\": \"Door Name\", \"default\": \"\", \"type\": \"string\" }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": { \"value\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/DoorMode\" } ] } }, \"required\": [ \"door_time\", \"door_name\", \"current_mode\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] }, \"DoorMode\": { \"title\": \"DoorMode\", \"type\": \"object\", \"properties\": { \"value\": { \"title\": \"Value\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"value\" ] } } } ``` ### /doors/{door_name}/health ``` { \"title\": \"DoorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /lifts/{lift_name}/state ``` { \"title\": \"LiftState\", \"type\": \"object\", \"properties\": { \"lift_time\": { \"title\": \"Lift Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"lift_name\": { \"title\": \"Lift Name\", \"default\": \"\", \"type\": \"string\" }, \"available_floors\": { \"title\": \"Available Floors\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"current_floor\": { \"title\": \"Current Floor\", \"default\": \"\", \"type\": \"string\" }, \"destination_floor\": { \"title\": \"Destination Floor\", \"default\": \"\", \"type\": \"string\" }, \"door_state\": { \"title\": \"Door State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_state\": { \"title\": \"Motion State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"available_modes\": { \"title\": \"Available Modes\", \"type\": \"array\", \"items\": { \"type\": \"integer\" } }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"session_id\": { \"title\": \"Session Id\", \"default\": \"\", \"type\": \"string\" } }, \"required\": [ \"lift_time\", \"lift_name\", \"available_floors\", \"current_floor\", \"destination_floor\", \"door_state\", \"motion_state\", \"available_modes\", \"current_mode\", \"session_id\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /lifts/{lift_name}/health ``` { \"title\": \"LiftHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /tasks/{task_id}/state ``` { \"title\": \"TaskState\", \"type\": \"object\", \"properties\": { \"booking\": { \"$ref\": \"#/definitions/Booking\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"assigned_to\": { \"title\": \"Assigned To\", \"description\": \"Which agent (robot) is the task assigned to\", \"allOf\": [ { \"$ref\": \"#/definitions/AssignedTo\" } ] }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"dispatch\": { \"$ref\": \"#/definitions/Dispatch\" }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary of the states of the phases of the task. The keys (property names) are phase IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phase\" } }, \"completed\": { \"title\": \"Completed\", \"description\": \"An array of the IDs of completed phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"active\": { \"title\": \"Active\", \"description\": \"The ID of the active phase for this task\", \"allOf\": [ { \"$ref\": \"#/definitions/Id\" } ] }, \"pending\": { \"title\": \"Pending\", \"description\": \"An array of the pending phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"interruptions\": { \"title\": \"Interruptions\", \"description\": \"A dictionary of interruptions that have been applied to this task. The keys (property names) are the unique token of the interruption request.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Interruption\" } }, \"cancellation\": { \"title\": \"Cancellation\", \"description\": \"If the task was cancelled, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Cancellation\" } ] }, \"killed\": { \"title\": \"Killed\", \"description\": \"If the task was killed, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Killed\" } ] } }, \"required\": [ \"booking\" ], \"definitions\": { \"Booking\": { \"title\": \"Booking\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"description\": \"The unique identifier for this task\", \"type\": \"string\" }, \"unix_millis_earliest_start_time\": { \"title\": \"Unix Millis Earliest Start Time\", \"type\": \"integer\" }, \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"type\": \"integer\" }, \"priority\": { \"title\": \"Priority\", \"description\": \"Priority information about this task\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"string\" } ] }, \"labels\": { \"title\": \"Labels\", \"description\": \"Information about how and why this task was booked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requester\": { \"title\": \"Requester\", \"description\": \"(Optional) An identifier for the entity that requested this task\", \"type\": \"string\" } }, \"required\": [ \"id\" ] }, \"Category\": { \"title\": \"Category\", \"description\": \"The category of this task or phase\", \"type\": \"string\" }, \"Detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about a task, phase, or event\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] }, \"EstimateMillis\": { \"title\": \"EstimateMillis\", \"description\": \"An estimate, in milliseconds, of how long the subject will take to complete\", \"minimum\": 0, \"type\": \"integer\" }, \"AssignedTo\": { \"title\": \"AssignedTo\", \"type\": \"object\", \"properties\": { \"group\": { \"title\": \"Group\", \"type\": \"string\" }, \"name\": { \"title\": \"Name\", \"type\": \"string\" } }, \"required\": [ \"group\", \"name\" ] }, \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"blocked\", \"error\", \"failed\", \"queued\", \"standby\", \"underway\", \"delayed\", \"skipped\", \"canceled\", \"killed\", \"completed\" ] }, \"Status1\": { \"title\": \"Status1\", \"description\": \"An enumeration.\", \"enum\": [ \"queued\", \"selected\", \"dispatched\", \"failed_to_assign\", \"canceled_in_flight\" ] }, \"Assignment\": { \"title\": \"Assignment\", \"type\": \"object\", \"properties\": { \"fleet_name\": { \"title\": \"Fleet Name\", \"type\": \"string\" }, \"expected_robot_name\": { \"title\": \"Expected Robot Name\", \"type\": \"string\" } } }, \"Error\": { \"title\": \"Error\", \"type\": \"object\", \"properties\": { \"code\": { \"title\": \"Code\", \"description\": \"A standard code for the kind of error that has occurred\", \"minimum\": 0, \"type\": \"integer\" }, \"category\": { \"title\": \"Category\", \"description\": \"The category of the error\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Details about the error\", \"type\": \"string\" } } }, \"Dispatch\": { \"title\": \"Dispatch\", \"type\": \"object\", \"properties\": { \"status\": { \"$ref\": \"#/definitions/Status1\" }, \"assignment\": { \"$ref\": \"#/definitions/Assignment\" }, \"errors\": { \"title\": \"Errors\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Error\" } } }, \"required\": [ \"status\" ] }, \"Id\": { \"title\": \"Id\", \"minimum\": 0, \"type\": \"integer\" }, \"EventState\": { \"title\": \"EventState\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"name\": { \"title\": \"Name\", \"description\": \"The brief name of the event\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the event\", \"allOf\": [ { \"$ref\": \"#/definitions/Detail\" } ] }, \"deps\": { \"title\": \"Deps\", \"description\": \"This event may depend on other events. This array contains the IDs of those other event dependencies.\", \"type\": \"array\", \"items\": { \"type\": \"integer\", \"minimum\": 0 } } }, \"required\": [ \"id\" ] }, \"Undo\": { \"title\": \"Undo\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the undo skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the undo skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"SkipPhaseRequest\": { \"title\": \"SkipPhaseRequest\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"undo\": { \"title\": \"Undo\", \"description\": \"Information about an undo skip request that applied to this request\", \"allOf\": [ { \"$ref\": \"#/definitions/Undo\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Phase\": { \"title\": \"Phase\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"final_event_id\": { \"$ref\": \"#/definitions/Id\" }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary of events for this phase. The keys (property names) are the event IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/EventState\" } }, \"skip_requests\": { \"title\": \"Skip Requests\", \"description\": \"Information about any skip requests that have been received\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/SkipPhaseRequest\" } } }, \"required\": [ \"id\" ] }, \"ResumedBy\": { \"title\": \"ResumedBy\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the resume request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the resume request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"labels\" ] }, \"Interruption\": { \"title\": \"Interruption\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the interruption request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the interruption\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"resumed_by\": { \"title\": \"Resumed By\", \"description\": \"Information about the resume request that ended this interruption. This field will be missing if the interruption is still active.\", \"allOf\": [ { \"$ref\": \"#/definitions/ResumedBy\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Cancellation\": { \"title\": \"Cancellation\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the cancel request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Killed\": { \"title\": \"Killed\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the kill request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] } } } ``` ### /tasks/{task_id}/log ``` { \"title\": \"TaskEventLog\", \"type\": \"object\", \"properties\": { \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary whose keys (property names) are the indices of a phase\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phases\" } } }, \"required\": [ \"task_id\" ], \"additionalProperties\": false, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] }, \"Phases\": { \"title\": \"Phases\", \"type\": \"object\", \"properties\": { \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall phase\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary whose keys (property names) are the indices of an event in the phase\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"additionalProperties\": false } } } ``` ### /dispensers/{guid}/state ``` { \"title\": \"DispenserState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /dispensers/{guid}/health ``` { \"title\": \"DispenserHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /ingestors/{guid}/state ``` { \"title\": \"IngestorState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /ingestors/{guid}/health ``` { \"title\": \"IngestorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /fleets/{name}/state ``` { \"title\": \"FleetState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"robots\": { \"title\": \"Robots\", \"description\": \"A dictionary of the states of the robots that belong to this fleet\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/RobotState\" } } }, \"definitions\": { \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"offline\", \"shutdown\", \"idle\", \"charging\", \"working\", \"error\" ] }, \"Location2D\": { \"title\": \"Location2D\", \"type\": \"object\", \"properties\": { \"map\": { \"title\": \"Map\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"type\": \"number\" } }, \"required\": [ \"map\", \"x\", \"y\", \"yaw\" ] }, \"Issue\": { \"title\": \"Issue\", \"type\": \"object\", \"properties\": { \"category\": { \"title\": \"Category\", \"description\": \"Category of the robot\'s issue\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the issue\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] } } }, \"Commission\": { \"title\": \"Commission\", \"type\": \"object\", \"properties\": { \"dispatch_tasks\": { \"title\": \"Dispatch Tasks\", \"description\": \"Should the robot accept dispatched tasks, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"direct_tasks\": { \"title\": \"Direct Tasks\", \"description\": \"Should the robot accept direct task requests, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"idle_behavior\": { \"title\": \"Idle Behavior\", \"description\": \"Should the robot perform its idle behavior, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" } } }, \"MutexGroups\": { \"title\": \"MutexGroups\", \"type\": \"object\", \"properties\": { \"locked\": { \"title\": \"Locked\", \"description\": \"A list of mutex groups that this robot has currently locked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requesting\": { \"title\": \"Requesting\", \"description\": \"A list of the mutex groups that this robot is currently requesting but has not lockd yet\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } } }, \"RobotState\": { \"title\": \"RobotState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"status\": { \"description\": \"A simple token representing the status of the robot\", \"allOf\": [ { \"$ref\": \"#/definitions/Status\" } ] }, \"task_id\": { \"title\": \"Task Id\", \"description\": \"The ID of the task this robot is currently working on. Empty string if the robot is not working on a task.\", \"type\": \"string\" }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"location\": { \"$ref\": \"#/definitions/Location2D\" }, \"battery\": { \"title\": \"Battery\", \"description\": \"State of charge of the battery. Values range from 0.0 (depleted) to 1.0 (fully charged)\", \"minimum\": 0.0, \"maximum\": 1.0, \"type\": \"number\" }, \"issues\": { \"title\": \"Issues\", \"description\": \"A list of issues with the robot that operators need to address\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Issue\" } }, \"commission\": { \"$ref\": \"#/definitions/Commission\" }, \"mutex_groups\": { \"title\": \"Mutex Groups\", \"description\": \"Information about the mutex groups that this robot is interacting with\", \"allOf\": [ { \"$ref\": \"#/definitions/MutexGroups\" } ] } } } } } ``` ### /fleets/{name}/log ``` { \"title\": \"FleetLog\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log for the overall fleet\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"robots\": { \"title\": \"Robots\", \"description\": \"Dictionary of logs for the individual robots. The keys (property names) are the robot names.\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] } } } ``` + * # NOTE: This endpoint is here for documentation purposes only, this is _not_ a REST endpoint. ## About This exposes a minimal pubsub system built on top of socket.io. It works similar to a normal socket.io endpoint, except that are 2 special rooms which control subscriptions. ## Rooms ### subscribe Clients must send a message to this room to start receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### unsubscribe Clients can send a message to this room to stop receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### /alerts/requests ``` { \"title\": \"AlertRequest\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"unix_millis_alert_time\": { \"title\": \"Unix Millis Alert Time\", \"type\": \"integer\" }, \"title\": { \"title\": \"Title\", \"type\": \"string\" }, \"subtitle\": { \"title\": \"Subtitle\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" }, \"display\": { \"title\": \"Display\", \"type\": \"boolean\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"responses_available\": { \"title\": \"Responses Available\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"alert_parameters\": { \"title\": \"Alert Parameters\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AlertParameter\" } }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" } }, \"required\": [ \"id\", \"unix_millis_alert_time\", \"title\", \"subtitle\", \"message\", \"display\", \"tier\", \"responses_available\", \"alert_parameters\" ], \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"info\", \"warning\", \"error\" ], \"type\": \"string\" }, \"AlertParameter\": { \"title\": \"AlertParameter\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"value\": { \"title\": \"Value\", \"type\": \"string\" } }, \"required\": [ \"name\", \"value\" ] } } } ``` ### /alerts/responses ``` { \"title\": \"AlertResponse\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"unix_millis_response_time\": { \"title\": \"Unix Millis Response Time\", \"type\": \"integer\" }, \"response\": { \"title\": \"Response\", \"type\": \"string\" } }, \"required\": [ \"id\", \"unix_millis_response_time\", \"response\" ] } ``` ### /beacons ``` { \"title\": \"BeaconState\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"online\": { \"title\": \"Online\", \"type\": \"boolean\" }, \"category\": { \"title\": \"Category\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"activated\": { \"title\": \"Activated\", \"type\": \"boolean\" }, \"level\": { \"title\": \"Level\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" } }, \"required\": [ \"id\", \"online\", \"activated\" ], \"additionalProperties\": false } ``` ### /building_map ``` { \"title\": \"BuildingMap\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Level\" } }, \"lifts\": { \"title\": \"Lifts\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Lift\" } } }, \"required\": [ \"name\", \"levels\", \"lifts\" ], \"definitions\": { \"AffineImage\": { \"title\": \"AffineImage\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x_offset\": { \"title\": \"X Offset\", \"default\": 0, \"type\": \"number\" }, \"y_offset\": { \"title\": \"Y Offset\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"scale\": { \"title\": \"Scale\", \"default\": 0, \"type\": \"number\" }, \"encoding\": { \"title\": \"Encoding\", \"default\": \"\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"string\" } }, \"required\": [ \"name\", \"x_offset\", \"y_offset\", \"yaw\", \"scale\", \"encoding\", \"data\" ] }, \"Place\": { \"title\": \"Place\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"position_tolerance\": { \"title\": \"Position Tolerance\", \"default\": 0, \"type\": \"number\" }, \"yaw_tolerance\": { \"title\": \"Yaw Tolerance\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"x\", \"y\", \"yaw\", \"position_tolerance\", \"yaw_tolerance\" ] }, \"Door\": { \"title\": \"Door\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"v1_x\": { \"title\": \"V1 X\", \"default\": 0, \"type\": \"number\" }, \"v1_y\": { \"title\": \"V1 Y\", \"default\": 0, \"type\": \"number\" }, \"v2_x\": { \"title\": \"V2 X\", \"default\": 0, \"type\": \"number\" }, \"v2_y\": { \"title\": \"V2 Y\", \"default\": 0, \"type\": \"number\" }, \"door_type\": { \"title\": \"Door Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_range\": { \"title\": \"Motion Range\", \"default\": 0, \"type\": \"number\" }, \"motion_direction\": { \"title\": \"Motion Direction\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" } }, \"required\": [ \"name\", \"v1_x\", \"v1_y\", \"v2_x\", \"v2_y\", \"door_type\", \"motion_range\", \"motion_direction\" ] }, \"Param\": { \"title\": \"Param\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"value_int\": { \"title\": \"Value Int\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"value_float\": { \"title\": \"Value Float\", \"default\": 0, \"type\": \"number\" }, \"value_string\": { \"title\": \"Value String\", \"default\": \"\", \"type\": \"string\" }, \"value_bool\": { \"title\": \"Value Bool\", \"default\": false, \"type\": \"boolean\" } }, \"required\": [ \"name\", \"type\", \"value_int\", \"value_float\", \"value_string\", \"value_bool\" ] }, \"GraphNode\": { \"title\": \"GraphNode\", \"type\": \"object\", \"properties\": { \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"x\", \"y\", \"name\", \"params\" ] }, \"GraphEdge\": { \"title\": \"GraphEdge\", \"type\": \"object\", \"properties\": { \"v1_idx\": { \"title\": \"V1 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"v2_idx\": { \"title\": \"V2 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } }, \"edge_type\": { \"title\": \"Edge Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" } }, \"required\": [ \"v1_idx\", \"v2_idx\", \"params\", \"edge_type\" ] }, \"Graph\": { \"title\": \"Graph\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"vertices\": { \"title\": \"Vertices\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphNode\" } }, \"edges\": { \"title\": \"Edges\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphEdge\" } }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"name\", \"vertices\", \"edges\", \"params\" ] }, \"Level\": { \"title\": \"Level\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"elevation\": { \"title\": \"Elevation\", \"default\": 0, \"type\": \"number\" }, \"images\": { \"title\": \"Images\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AffineImage\" } }, \"places\": { \"title\": \"Places\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Place\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"nav_graphs\": { \"title\": \"Nav Graphs\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Graph\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] } }, \"required\": [ \"name\", \"elevation\", \"images\", \"places\", \"doors\", \"nav_graphs\", \"wall_graph\" ] }, \"Lift\": { \"title\": \"Lift\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] }, \"ref_x\": { \"title\": \"Ref X\", \"default\": 0, \"type\": \"number\" }, \"ref_y\": { \"title\": \"Ref Y\", \"default\": 0, \"type\": \"number\" }, \"ref_yaw\": { \"title\": \"Ref Yaw\", \"default\": 0, \"type\": \"number\" }, \"width\": { \"title\": \"Width\", \"default\": 0, \"type\": \"number\" }, \"depth\": { \"title\": \"Depth\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"levels\", \"doors\", \"wall_graph\", \"ref_x\", \"ref_y\", \"ref_yaw\", \"width\", \"depth\" ] } } } ``` ### /building_map/fire_alarm_trigger ``` { \"title\": \"FireAlarmTriggerState\", \"type\": \"object\", \"properties\": { \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"trigger\": { \"title\": \"Trigger\", \"type\": \"boolean\" } }, \"required\": [ \"unix_millis_time\", \"trigger\" ] } ``` ### /delivery_alerts ``` { \"title\": \"DeliveryAlert\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"action\": { \"$ref\": \"#/definitions/Action\" }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" } }, \"required\": [ \"id\", \"category\", \"tier\", \"action\", \"task_id\", \"message\" ], \"definitions\": { \"Category\": { \"title\": \"Category\", \"description\": \"An enumeration.\", \"enum\": [ \"missing\", \"wrong\", \"obstructed\", \"cancelled\" ], \"type\": \"string\" }, \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"warning\", \"error\" ], \"type\": \"string\" }, \"Action\": { \"title\": \"Action\", \"description\": \"An enumeration.\", \"enum\": [ \"waiting\", \"cancelled\", \"override\", \"resume\" ], \"type\": \"string\" } } } ``` ### /doors/{door_name}/state ``` { \"title\": \"DoorState\", \"type\": \"object\", \"properties\": { \"door_time\": { \"title\": \"Door Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"door_name\": { \"title\": \"Door Name\", \"default\": \"\", \"type\": \"string\" }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": { \"value\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/DoorMode\" } ] } }, \"required\": [ \"door_time\", \"door_name\", \"current_mode\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] }, \"DoorMode\": { \"title\": \"DoorMode\", \"type\": \"object\", \"properties\": { \"value\": { \"title\": \"Value\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"value\" ] } } } ``` ### /doors/{door_name}/health ``` { \"title\": \"DoorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /lifts/{lift_name}/state ``` { \"title\": \"LiftState\", \"type\": \"object\", \"properties\": { \"lift_time\": { \"title\": \"Lift Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"lift_name\": { \"title\": \"Lift Name\", \"default\": \"\", \"type\": \"string\" }, \"available_floors\": { \"title\": \"Available Floors\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"current_floor\": { \"title\": \"Current Floor\", \"default\": \"\", \"type\": \"string\" }, \"destination_floor\": { \"title\": \"Destination Floor\", \"default\": \"\", \"type\": \"string\" }, \"door_state\": { \"title\": \"Door State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_state\": { \"title\": \"Motion State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"available_modes\": { \"title\": \"Available Modes\", \"type\": \"array\", \"items\": { \"type\": \"integer\" } }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"session_id\": { \"title\": \"Session Id\", \"default\": \"\", \"type\": \"string\" } }, \"required\": [ \"lift_time\", \"lift_name\", \"available_floors\", \"current_floor\", \"destination_floor\", \"door_state\", \"motion_state\", \"available_modes\", \"current_mode\", \"session_id\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /lifts/{lift_name}/health ``` { \"title\": \"LiftHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /tasks/{task_id}/state ``` { \"title\": \"TaskState\", \"type\": \"object\", \"properties\": { \"booking\": { \"$ref\": \"#/definitions/Booking\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"assigned_to\": { \"title\": \"Assigned To\", \"description\": \"Which agent (robot) is the task assigned to\", \"allOf\": [ { \"$ref\": \"#/definitions/AssignedTo\" } ] }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"dispatch\": { \"$ref\": \"#/definitions/Dispatch\" }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary of the states of the phases of the task. The keys (property names) are phase IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phase\" } }, \"completed\": { \"title\": \"Completed\", \"description\": \"An array of the IDs of completed phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"active\": { \"title\": \"Active\", \"description\": \"The ID of the active phase for this task\", \"allOf\": [ { \"$ref\": \"#/definitions/Id\" } ] }, \"pending\": { \"title\": \"Pending\", \"description\": \"An array of the pending phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"interruptions\": { \"title\": \"Interruptions\", \"description\": \"A dictionary of interruptions that have been applied to this task. The keys (property names) are the unique token of the interruption request.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Interruption\" } }, \"cancellation\": { \"title\": \"Cancellation\", \"description\": \"If the task was cancelled, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Cancellation\" } ] }, \"killed\": { \"title\": \"Killed\", \"description\": \"If the task was killed, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Killed\" } ] } }, \"required\": [ \"booking\" ], \"definitions\": { \"Booking\": { \"title\": \"Booking\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"description\": \"The unique identifier for this task\", \"type\": \"string\" }, \"unix_millis_earliest_start_time\": { \"title\": \"Unix Millis Earliest Start Time\", \"type\": \"integer\" }, \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"type\": \"integer\" }, \"priority\": { \"title\": \"Priority\", \"description\": \"Priority information about this task\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"string\" } ] }, \"labels\": { \"title\": \"Labels\", \"description\": \"Information about how and why this task was booked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requester\": { \"title\": \"Requester\", \"description\": \"(Optional) An identifier for the entity that requested this task\", \"type\": \"string\" } }, \"required\": [ \"id\" ] }, \"Category\": { \"title\": \"Category\", \"description\": \"The category of this task or phase\", \"type\": \"string\" }, \"Detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about a task, phase, or event\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] }, \"EstimateMillis\": { \"title\": \"EstimateMillis\", \"description\": \"An estimate, in milliseconds, of how long the subject will take to complete\", \"minimum\": 0, \"type\": \"integer\" }, \"AssignedTo\": { \"title\": \"AssignedTo\", \"type\": \"object\", \"properties\": { \"group\": { \"title\": \"Group\", \"type\": \"string\" }, \"name\": { \"title\": \"Name\", \"type\": \"string\" } }, \"required\": [ \"group\", \"name\" ] }, \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"blocked\", \"error\", \"failed\", \"queued\", \"standby\", \"underway\", \"delayed\", \"skipped\", \"canceled\", \"killed\", \"completed\" ] }, \"Status1\": { \"title\": \"Status1\", \"description\": \"An enumeration.\", \"enum\": [ \"queued\", \"selected\", \"dispatched\", \"failed_to_assign\", \"canceled_in_flight\" ] }, \"Assignment\": { \"title\": \"Assignment\", \"type\": \"object\", \"properties\": { \"fleet_name\": { \"title\": \"Fleet Name\", \"type\": \"string\" }, \"expected_robot_name\": { \"title\": \"Expected Robot Name\", \"type\": \"string\" } } }, \"Error\": { \"title\": \"Error\", \"type\": \"object\", \"properties\": { \"code\": { \"title\": \"Code\", \"description\": \"A standard code for the kind of error that has occurred\", \"minimum\": 0, \"type\": \"integer\" }, \"category\": { \"title\": \"Category\", \"description\": \"The category of the error\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Details about the error\", \"type\": \"string\" } } }, \"Dispatch\": { \"title\": \"Dispatch\", \"type\": \"object\", \"properties\": { \"status\": { \"$ref\": \"#/definitions/Status1\" }, \"assignment\": { \"$ref\": \"#/definitions/Assignment\" }, \"errors\": { \"title\": \"Errors\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Error\" } } }, \"required\": [ \"status\" ] }, \"Id\": { \"title\": \"Id\", \"minimum\": 0, \"type\": \"integer\" }, \"EventState\": { \"title\": \"EventState\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"name\": { \"title\": \"Name\", \"description\": \"The brief name of the event\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the event\", \"allOf\": [ { \"$ref\": \"#/definitions/Detail\" } ] }, \"deps\": { \"title\": \"Deps\", \"description\": \"This event may depend on other events. This array contains the IDs of those other event dependencies.\", \"type\": \"array\", \"items\": { \"type\": \"integer\", \"minimum\": 0 } } }, \"required\": [ \"id\" ] }, \"Undo\": { \"title\": \"Undo\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the undo skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the undo skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"SkipPhaseRequest\": { \"title\": \"SkipPhaseRequest\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"undo\": { \"title\": \"Undo\", \"description\": \"Information about an undo skip request that applied to this request\", \"allOf\": [ { \"$ref\": \"#/definitions/Undo\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Phase\": { \"title\": \"Phase\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"final_event_id\": { \"$ref\": \"#/definitions/Id\" }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary of events for this phase. The keys (property names) are the event IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/EventState\" } }, \"skip_requests\": { \"title\": \"Skip Requests\", \"description\": \"Information about any skip requests that have been received\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/SkipPhaseRequest\" } } }, \"required\": [ \"id\" ] }, \"ResumedBy\": { \"title\": \"ResumedBy\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the resume request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the resume request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"labels\" ] }, \"Interruption\": { \"title\": \"Interruption\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the interruption request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the interruption\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"resumed_by\": { \"title\": \"Resumed By\", \"description\": \"Information about the resume request that ended this interruption. This field will be missing if the interruption is still active.\", \"allOf\": [ { \"$ref\": \"#/definitions/ResumedBy\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Cancellation\": { \"title\": \"Cancellation\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the cancel request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Killed\": { \"title\": \"Killed\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the kill request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] } } } ``` ### /tasks/{task_id}/log ``` { \"title\": \"TaskEventLog\", \"type\": \"object\", \"properties\": { \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary whose keys (property names) are the indices of a phase\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phases\" } } }, \"required\": [ \"task_id\" ], \"additionalProperties\": false, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] }, \"Phases\": { \"title\": \"Phases\", \"type\": \"object\", \"properties\": { \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall phase\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary whose keys (property names) are the indices of an event in the phase\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"additionalProperties\": false } } } ``` ### /dispensers/{guid}/state ``` { \"title\": \"DispenserState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /dispensers/{guid}/health ``` { \"title\": \"DispenserHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /ingestors/{guid}/state ``` { \"title\": \"IngestorState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /ingestors/{guid}/health ``` { \"title\": \"IngestorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /fleets/{name}/state ``` { \"title\": \"FleetState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"robots\": { \"title\": \"Robots\", \"description\": \"A dictionary of the states of the robots that belong to this fleet\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/RobotState\" } } }, \"definitions\": { \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"offline\", \"shutdown\", \"idle\", \"charging\", \"working\", \"error\" ] }, \"Location2D\": { \"title\": \"Location2D\", \"type\": \"object\", \"properties\": { \"map\": { \"title\": \"Map\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"type\": \"number\" } }, \"required\": [ \"map\", \"x\", \"y\", \"yaw\" ] }, \"Issue\": { \"title\": \"Issue\", \"type\": \"object\", \"properties\": { \"category\": { \"title\": \"Category\", \"description\": \"Category of the robot\'s issue\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the issue\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] } } }, \"Commission\": { \"title\": \"Commission\", \"type\": \"object\", \"properties\": { \"dispatch_tasks\": { \"title\": \"Dispatch Tasks\", \"description\": \"Should the robot accept dispatched tasks, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"direct_tasks\": { \"title\": \"Direct Tasks\", \"description\": \"Should the robot accept direct task requests, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"idle_behavior\": { \"title\": \"Idle Behavior\", \"description\": \"Should the robot perform its idle behavior, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" } } }, \"MutexGroups\": { \"title\": \"MutexGroups\", \"type\": \"object\", \"properties\": { \"locked\": { \"title\": \"Locked\", \"description\": \"A list of mutex groups that this robot has currently locked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requesting\": { \"title\": \"Requesting\", \"description\": \"A list of the mutex groups that this robot is currently requesting but has not lockd yet\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } } }, \"RobotState\": { \"title\": \"RobotState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"status\": { \"description\": \"A simple token representing the status of the robot\", \"allOf\": [ { \"$ref\": \"#/definitions/Status\" } ] }, \"task_id\": { \"title\": \"Task Id\", \"description\": \"The ID of the task this robot is currently working on. Empty string if the robot is not working on a task.\", \"type\": \"string\" }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"location\": { \"$ref\": \"#/definitions/Location2D\" }, \"battery\": { \"title\": \"Battery\", \"description\": \"State of charge of the battery. Values range from 0.0 (depleted) to 1.0 (fully charged)\", \"minimum\": 0.0, \"maximum\": 1.0, \"type\": \"number\" }, \"issues\": { \"title\": \"Issues\", \"description\": \"A list of issues with the robot that operators need to address\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Issue\" } }, \"commission\": { \"$ref\": \"#/definitions/Commission\" }, \"mutex_groups\": { \"title\": \"Mutex Groups\", \"description\": \"Information about the mutex groups that this robot is interacting with\", \"allOf\": [ { \"$ref\": \"#/definitions/MutexGroups\" } ] } } } } } ``` ### /fleets/{name}/log ``` { \"title\": \"FleetLog\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log for the overall fleet\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"robots\": { \"title\": \"Robots\", \"description\": \"Dictionary of logs for the individual robots. The keys (property names) are the robot names.\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] } } } ``` ### /rios ``` { \"title\": \"Rio\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"object\" } }, \"required\": [ \"id\", \"type\", \"data\" ] } ``` * @summary Socket.io endpoint * @param {*} [options] Override http request option. * @throws {RequiredError} @@ -5983,7 +6321,7 @@ export const DefaultApiFp = function (configuration?: Configuration) { return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** - * # NOTE: This endpoint is here for documentation purposes only, this is _not_ a REST endpoint. ## About This exposes a minimal pubsub system built on top of socket.io. It works similar to a normal socket.io endpoint, except that are 2 special rooms which control subscriptions. ## Rooms ### subscribe Clients must send a message to this room to start receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### unsubscribe Clients can send a message to this room to stop receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### /alerts ``` { \"title\": \"Alert\", \"description\": \"General alert that can be triggered by events.\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"original_id\": { \"title\": \"Original Id\", \"maxLength\": 255, \"type\": \"string\" }, \"category\": { \"title\": \"Category\", \"description\": \"Default: default
Task: task
Fleet: fleet
Robot: robot\", \"maxLength\": 7, \"type\": \"string\" }, \"unix_millis_created_time\": { \"title\": \"Unix Millis Created Time\", \"minimum\": -9223372036854775808, \"maximum\": 9223372036854775807, \"type\": \"integer\" }, \"acknowledged_by\": { \"title\": \"Acknowledged By\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"unix_millis_acknowledged_time\": { \"title\": \"Unix Millis Acknowledged Time\", \"minimum\": -9223372036854775808, \"maximum\": 9223372036854775807, \"nullable\": true, \"type\": \"integer\" } }, \"required\": [ \"id\", \"original_id\", \"category\", \"unix_millis_created_time\" ], \"additionalProperties\": false } ``` ### /beacons ``` { \"title\": \"BeaconState\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"online\": { \"title\": \"Online\", \"type\": \"boolean\" }, \"category\": { \"title\": \"Category\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"activated\": { \"title\": \"Activated\", \"type\": \"boolean\" }, \"level\": { \"title\": \"Level\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" } }, \"required\": [ \"id\", \"online\", \"activated\" ], \"additionalProperties\": false } ``` ### /building_map ``` { \"title\": \"BuildingMap\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Level\" } }, \"lifts\": { \"title\": \"Lifts\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Lift\" } } }, \"required\": [ \"name\", \"levels\", \"lifts\" ], \"definitions\": { \"AffineImage\": { \"title\": \"AffineImage\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x_offset\": { \"title\": \"X Offset\", \"default\": 0, \"type\": \"number\" }, \"y_offset\": { \"title\": \"Y Offset\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"scale\": { \"title\": \"Scale\", \"default\": 0, \"type\": \"number\" }, \"encoding\": { \"title\": \"Encoding\", \"default\": \"\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"string\" } }, \"required\": [ \"name\", \"x_offset\", \"y_offset\", \"yaw\", \"scale\", \"encoding\", \"data\" ] }, \"Place\": { \"title\": \"Place\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"position_tolerance\": { \"title\": \"Position Tolerance\", \"default\": 0, \"type\": \"number\" }, \"yaw_tolerance\": { \"title\": \"Yaw Tolerance\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"x\", \"y\", \"yaw\", \"position_tolerance\", \"yaw_tolerance\" ] }, \"Door\": { \"title\": \"Door\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"v1_x\": { \"title\": \"V1 X\", \"default\": 0, \"type\": \"number\" }, \"v1_y\": { \"title\": \"V1 Y\", \"default\": 0, \"type\": \"number\" }, \"v2_x\": { \"title\": \"V2 X\", \"default\": 0, \"type\": \"number\" }, \"v2_y\": { \"title\": \"V2 Y\", \"default\": 0, \"type\": \"number\" }, \"door_type\": { \"title\": \"Door Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_range\": { \"title\": \"Motion Range\", \"default\": 0, \"type\": \"number\" }, \"motion_direction\": { \"title\": \"Motion Direction\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" } }, \"required\": [ \"name\", \"v1_x\", \"v1_y\", \"v2_x\", \"v2_y\", \"door_type\", \"motion_range\", \"motion_direction\" ] }, \"Param\": { \"title\": \"Param\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"value_int\": { \"title\": \"Value Int\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"value_float\": { \"title\": \"Value Float\", \"default\": 0, \"type\": \"number\" }, \"value_string\": { \"title\": \"Value String\", \"default\": \"\", \"type\": \"string\" }, \"value_bool\": { \"title\": \"Value Bool\", \"default\": false, \"type\": \"boolean\" } }, \"required\": [ \"name\", \"type\", \"value_int\", \"value_float\", \"value_string\", \"value_bool\" ] }, \"GraphNode\": { \"title\": \"GraphNode\", \"type\": \"object\", \"properties\": { \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"x\", \"y\", \"name\", \"params\" ] }, \"GraphEdge\": { \"title\": \"GraphEdge\", \"type\": \"object\", \"properties\": { \"v1_idx\": { \"title\": \"V1 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"v2_idx\": { \"title\": \"V2 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } }, \"edge_type\": { \"title\": \"Edge Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" } }, \"required\": [ \"v1_idx\", \"v2_idx\", \"params\", \"edge_type\" ] }, \"Graph\": { \"title\": \"Graph\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"vertices\": { \"title\": \"Vertices\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphNode\" } }, \"edges\": { \"title\": \"Edges\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphEdge\" } }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"name\", \"vertices\", \"edges\", \"params\" ] }, \"Level\": { \"title\": \"Level\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"elevation\": { \"title\": \"Elevation\", \"default\": 0, \"type\": \"number\" }, \"images\": { \"title\": \"Images\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AffineImage\" } }, \"places\": { \"title\": \"Places\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Place\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"nav_graphs\": { \"title\": \"Nav Graphs\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Graph\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] } }, \"required\": [ \"name\", \"elevation\", \"images\", \"places\", \"doors\", \"nav_graphs\", \"wall_graph\" ] }, \"Lift\": { \"title\": \"Lift\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] }, \"ref_x\": { \"title\": \"Ref X\", \"default\": 0, \"type\": \"number\" }, \"ref_y\": { \"title\": \"Ref Y\", \"default\": 0, \"type\": \"number\" }, \"ref_yaw\": { \"title\": \"Ref Yaw\", \"default\": 0, \"type\": \"number\" }, \"width\": { \"title\": \"Width\", \"default\": 0, \"type\": \"number\" }, \"depth\": { \"title\": \"Depth\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"levels\", \"doors\", \"wall_graph\", \"ref_x\", \"ref_y\", \"ref_yaw\", \"width\", \"depth\" ] } } } ``` ### /building_map/fire_alarm_trigger ``` { \"title\": \"FireAlarmTriggerState\", \"type\": \"object\", \"properties\": { \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"trigger\": { \"title\": \"Trigger\", \"type\": \"boolean\" } }, \"required\": [ \"unix_millis_time\", \"trigger\" ] } ``` ### /delivery_alerts ``` { \"title\": \"DeliveryAlert\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"action\": { \"$ref\": \"#/definitions/Action\" }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" } }, \"required\": [ \"id\", \"category\", \"tier\", \"action\", \"task_id\", \"message\" ], \"definitions\": { \"Category\": { \"title\": \"Category\", \"description\": \"An enumeration.\", \"enum\": [ \"missing\", \"wrong\", \"obstructed\", \"cancelled\" ], \"type\": \"string\" }, \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"warning\", \"error\" ], \"type\": \"string\" }, \"Action\": { \"title\": \"Action\", \"description\": \"An enumeration.\", \"enum\": [ \"waiting\", \"cancelled\", \"override\", \"resume\" ], \"type\": \"string\" } } } ``` ### /doors/{door_name}/state ``` { \"title\": \"DoorState\", \"type\": \"object\", \"properties\": { \"door_time\": { \"title\": \"Door Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"door_name\": { \"title\": \"Door Name\", \"default\": \"\", \"type\": \"string\" }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": { \"value\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/DoorMode\" } ] } }, \"required\": [ \"door_time\", \"door_name\", \"current_mode\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] }, \"DoorMode\": { \"title\": \"DoorMode\", \"type\": \"object\", \"properties\": { \"value\": { \"title\": \"Value\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"value\" ] } } } ``` ### /doors/{door_name}/health ``` { \"title\": \"DoorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /lifts/{lift_name}/state ``` { \"title\": \"LiftState\", \"type\": \"object\", \"properties\": { \"lift_time\": { \"title\": \"Lift Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"lift_name\": { \"title\": \"Lift Name\", \"default\": \"\", \"type\": \"string\" }, \"available_floors\": { \"title\": \"Available Floors\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"current_floor\": { \"title\": \"Current Floor\", \"default\": \"\", \"type\": \"string\" }, \"destination_floor\": { \"title\": \"Destination Floor\", \"default\": \"\", \"type\": \"string\" }, \"door_state\": { \"title\": \"Door State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_state\": { \"title\": \"Motion State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"available_modes\": { \"title\": \"Available Modes\", \"type\": \"array\", \"items\": { \"type\": \"integer\" } }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"session_id\": { \"title\": \"Session Id\", \"default\": \"\", \"type\": \"string\" } }, \"required\": [ \"lift_time\", \"lift_name\", \"available_floors\", \"current_floor\", \"destination_floor\", \"door_state\", \"motion_state\", \"available_modes\", \"current_mode\", \"session_id\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /lifts/{lift_name}/health ``` { \"title\": \"LiftHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /tasks/{task_id}/state ``` { \"title\": \"TaskState\", \"type\": \"object\", \"properties\": { \"booking\": { \"$ref\": \"#/definitions/Booking\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"assigned_to\": { \"title\": \"Assigned To\", \"description\": \"Which agent (robot) is the task assigned to\", \"allOf\": [ { \"$ref\": \"#/definitions/AssignedTo\" } ] }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"dispatch\": { \"$ref\": \"#/definitions/Dispatch\" }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary of the states of the phases of the task. The keys (property names) are phase IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phase\" } }, \"completed\": { \"title\": \"Completed\", \"description\": \"An array of the IDs of completed phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"active\": { \"title\": \"Active\", \"description\": \"The ID of the active phase for this task\", \"allOf\": [ { \"$ref\": \"#/definitions/Id\" } ] }, \"pending\": { \"title\": \"Pending\", \"description\": \"An array of the pending phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"interruptions\": { \"title\": \"Interruptions\", \"description\": \"A dictionary of interruptions that have been applied to this task. The keys (property names) are the unique token of the interruption request.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Interruption\" } }, \"cancellation\": { \"title\": \"Cancellation\", \"description\": \"If the task was cancelled, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Cancellation\" } ] }, \"killed\": { \"title\": \"Killed\", \"description\": \"If the task was killed, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Killed\" } ] } }, \"required\": [ \"booking\" ], \"definitions\": { \"Booking\": { \"title\": \"Booking\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"description\": \"The unique identifier for this task\", \"type\": \"string\" }, \"unix_millis_earliest_start_time\": { \"title\": \"Unix Millis Earliest Start Time\", \"type\": \"integer\" }, \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"type\": \"integer\" }, \"priority\": { \"title\": \"Priority\", \"description\": \"Priority information about this task\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"string\" } ] }, \"labels\": { \"title\": \"Labels\", \"description\": \"Information about how and why this task was booked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requester\": { \"title\": \"Requester\", \"description\": \"(Optional) An identifier for the entity that requested this task\", \"type\": \"string\" } }, \"required\": [ \"id\" ] }, \"Category\": { \"title\": \"Category\", \"description\": \"The category of this task or phase\", \"type\": \"string\" }, \"Detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about a task, phase, or event\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] }, \"EstimateMillis\": { \"title\": \"EstimateMillis\", \"description\": \"An estimate, in milliseconds, of how long the subject will take to complete\", \"minimum\": 0, \"type\": \"integer\" }, \"AssignedTo\": { \"title\": \"AssignedTo\", \"type\": \"object\", \"properties\": { \"group\": { \"title\": \"Group\", \"type\": \"string\" }, \"name\": { \"title\": \"Name\", \"type\": \"string\" } }, \"required\": [ \"group\", \"name\" ] }, \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"blocked\", \"error\", \"failed\", \"queued\", \"standby\", \"underway\", \"delayed\", \"skipped\", \"canceled\", \"killed\", \"completed\" ] }, \"Status1\": { \"title\": \"Status1\", \"description\": \"An enumeration.\", \"enum\": [ \"queued\", \"selected\", \"dispatched\", \"failed_to_assign\", \"canceled_in_flight\" ] }, \"Assignment\": { \"title\": \"Assignment\", \"type\": \"object\", \"properties\": { \"fleet_name\": { \"title\": \"Fleet Name\", \"type\": \"string\" }, \"expected_robot_name\": { \"title\": \"Expected Robot Name\", \"type\": \"string\" } } }, \"Error\": { \"title\": \"Error\", \"type\": \"object\", \"properties\": { \"code\": { \"title\": \"Code\", \"description\": \"A standard code for the kind of error that has occurred\", \"minimum\": 0, \"type\": \"integer\" }, \"category\": { \"title\": \"Category\", \"description\": \"The category of the error\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Details about the error\", \"type\": \"string\" } } }, \"Dispatch\": { \"title\": \"Dispatch\", \"type\": \"object\", \"properties\": { \"status\": { \"$ref\": \"#/definitions/Status1\" }, \"assignment\": { \"$ref\": \"#/definitions/Assignment\" }, \"errors\": { \"title\": \"Errors\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Error\" } } }, \"required\": [ \"status\" ] }, \"Id\": { \"title\": \"Id\", \"minimum\": 0, \"type\": \"integer\" }, \"EventState\": { \"title\": \"EventState\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"name\": { \"title\": \"Name\", \"description\": \"The brief name of the event\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the event\", \"allOf\": [ { \"$ref\": \"#/definitions/Detail\" } ] }, \"deps\": { \"title\": \"Deps\", \"description\": \"This event may depend on other events. This array contains the IDs of those other event dependencies.\", \"type\": \"array\", \"items\": { \"type\": \"integer\", \"minimum\": 0 } } }, \"required\": [ \"id\" ] }, \"Undo\": { \"title\": \"Undo\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the undo skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the undo skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"SkipPhaseRequest\": { \"title\": \"SkipPhaseRequest\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"undo\": { \"title\": \"Undo\", \"description\": \"Information about an undo skip request that applied to this request\", \"allOf\": [ { \"$ref\": \"#/definitions/Undo\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Phase\": { \"title\": \"Phase\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"final_event_id\": { \"$ref\": \"#/definitions/Id\" }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary of events for this phase. The keys (property names) are the event IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/EventState\" } }, \"skip_requests\": { \"title\": \"Skip Requests\", \"description\": \"Information about any skip requests that have been received\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/SkipPhaseRequest\" } } }, \"required\": [ \"id\" ] }, \"ResumedBy\": { \"title\": \"ResumedBy\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the resume request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the resume request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"labels\" ] }, \"Interruption\": { \"title\": \"Interruption\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the interruption request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the interruption\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"resumed_by\": { \"title\": \"Resumed By\", \"description\": \"Information about the resume request that ended this interruption. This field will be missing if the interruption is still active.\", \"allOf\": [ { \"$ref\": \"#/definitions/ResumedBy\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Cancellation\": { \"title\": \"Cancellation\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the cancel request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Killed\": { \"title\": \"Killed\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the kill request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] } } } ``` ### /tasks/{task_id}/log ``` { \"title\": \"TaskEventLog\", \"type\": \"object\", \"properties\": { \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary whose keys (property names) are the indices of a phase\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phases\" } } }, \"required\": [ \"task_id\" ], \"additionalProperties\": false, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] }, \"Phases\": { \"title\": \"Phases\", \"type\": \"object\", \"properties\": { \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall phase\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary whose keys (property names) are the indices of an event in the phase\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"additionalProperties\": false } } } ``` ### /dispensers/{guid}/state ``` { \"title\": \"DispenserState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /dispensers/{guid}/health ``` { \"title\": \"DispenserHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /ingestors/{guid}/state ``` { \"title\": \"IngestorState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /ingestors/{guid}/health ``` { \"title\": \"IngestorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /fleets/{name}/state ``` { \"title\": \"FleetState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"robots\": { \"title\": \"Robots\", \"description\": \"A dictionary of the states of the robots that belong to this fleet\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/RobotState\" } } }, \"definitions\": { \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"offline\", \"shutdown\", \"idle\", \"charging\", \"working\", \"error\" ] }, \"Location2D\": { \"title\": \"Location2D\", \"type\": \"object\", \"properties\": { \"map\": { \"title\": \"Map\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"type\": \"number\" } }, \"required\": [ \"map\", \"x\", \"y\", \"yaw\" ] }, \"Issue\": { \"title\": \"Issue\", \"type\": \"object\", \"properties\": { \"category\": { \"title\": \"Category\", \"description\": \"Category of the robot\'s issue\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the issue\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] } } }, \"Commission\": { \"title\": \"Commission\", \"type\": \"object\", \"properties\": { \"dispatch_tasks\": { \"title\": \"Dispatch Tasks\", \"description\": \"Should the robot accept dispatched tasks, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"direct_tasks\": { \"title\": \"Direct Tasks\", \"description\": \"Should the robot accept direct task requests, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"idle_behavior\": { \"title\": \"Idle Behavior\", \"description\": \"Should the robot perform its idle behavior, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" } } }, \"MutexGroups\": { \"title\": \"MutexGroups\", \"type\": \"object\", \"properties\": { \"locked\": { \"title\": \"Locked\", \"description\": \"A list of mutex groups that this robot has currently locked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requesting\": { \"title\": \"Requesting\", \"description\": \"A list of the mutex groups that this robot is currently requesting but has not lockd yet\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } } }, \"RobotState\": { \"title\": \"RobotState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"status\": { \"description\": \"A simple token representing the status of the robot\", \"allOf\": [ { \"$ref\": \"#/definitions/Status\" } ] }, \"task_id\": { \"title\": \"Task Id\", \"description\": \"The ID of the task this robot is currently working on. Empty string if the robot is not working on a task.\", \"type\": \"string\" }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"location\": { \"$ref\": \"#/definitions/Location2D\" }, \"battery\": { \"title\": \"Battery\", \"description\": \"State of charge of the battery. Values range from 0.0 (depleted) to 1.0 (fully charged)\", \"minimum\": 0.0, \"maximum\": 1.0, \"type\": \"number\" }, \"issues\": { \"title\": \"Issues\", \"description\": \"A list of issues with the robot that operators need to address\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Issue\" } }, \"commission\": { \"$ref\": \"#/definitions/Commission\" }, \"mutex_groups\": { \"title\": \"Mutex Groups\", \"description\": \"Information about the mutex groups that this robot is interacting with\", \"allOf\": [ { \"$ref\": \"#/definitions/MutexGroups\" } ] } } } } } ``` ### /fleets/{name}/log ``` { \"title\": \"FleetLog\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log for the overall fleet\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"robots\": { \"title\": \"Robots\", \"description\": \"Dictionary of logs for the individual robots. The keys (property names) are the robot names.\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] } } } ``` + * # NOTE: This endpoint is here for documentation purposes only, this is _not_ a REST endpoint. ## About This exposes a minimal pubsub system built on top of socket.io. It works similar to a normal socket.io endpoint, except that are 2 special rooms which control subscriptions. ## Rooms ### subscribe Clients must send a message to this room to start receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### unsubscribe Clients can send a message to this room to stop receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### /alerts/requests ``` { \"title\": \"AlertRequest\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"unix_millis_alert_time\": { \"title\": \"Unix Millis Alert Time\", \"type\": \"integer\" }, \"title\": { \"title\": \"Title\", \"type\": \"string\" }, \"subtitle\": { \"title\": \"Subtitle\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" }, \"display\": { \"title\": \"Display\", \"type\": \"boolean\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"responses_available\": { \"title\": \"Responses Available\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"alert_parameters\": { \"title\": \"Alert Parameters\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AlertParameter\" } }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" } }, \"required\": [ \"id\", \"unix_millis_alert_time\", \"title\", \"subtitle\", \"message\", \"display\", \"tier\", \"responses_available\", \"alert_parameters\" ], \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"info\", \"warning\", \"error\" ], \"type\": \"string\" }, \"AlertParameter\": { \"title\": \"AlertParameter\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"value\": { \"title\": \"Value\", \"type\": \"string\" } }, \"required\": [ \"name\", \"value\" ] } } } ``` ### /alerts/responses ``` { \"title\": \"AlertResponse\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"unix_millis_response_time\": { \"title\": \"Unix Millis Response Time\", \"type\": \"integer\" }, \"response\": { \"title\": \"Response\", \"type\": \"string\" } }, \"required\": [ \"id\", \"unix_millis_response_time\", \"response\" ] } ``` ### /beacons ``` { \"title\": \"BeaconState\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"online\": { \"title\": \"Online\", \"type\": \"boolean\" }, \"category\": { \"title\": \"Category\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"activated\": { \"title\": \"Activated\", \"type\": \"boolean\" }, \"level\": { \"title\": \"Level\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" } }, \"required\": [ \"id\", \"online\", \"activated\" ], \"additionalProperties\": false } ``` ### /building_map ``` { \"title\": \"BuildingMap\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Level\" } }, \"lifts\": { \"title\": \"Lifts\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Lift\" } } }, \"required\": [ \"name\", \"levels\", \"lifts\" ], \"definitions\": { \"AffineImage\": { \"title\": \"AffineImage\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x_offset\": { \"title\": \"X Offset\", \"default\": 0, \"type\": \"number\" }, \"y_offset\": { \"title\": \"Y Offset\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"scale\": { \"title\": \"Scale\", \"default\": 0, \"type\": \"number\" }, \"encoding\": { \"title\": \"Encoding\", \"default\": \"\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"string\" } }, \"required\": [ \"name\", \"x_offset\", \"y_offset\", \"yaw\", \"scale\", \"encoding\", \"data\" ] }, \"Place\": { \"title\": \"Place\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"position_tolerance\": { \"title\": \"Position Tolerance\", \"default\": 0, \"type\": \"number\" }, \"yaw_tolerance\": { \"title\": \"Yaw Tolerance\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"x\", \"y\", \"yaw\", \"position_tolerance\", \"yaw_tolerance\" ] }, \"Door\": { \"title\": \"Door\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"v1_x\": { \"title\": \"V1 X\", \"default\": 0, \"type\": \"number\" }, \"v1_y\": { \"title\": \"V1 Y\", \"default\": 0, \"type\": \"number\" }, \"v2_x\": { \"title\": \"V2 X\", \"default\": 0, \"type\": \"number\" }, \"v2_y\": { \"title\": \"V2 Y\", \"default\": 0, \"type\": \"number\" }, \"door_type\": { \"title\": \"Door Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_range\": { \"title\": \"Motion Range\", \"default\": 0, \"type\": \"number\" }, \"motion_direction\": { \"title\": \"Motion Direction\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" } }, \"required\": [ \"name\", \"v1_x\", \"v1_y\", \"v2_x\", \"v2_y\", \"door_type\", \"motion_range\", \"motion_direction\" ] }, \"Param\": { \"title\": \"Param\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"value_int\": { \"title\": \"Value Int\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"value_float\": { \"title\": \"Value Float\", \"default\": 0, \"type\": \"number\" }, \"value_string\": { \"title\": \"Value String\", \"default\": \"\", \"type\": \"string\" }, \"value_bool\": { \"title\": \"Value Bool\", \"default\": false, \"type\": \"boolean\" } }, \"required\": [ \"name\", \"type\", \"value_int\", \"value_float\", \"value_string\", \"value_bool\" ] }, \"GraphNode\": { \"title\": \"GraphNode\", \"type\": \"object\", \"properties\": { \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"x\", \"y\", \"name\", \"params\" ] }, \"GraphEdge\": { \"title\": \"GraphEdge\", \"type\": \"object\", \"properties\": { \"v1_idx\": { \"title\": \"V1 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"v2_idx\": { \"title\": \"V2 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } }, \"edge_type\": { \"title\": \"Edge Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" } }, \"required\": [ \"v1_idx\", \"v2_idx\", \"params\", \"edge_type\" ] }, \"Graph\": { \"title\": \"Graph\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"vertices\": { \"title\": \"Vertices\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphNode\" } }, \"edges\": { \"title\": \"Edges\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphEdge\" } }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"name\", \"vertices\", \"edges\", \"params\" ] }, \"Level\": { \"title\": \"Level\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"elevation\": { \"title\": \"Elevation\", \"default\": 0, \"type\": \"number\" }, \"images\": { \"title\": \"Images\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AffineImage\" } }, \"places\": { \"title\": \"Places\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Place\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"nav_graphs\": { \"title\": \"Nav Graphs\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Graph\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] } }, \"required\": [ \"name\", \"elevation\", \"images\", \"places\", \"doors\", \"nav_graphs\", \"wall_graph\" ] }, \"Lift\": { \"title\": \"Lift\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] }, \"ref_x\": { \"title\": \"Ref X\", \"default\": 0, \"type\": \"number\" }, \"ref_y\": { \"title\": \"Ref Y\", \"default\": 0, \"type\": \"number\" }, \"ref_yaw\": { \"title\": \"Ref Yaw\", \"default\": 0, \"type\": \"number\" }, \"width\": { \"title\": \"Width\", \"default\": 0, \"type\": \"number\" }, \"depth\": { \"title\": \"Depth\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"levels\", \"doors\", \"wall_graph\", \"ref_x\", \"ref_y\", \"ref_yaw\", \"width\", \"depth\" ] } } } ``` ### /building_map/fire_alarm_trigger ``` { \"title\": \"FireAlarmTriggerState\", \"type\": \"object\", \"properties\": { \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"trigger\": { \"title\": \"Trigger\", \"type\": \"boolean\" } }, \"required\": [ \"unix_millis_time\", \"trigger\" ] } ``` ### /delivery_alerts ``` { \"title\": \"DeliveryAlert\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"action\": { \"$ref\": \"#/definitions/Action\" }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" } }, \"required\": [ \"id\", \"category\", \"tier\", \"action\", \"task_id\", \"message\" ], \"definitions\": { \"Category\": { \"title\": \"Category\", \"description\": \"An enumeration.\", \"enum\": [ \"missing\", \"wrong\", \"obstructed\", \"cancelled\" ], \"type\": \"string\" }, \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"warning\", \"error\" ], \"type\": \"string\" }, \"Action\": { \"title\": \"Action\", \"description\": \"An enumeration.\", \"enum\": [ \"waiting\", \"cancelled\", \"override\", \"resume\" ], \"type\": \"string\" } } } ``` ### /doors/{door_name}/state ``` { \"title\": \"DoorState\", \"type\": \"object\", \"properties\": { \"door_time\": { \"title\": \"Door Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"door_name\": { \"title\": \"Door Name\", \"default\": \"\", \"type\": \"string\" }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": { \"value\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/DoorMode\" } ] } }, \"required\": [ \"door_time\", \"door_name\", \"current_mode\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] }, \"DoorMode\": { \"title\": \"DoorMode\", \"type\": \"object\", \"properties\": { \"value\": { \"title\": \"Value\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"value\" ] } } } ``` ### /doors/{door_name}/health ``` { \"title\": \"DoorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /lifts/{lift_name}/state ``` { \"title\": \"LiftState\", \"type\": \"object\", \"properties\": { \"lift_time\": { \"title\": \"Lift Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"lift_name\": { \"title\": \"Lift Name\", \"default\": \"\", \"type\": \"string\" }, \"available_floors\": { \"title\": \"Available Floors\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"current_floor\": { \"title\": \"Current Floor\", \"default\": \"\", \"type\": \"string\" }, \"destination_floor\": { \"title\": \"Destination Floor\", \"default\": \"\", \"type\": \"string\" }, \"door_state\": { \"title\": \"Door State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_state\": { \"title\": \"Motion State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"available_modes\": { \"title\": \"Available Modes\", \"type\": \"array\", \"items\": { \"type\": \"integer\" } }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"session_id\": { \"title\": \"Session Id\", \"default\": \"\", \"type\": \"string\" } }, \"required\": [ \"lift_time\", \"lift_name\", \"available_floors\", \"current_floor\", \"destination_floor\", \"door_state\", \"motion_state\", \"available_modes\", \"current_mode\", \"session_id\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /lifts/{lift_name}/health ``` { \"title\": \"LiftHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /tasks/{task_id}/state ``` { \"title\": \"TaskState\", \"type\": \"object\", \"properties\": { \"booking\": { \"$ref\": \"#/definitions/Booking\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"assigned_to\": { \"title\": \"Assigned To\", \"description\": \"Which agent (robot) is the task assigned to\", \"allOf\": [ { \"$ref\": \"#/definitions/AssignedTo\" } ] }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"dispatch\": { \"$ref\": \"#/definitions/Dispatch\" }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary of the states of the phases of the task. The keys (property names) are phase IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phase\" } }, \"completed\": { \"title\": \"Completed\", \"description\": \"An array of the IDs of completed phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"active\": { \"title\": \"Active\", \"description\": \"The ID of the active phase for this task\", \"allOf\": [ { \"$ref\": \"#/definitions/Id\" } ] }, \"pending\": { \"title\": \"Pending\", \"description\": \"An array of the pending phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"interruptions\": { \"title\": \"Interruptions\", \"description\": \"A dictionary of interruptions that have been applied to this task. The keys (property names) are the unique token of the interruption request.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Interruption\" } }, \"cancellation\": { \"title\": \"Cancellation\", \"description\": \"If the task was cancelled, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Cancellation\" } ] }, \"killed\": { \"title\": \"Killed\", \"description\": \"If the task was killed, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Killed\" } ] } }, \"required\": [ \"booking\" ], \"definitions\": { \"Booking\": { \"title\": \"Booking\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"description\": \"The unique identifier for this task\", \"type\": \"string\" }, \"unix_millis_earliest_start_time\": { \"title\": \"Unix Millis Earliest Start Time\", \"type\": \"integer\" }, \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"type\": \"integer\" }, \"priority\": { \"title\": \"Priority\", \"description\": \"Priority information about this task\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"string\" } ] }, \"labels\": { \"title\": \"Labels\", \"description\": \"Information about how and why this task was booked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requester\": { \"title\": \"Requester\", \"description\": \"(Optional) An identifier for the entity that requested this task\", \"type\": \"string\" } }, \"required\": [ \"id\" ] }, \"Category\": { \"title\": \"Category\", \"description\": \"The category of this task or phase\", \"type\": \"string\" }, \"Detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about a task, phase, or event\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] }, \"EstimateMillis\": { \"title\": \"EstimateMillis\", \"description\": \"An estimate, in milliseconds, of how long the subject will take to complete\", \"minimum\": 0, \"type\": \"integer\" }, \"AssignedTo\": { \"title\": \"AssignedTo\", \"type\": \"object\", \"properties\": { \"group\": { \"title\": \"Group\", \"type\": \"string\" }, \"name\": { \"title\": \"Name\", \"type\": \"string\" } }, \"required\": [ \"group\", \"name\" ] }, \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"blocked\", \"error\", \"failed\", \"queued\", \"standby\", \"underway\", \"delayed\", \"skipped\", \"canceled\", \"killed\", \"completed\" ] }, \"Status1\": { \"title\": \"Status1\", \"description\": \"An enumeration.\", \"enum\": [ \"queued\", \"selected\", \"dispatched\", \"failed_to_assign\", \"canceled_in_flight\" ] }, \"Assignment\": { \"title\": \"Assignment\", \"type\": \"object\", \"properties\": { \"fleet_name\": { \"title\": \"Fleet Name\", \"type\": \"string\" }, \"expected_robot_name\": { \"title\": \"Expected Robot Name\", \"type\": \"string\" } } }, \"Error\": { \"title\": \"Error\", \"type\": \"object\", \"properties\": { \"code\": { \"title\": \"Code\", \"description\": \"A standard code for the kind of error that has occurred\", \"minimum\": 0, \"type\": \"integer\" }, \"category\": { \"title\": \"Category\", \"description\": \"The category of the error\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Details about the error\", \"type\": \"string\" } } }, \"Dispatch\": { \"title\": \"Dispatch\", \"type\": \"object\", \"properties\": { \"status\": { \"$ref\": \"#/definitions/Status1\" }, \"assignment\": { \"$ref\": \"#/definitions/Assignment\" }, \"errors\": { \"title\": \"Errors\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Error\" } } }, \"required\": [ \"status\" ] }, \"Id\": { \"title\": \"Id\", \"minimum\": 0, \"type\": \"integer\" }, \"EventState\": { \"title\": \"EventState\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"name\": { \"title\": \"Name\", \"description\": \"The brief name of the event\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the event\", \"allOf\": [ { \"$ref\": \"#/definitions/Detail\" } ] }, \"deps\": { \"title\": \"Deps\", \"description\": \"This event may depend on other events. This array contains the IDs of those other event dependencies.\", \"type\": \"array\", \"items\": { \"type\": \"integer\", \"minimum\": 0 } } }, \"required\": [ \"id\" ] }, \"Undo\": { \"title\": \"Undo\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the undo skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the undo skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"SkipPhaseRequest\": { \"title\": \"SkipPhaseRequest\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"undo\": { \"title\": \"Undo\", \"description\": \"Information about an undo skip request that applied to this request\", \"allOf\": [ { \"$ref\": \"#/definitions/Undo\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Phase\": { \"title\": \"Phase\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"final_event_id\": { \"$ref\": \"#/definitions/Id\" }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary of events for this phase. The keys (property names) are the event IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/EventState\" } }, \"skip_requests\": { \"title\": \"Skip Requests\", \"description\": \"Information about any skip requests that have been received\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/SkipPhaseRequest\" } } }, \"required\": [ \"id\" ] }, \"ResumedBy\": { \"title\": \"ResumedBy\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the resume request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the resume request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"labels\" ] }, \"Interruption\": { \"title\": \"Interruption\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the interruption request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the interruption\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"resumed_by\": { \"title\": \"Resumed By\", \"description\": \"Information about the resume request that ended this interruption. This field will be missing if the interruption is still active.\", \"allOf\": [ { \"$ref\": \"#/definitions/ResumedBy\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Cancellation\": { \"title\": \"Cancellation\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the cancel request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Killed\": { \"title\": \"Killed\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the kill request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] } } } ``` ### /tasks/{task_id}/log ``` { \"title\": \"TaskEventLog\", \"type\": \"object\", \"properties\": { \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary whose keys (property names) are the indices of a phase\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phases\" } } }, \"required\": [ \"task_id\" ], \"additionalProperties\": false, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] }, \"Phases\": { \"title\": \"Phases\", \"type\": \"object\", \"properties\": { \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall phase\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary whose keys (property names) are the indices of an event in the phase\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"additionalProperties\": false } } } ``` ### /dispensers/{guid}/state ``` { \"title\": \"DispenserState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /dispensers/{guid}/health ``` { \"title\": \"DispenserHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /ingestors/{guid}/state ``` { \"title\": \"IngestorState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /ingestors/{guid}/health ``` { \"title\": \"IngestorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /fleets/{name}/state ``` { \"title\": \"FleetState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"robots\": { \"title\": \"Robots\", \"description\": \"A dictionary of the states of the robots that belong to this fleet\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/RobotState\" } } }, \"definitions\": { \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"offline\", \"shutdown\", \"idle\", \"charging\", \"working\", \"error\" ] }, \"Location2D\": { \"title\": \"Location2D\", \"type\": \"object\", \"properties\": { \"map\": { \"title\": \"Map\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"type\": \"number\" } }, \"required\": [ \"map\", \"x\", \"y\", \"yaw\" ] }, \"Issue\": { \"title\": \"Issue\", \"type\": \"object\", \"properties\": { \"category\": { \"title\": \"Category\", \"description\": \"Category of the robot\'s issue\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the issue\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] } } }, \"Commission\": { \"title\": \"Commission\", \"type\": \"object\", \"properties\": { \"dispatch_tasks\": { \"title\": \"Dispatch Tasks\", \"description\": \"Should the robot accept dispatched tasks, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"direct_tasks\": { \"title\": \"Direct Tasks\", \"description\": \"Should the robot accept direct task requests, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"idle_behavior\": { \"title\": \"Idle Behavior\", \"description\": \"Should the robot perform its idle behavior, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" } } }, \"MutexGroups\": { \"title\": \"MutexGroups\", \"type\": \"object\", \"properties\": { \"locked\": { \"title\": \"Locked\", \"description\": \"A list of mutex groups that this robot has currently locked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requesting\": { \"title\": \"Requesting\", \"description\": \"A list of the mutex groups that this robot is currently requesting but has not lockd yet\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } } }, \"RobotState\": { \"title\": \"RobotState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"status\": { \"description\": \"A simple token representing the status of the robot\", \"allOf\": [ { \"$ref\": \"#/definitions/Status\" } ] }, \"task_id\": { \"title\": \"Task Id\", \"description\": \"The ID of the task this robot is currently working on. Empty string if the robot is not working on a task.\", \"type\": \"string\" }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"location\": { \"$ref\": \"#/definitions/Location2D\" }, \"battery\": { \"title\": \"Battery\", \"description\": \"State of charge of the battery. Values range from 0.0 (depleted) to 1.0 (fully charged)\", \"minimum\": 0.0, \"maximum\": 1.0, \"type\": \"number\" }, \"issues\": { \"title\": \"Issues\", \"description\": \"A list of issues with the robot that operators need to address\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Issue\" } }, \"commission\": { \"$ref\": \"#/definitions/Commission\" }, \"mutex_groups\": { \"title\": \"Mutex Groups\", \"description\": \"Information about the mutex groups that this robot is interacting with\", \"allOf\": [ { \"$ref\": \"#/definitions/MutexGroups\" } ] } } } } } ``` ### /fleets/{name}/log ``` { \"title\": \"FleetLog\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log for the overall fleet\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"robots\": { \"title\": \"Robots\", \"description\": \"Dictionary of logs for the individual robots. The keys (property names) are the robot names.\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] } } } ``` ### /rios ``` { \"title\": \"Rio\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"object\" } }, \"required\": [ \"id\", \"type\", \"data\" ] } ``` * @summary Socket.io endpoint * @param {*} [options] Override http request option. * @throws {RequiredError} @@ -6038,7 +6376,7 @@ export const DefaultApiFactory = function ( return localVarFp.getUserUserGet(options).then((request) => request(axios, basePath)); }, /** - * # NOTE: This endpoint is here for documentation purposes only, this is _not_ a REST endpoint. ## About This exposes a minimal pubsub system built on top of socket.io. It works similar to a normal socket.io endpoint, except that are 2 special rooms which control subscriptions. ## Rooms ### subscribe Clients must send a message to this room to start receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### unsubscribe Clients can send a message to this room to stop receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### /alerts ``` { \"title\": \"Alert\", \"description\": \"General alert that can be triggered by events.\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"original_id\": { \"title\": \"Original Id\", \"maxLength\": 255, \"type\": \"string\" }, \"category\": { \"title\": \"Category\", \"description\": \"Default: default
Task: task
Fleet: fleet
Robot: robot\", \"maxLength\": 7, \"type\": \"string\" }, \"unix_millis_created_time\": { \"title\": \"Unix Millis Created Time\", \"minimum\": -9223372036854775808, \"maximum\": 9223372036854775807, \"type\": \"integer\" }, \"acknowledged_by\": { \"title\": \"Acknowledged By\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"unix_millis_acknowledged_time\": { \"title\": \"Unix Millis Acknowledged Time\", \"minimum\": -9223372036854775808, \"maximum\": 9223372036854775807, \"nullable\": true, \"type\": \"integer\" } }, \"required\": [ \"id\", \"original_id\", \"category\", \"unix_millis_created_time\" ], \"additionalProperties\": false } ``` ### /beacons ``` { \"title\": \"BeaconState\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"online\": { \"title\": \"Online\", \"type\": \"boolean\" }, \"category\": { \"title\": \"Category\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"activated\": { \"title\": \"Activated\", \"type\": \"boolean\" }, \"level\": { \"title\": \"Level\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" } }, \"required\": [ \"id\", \"online\", \"activated\" ], \"additionalProperties\": false } ``` ### /building_map ``` { \"title\": \"BuildingMap\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Level\" } }, \"lifts\": { \"title\": \"Lifts\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Lift\" } } }, \"required\": [ \"name\", \"levels\", \"lifts\" ], \"definitions\": { \"AffineImage\": { \"title\": \"AffineImage\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x_offset\": { \"title\": \"X Offset\", \"default\": 0, \"type\": \"number\" }, \"y_offset\": { \"title\": \"Y Offset\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"scale\": { \"title\": \"Scale\", \"default\": 0, \"type\": \"number\" }, \"encoding\": { \"title\": \"Encoding\", \"default\": \"\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"string\" } }, \"required\": [ \"name\", \"x_offset\", \"y_offset\", \"yaw\", \"scale\", \"encoding\", \"data\" ] }, \"Place\": { \"title\": \"Place\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"position_tolerance\": { \"title\": \"Position Tolerance\", \"default\": 0, \"type\": \"number\" }, \"yaw_tolerance\": { \"title\": \"Yaw Tolerance\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"x\", \"y\", \"yaw\", \"position_tolerance\", \"yaw_tolerance\" ] }, \"Door\": { \"title\": \"Door\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"v1_x\": { \"title\": \"V1 X\", \"default\": 0, \"type\": \"number\" }, \"v1_y\": { \"title\": \"V1 Y\", \"default\": 0, \"type\": \"number\" }, \"v2_x\": { \"title\": \"V2 X\", \"default\": 0, \"type\": \"number\" }, \"v2_y\": { \"title\": \"V2 Y\", \"default\": 0, \"type\": \"number\" }, \"door_type\": { \"title\": \"Door Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_range\": { \"title\": \"Motion Range\", \"default\": 0, \"type\": \"number\" }, \"motion_direction\": { \"title\": \"Motion Direction\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" } }, \"required\": [ \"name\", \"v1_x\", \"v1_y\", \"v2_x\", \"v2_y\", \"door_type\", \"motion_range\", \"motion_direction\" ] }, \"Param\": { \"title\": \"Param\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"value_int\": { \"title\": \"Value Int\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"value_float\": { \"title\": \"Value Float\", \"default\": 0, \"type\": \"number\" }, \"value_string\": { \"title\": \"Value String\", \"default\": \"\", \"type\": \"string\" }, \"value_bool\": { \"title\": \"Value Bool\", \"default\": false, \"type\": \"boolean\" } }, \"required\": [ \"name\", \"type\", \"value_int\", \"value_float\", \"value_string\", \"value_bool\" ] }, \"GraphNode\": { \"title\": \"GraphNode\", \"type\": \"object\", \"properties\": { \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"x\", \"y\", \"name\", \"params\" ] }, \"GraphEdge\": { \"title\": \"GraphEdge\", \"type\": \"object\", \"properties\": { \"v1_idx\": { \"title\": \"V1 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"v2_idx\": { \"title\": \"V2 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } }, \"edge_type\": { \"title\": \"Edge Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" } }, \"required\": [ \"v1_idx\", \"v2_idx\", \"params\", \"edge_type\" ] }, \"Graph\": { \"title\": \"Graph\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"vertices\": { \"title\": \"Vertices\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphNode\" } }, \"edges\": { \"title\": \"Edges\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphEdge\" } }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"name\", \"vertices\", \"edges\", \"params\" ] }, \"Level\": { \"title\": \"Level\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"elevation\": { \"title\": \"Elevation\", \"default\": 0, \"type\": \"number\" }, \"images\": { \"title\": \"Images\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AffineImage\" } }, \"places\": { \"title\": \"Places\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Place\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"nav_graphs\": { \"title\": \"Nav Graphs\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Graph\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] } }, \"required\": [ \"name\", \"elevation\", \"images\", \"places\", \"doors\", \"nav_graphs\", \"wall_graph\" ] }, \"Lift\": { \"title\": \"Lift\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] }, \"ref_x\": { \"title\": \"Ref X\", \"default\": 0, \"type\": \"number\" }, \"ref_y\": { \"title\": \"Ref Y\", \"default\": 0, \"type\": \"number\" }, \"ref_yaw\": { \"title\": \"Ref Yaw\", \"default\": 0, \"type\": \"number\" }, \"width\": { \"title\": \"Width\", \"default\": 0, \"type\": \"number\" }, \"depth\": { \"title\": \"Depth\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"levels\", \"doors\", \"wall_graph\", \"ref_x\", \"ref_y\", \"ref_yaw\", \"width\", \"depth\" ] } } } ``` ### /building_map/fire_alarm_trigger ``` { \"title\": \"FireAlarmTriggerState\", \"type\": \"object\", \"properties\": { \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"trigger\": { \"title\": \"Trigger\", \"type\": \"boolean\" } }, \"required\": [ \"unix_millis_time\", \"trigger\" ] } ``` ### /delivery_alerts ``` { \"title\": \"DeliveryAlert\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"action\": { \"$ref\": \"#/definitions/Action\" }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" } }, \"required\": [ \"id\", \"category\", \"tier\", \"action\", \"task_id\", \"message\" ], \"definitions\": { \"Category\": { \"title\": \"Category\", \"description\": \"An enumeration.\", \"enum\": [ \"missing\", \"wrong\", \"obstructed\", \"cancelled\" ], \"type\": \"string\" }, \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"warning\", \"error\" ], \"type\": \"string\" }, \"Action\": { \"title\": \"Action\", \"description\": \"An enumeration.\", \"enum\": [ \"waiting\", \"cancelled\", \"override\", \"resume\" ], \"type\": \"string\" } } } ``` ### /doors/{door_name}/state ``` { \"title\": \"DoorState\", \"type\": \"object\", \"properties\": { \"door_time\": { \"title\": \"Door Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"door_name\": { \"title\": \"Door Name\", \"default\": \"\", \"type\": \"string\" }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": { \"value\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/DoorMode\" } ] } }, \"required\": [ \"door_time\", \"door_name\", \"current_mode\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] }, \"DoorMode\": { \"title\": \"DoorMode\", \"type\": \"object\", \"properties\": { \"value\": { \"title\": \"Value\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"value\" ] } } } ``` ### /doors/{door_name}/health ``` { \"title\": \"DoorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /lifts/{lift_name}/state ``` { \"title\": \"LiftState\", \"type\": \"object\", \"properties\": { \"lift_time\": { \"title\": \"Lift Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"lift_name\": { \"title\": \"Lift Name\", \"default\": \"\", \"type\": \"string\" }, \"available_floors\": { \"title\": \"Available Floors\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"current_floor\": { \"title\": \"Current Floor\", \"default\": \"\", \"type\": \"string\" }, \"destination_floor\": { \"title\": \"Destination Floor\", \"default\": \"\", \"type\": \"string\" }, \"door_state\": { \"title\": \"Door State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_state\": { \"title\": \"Motion State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"available_modes\": { \"title\": \"Available Modes\", \"type\": \"array\", \"items\": { \"type\": \"integer\" } }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"session_id\": { \"title\": \"Session Id\", \"default\": \"\", \"type\": \"string\" } }, \"required\": [ \"lift_time\", \"lift_name\", \"available_floors\", \"current_floor\", \"destination_floor\", \"door_state\", \"motion_state\", \"available_modes\", \"current_mode\", \"session_id\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /lifts/{lift_name}/health ``` { \"title\": \"LiftHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /tasks/{task_id}/state ``` { \"title\": \"TaskState\", \"type\": \"object\", \"properties\": { \"booking\": { \"$ref\": \"#/definitions/Booking\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"assigned_to\": { \"title\": \"Assigned To\", \"description\": \"Which agent (robot) is the task assigned to\", \"allOf\": [ { \"$ref\": \"#/definitions/AssignedTo\" } ] }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"dispatch\": { \"$ref\": \"#/definitions/Dispatch\" }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary of the states of the phases of the task. The keys (property names) are phase IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phase\" } }, \"completed\": { \"title\": \"Completed\", \"description\": \"An array of the IDs of completed phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"active\": { \"title\": \"Active\", \"description\": \"The ID of the active phase for this task\", \"allOf\": [ { \"$ref\": \"#/definitions/Id\" } ] }, \"pending\": { \"title\": \"Pending\", \"description\": \"An array of the pending phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"interruptions\": { \"title\": \"Interruptions\", \"description\": \"A dictionary of interruptions that have been applied to this task. The keys (property names) are the unique token of the interruption request.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Interruption\" } }, \"cancellation\": { \"title\": \"Cancellation\", \"description\": \"If the task was cancelled, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Cancellation\" } ] }, \"killed\": { \"title\": \"Killed\", \"description\": \"If the task was killed, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Killed\" } ] } }, \"required\": [ \"booking\" ], \"definitions\": { \"Booking\": { \"title\": \"Booking\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"description\": \"The unique identifier for this task\", \"type\": \"string\" }, \"unix_millis_earliest_start_time\": { \"title\": \"Unix Millis Earliest Start Time\", \"type\": \"integer\" }, \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"type\": \"integer\" }, \"priority\": { \"title\": \"Priority\", \"description\": \"Priority information about this task\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"string\" } ] }, \"labels\": { \"title\": \"Labels\", \"description\": \"Information about how and why this task was booked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requester\": { \"title\": \"Requester\", \"description\": \"(Optional) An identifier for the entity that requested this task\", \"type\": \"string\" } }, \"required\": [ \"id\" ] }, \"Category\": { \"title\": \"Category\", \"description\": \"The category of this task or phase\", \"type\": \"string\" }, \"Detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about a task, phase, or event\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] }, \"EstimateMillis\": { \"title\": \"EstimateMillis\", \"description\": \"An estimate, in milliseconds, of how long the subject will take to complete\", \"minimum\": 0, \"type\": \"integer\" }, \"AssignedTo\": { \"title\": \"AssignedTo\", \"type\": \"object\", \"properties\": { \"group\": { \"title\": \"Group\", \"type\": \"string\" }, \"name\": { \"title\": \"Name\", \"type\": \"string\" } }, \"required\": [ \"group\", \"name\" ] }, \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"blocked\", \"error\", \"failed\", \"queued\", \"standby\", \"underway\", \"delayed\", \"skipped\", \"canceled\", \"killed\", \"completed\" ] }, \"Status1\": { \"title\": \"Status1\", \"description\": \"An enumeration.\", \"enum\": [ \"queued\", \"selected\", \"dispatched\", \"failed_to_assign\", \"canceled_in_flight\" ] }, \"Assignment\": { \"title\": \"Assignment\", \"type\": \"object\", \"properties\": { \"fleet_name\": { \"title\": \"Fleet Name\", \"type\": \"string\" }, \"expected_robot_name\": { \"title\": \"Expected Robot Name\", \"type\": \"string\" } } }, \"Error\": { \"title\": \"Error\", \"type\": \"object\", \"properties\": { \"code\": { \"title\": \"Code\", \"description\": \"A standard code for the kind of error that has occurred\", \"minimum\": 0, \"type\": \"integer\" }, \"category\": { \"title\": \"Category\", \"description\": \"The category of the error\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Details about the error\", \"type\": \"string\" } } }, \"Dispatch\": { \"title\": \"Dispatch\", \"type\": \"object\", \"properties\": { \"status\": { \"$ref\": \"#/definitions/Status1\" }, \"assignment\": { \"$ref\": \"#/definitions/Assignment\" }, \"errors\": { \"title\": \"Errors\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Error\" } } }, \"required\": [ \"status\" ] }, \"Id\": { \"title\": \"Id\", \"minimum\": 0, \"type\": \"integer\" }, \"EventState\": { \"title\": \"EventState\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"name\": { \"title\": \"Name\", \"description\": \"The brief name of the event\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the event\", \"allOf\": [ { \"$ref\": \"#/definitions/Detail\" } ] }, \"deps\": { \"title\": \"Deps\", \"description\": \"This event may depend on other events. This array contains the IDs of those other event dependencies.\", \"type\": \"array\", \"items\": { \"type\": \"integer\", \"minimum\": 0 } } }, \"required\": [ \"id\" ] }, \"Undo\": { \"title\": \"Undo\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the undo skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the undo skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"SkipPhaseRequest\": { \"title\": \"SkipPhaseRequest\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"undo\": { \"title\": \"Undo\", \"description\": \"Information about an undo skip request that applied to this request\", \"allOf\": [ { \"$ref\": \"#/definitions/Undo\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Phase\": { \"title\": \"Phase\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"final_event_id\": { \"$ref\": \"#/definitions/Id\" }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary of events for this phase. The keys (property names) are the event IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/EventState\" } }, \"skip_requests\": { \"title\": \"Skip Requests\", \"description\": \"Information about any skip requests that have been received\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/SkipPhaseRequest\" } } }, \"required\": [ \"id\" ] }, \"ResumedBy\": { \"title\": \"ResumedBy\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the resume request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the resume request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"labels\" ] }, \"Interruption\": { \"title\": \"Interruption\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the interruption request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the interruption\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"resumed_by\": { \"title\": \"Resumed By\", \"description\": \"Information about the resume request that ended this interruption. This field will be missing if the interruption is still active.\", \"allOf\": [ { \"$ref\": \"#/definitions/ResumedBy\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Cancellation\": { \"title\": \"Cancellation\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the cancel request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Killed\": { \"title\": \"Killed\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the kill request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] } } } ``` ### /tasks/{task_id}/log ``` { \"title\": \"TaskEventLog\", \"type\": \"object\", \"properties\": { \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary whose keys (property names) are the indices of a phase\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phases\" } } }, \"required\": [ \"task_id\" ], \"additionalProperties\": false, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] }, \"Phases\": { \"title\": \"Phases\", \"type\": \"object\", \"properties\": { \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall phase\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary whose keys (property names) are the indices of an event in the phase\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"additionalProperties\": false } } } ``` ### /dispensers/{guid}/state ``` { \"title\": \"DispenserState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /dispensers/{guid}/health ``` { \"title\": \"DispenserHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /ingestors/{guid}/state ``` { \"title\": \"IngestorState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /ingestors/{guid}/health ``` { \"title\": \"IngestorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /fleets/{name}/state ``` { \"title\": \"FleetState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"robots\": { \"title\": \"Robots\", \"description\": \"A dictionary of the states of the robots that belong to this fleet\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/RobotState\" } } }, \"definitions\": { \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"offline\", \"shutdown\", \"idle\", \"charging\", \"working\", \"error\" ] }, \"Location2D\": { \"title\": \"Location2D\", \"type\": \"object\", \"properties\": { \"map\": { \"title\": \"Map\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"type\": \"number\" } }, \"required\": [ \"map\", \"x\", \"y\", \"yaw\" ] }, \"Issue\": { \"title\": \"Issue\", \"type\": \"object\", \"properties\": { \"category\": { \"title\": \"Category\", \"description\": \"Category of the robot\'s issue\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the issue\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] } } }, \"Commission\": { \"title\": \"Commission\", \"type\": \"object\", \"properties\": { \"dispatch_tasks\": { \"title\": \"Dispatch Tasks\", \"description\": \"Should the robot accept dispatched tasks, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"direct_tasks\": { \"title\": \"Direct Tasks\", \"description\": \"Should the robot accept direct task requests, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"idle_behavior\": { \"title\": \"Idle Behavior\", \"description\": \"Should the robot perform its idle behavior, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" } } }, \"MutexGroups\": { \"title\": \"MutexGroups\", \"type\": \"object\", \"properties\": { \"locked\": { \"title\": \"Locked\", \"description\": \"A list of mutex groups that this robot has currently locked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requesting\": { \"title\": \"Requesting\", \"description\": \"A list of the mutex groups that this robot is currently requesting but has not lockd yet\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } } }, \"RobotState\": { \"title\": \"RobotState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"status\": { \"description\": \"A simple token representing the status of the robot\", \"allOf\": [ { \"$ref\": \"#/definitions/Status\" } ] }, \"task_id\": { \"title\": \"Task Id\", \"description\": \"The ID of the task this robot is currently working on. Empty string if the robot is not working on a task.\", \"type\": \"string\" }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"location\": { \"$ref\": \"#/definitions/Location2D\" }, \"battery\": { \"title\": \"Battery\", \"description\": \"State of charge of the battery. Values range from 0.0 (depleted) to 1.0 (fully charged)\", \"minimum\": 0.0, \"maximum\": 1.0, \"type\": \"number\" }, \"issues\": { \"title\": \"Issues\", \"description\": \"A list of issues with the robot that operators need to address\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Issue\" } }, \"commission\": { \"$ref\": \"#/definitions/Commission\" }, \"mutex_groups\": { \"title\": \"Mutex Groups\", \"description\": \"Information about the mutex groups that this robot is interacting with\", \"allOf\": [ { \"$ref\": \"#/definitions/MutexGroups\" } ] } } } } } ``` ### /fleets/{name}/log ``` { \"title\": \"FleetLog\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log for the overall fleet\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"robots\": { \"title\": \"Robots\", \"description\": \"Dictionary of logs for the individual robots. The keys (property names) are the robot names.\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] } } } ``` + * # NOTE: This endpoint is here for documentation purposes only, this is _not_ a REST endpoint. ## About This exposes a minimal pubsub system built on top of socket.io. It works similar to a normal socket.io endpoint, except that are 2 special rooms which control subscriptions. ## Rooms ### subscribe Clients must send a message to this room to start receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### unsubscribe Clients can send a message to this room to stop receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### /alerts/requests ``` { \"title\": \"AlertRequest\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"unix_millis_alert_time\": { \"title\": \"Unix Millis Alert Time\", \"type\": \"integer\" }, \"title\": { \"title\": \"Title\", \"type\": \"string\" }, \"subtitle\": { \"title\": \"Subtitle\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" }, \"display\": { \"title\": \"Display\", \"type\": \"boolean\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"responses_available\": { \"title\": \"Responses Available\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"alert_parameters\": { \"title\": \"Alert Parameters\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AlertParameter\" } }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" } }, \"required\": [ \"id\", \"unix_millis_alert_time\", \"title\", \"subtitle\", \"message\", \"display\", \"tier\", \"responses_available\", \"alert_parameters\" ], \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"info\", \"warning\", \"error\" ], \"type\": \"string\" }, \"AlertParameter\": { \"title\": \"AlertParameter\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"value\": { \"title\": \"Value\", \"type\": \"string\" } }, \"required\": [ \"name\", \"value\" ] } } } ``` ### /alerts/responses ``` { \"title\": \"AlertResponse\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"unix_millis_response_time\": { \"title\": \"Unix Millis Response Time\", \"type\": \"integer\" }, \"response\": { \"title\": \"Response\", \"type\": \"string\" } }, \"required\": [ \"id\", \"unix_millis_response_time\", \"response\" ] } ``` ### /beacons ``` { \"title\": \"BeaconState\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"online\": { \"title\": \"Online\", \"type\": \"boolean\" }, \"category\": { \"title\": \"Category\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"activated\": { \"title\": \"Activated\", \"type\": \"boolean\" }, \"level\": { \"title\": \"Level\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" } }, \"required\": [ \"id\", \"online\", \"activated\" ], \"additionalProperties\": false } ``` ### /building_map ``` { \"title\": \"BuildingMap\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Level\" } }, \"lifts\": { \"title\": \"Lifts\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Lift\" } } }, \"required\": [ \"name\", \"levels\", \"lifts\" ], \"definitions\": { \"AffineImage\": { \"title\": \"AffineImage\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x_offset\": { \"title\": \"X Offset\", \"default\": 0, \"type\": \"number\" }, \"y_offset\": { \"title\": \"Y Offset\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"scale\": { \"title\": \"Scale\", \"default\": 0, \"type\": \"number\" }, \"encoding\": { \"title\": \"Encoding\", \"default\": \"\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"string\" } }, \"required\": [ \"name\", \"x_offset\", \"y_offset\", \"yaw\", \"scale\", \"encoding\", \"data\" ] }, \"Place\": { \"title\": \"Place\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"position_tolerance\": { \"title\": \"Position Tolerance\", \"default\": 0, \"type\": \"number\" }, \"yaw_tolerance\": { \"title\": \"Yaw Tolerance\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"x\", \"y\", \"yaw\", \"position_tolerance\", \"yaw_tolerance\" ] }, \"Door\": { \"title\": \"Door\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"v1_x\": { \"title\": \"V1 X\", \"default\": 0, \"type\": \"number\" }, \"v1_y\": { \"title\": \"V1 Y\", \"default\": 0, \"type\": \"number\" }, \"v2_x\": { \"title\": \"V2 X\", \"default\": 0, \"type\": \"number\" }, \"v2_y\": { \"title\": \"V2 Y\", \"default\": 0, \"type\": \"number\" }, \"door_type\": { \"title\": \"Door Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_range\": { \"title\": \"Motion Range\", \"default\": 0, \"type\": \"number\" }, \"motion_direction\": { \"title\": \"Motion Direction\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" } }, \"required\": [ \"name\", \"v1_x\", \"v1_y\", \"v2_x\", \"v2_y\", \"door_type\", \"motion_range\", \"motion_direction\" ] }, \"Param\": { \"title\": \"Param\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"value_int\": { \"title\": \"Value Int\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"value_float\": { \"title\": \"Value Float\", \"default\": 0, \"type\": \"number\" }, \"value_string\": { \"title\": \"Value String\", \"default\": \"\", \"type\": \"string\" }, \"value_bool\": { \"title\": \"Value Bool\", \"default\": false, \"type\": \"boolean\" } }, \"required\": [ \"name\", \"type\", \"value_int\", \"value_float\", \"value_string\", \"value_bool\" ] }, \"GraphNode\": { \"title\": \"GraphNode\", \"type\": \"object\", \"properties\": { \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"x\", \"y\", \"name\", \"params\" ] }, \"GraphEdge\": { \"title\": \"GraphEdge\", \"type\": \"object\", \"properties\": { \"v1_idx\": { \"title\": \"V1 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"v2_idx\": { \"title\": \"V2 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } }, \"edge_type\": { \"title\": \"Edge Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" } }, \"required\": [ \"v1_idx\", \"v2_idx\", \"params\", \"edge_type\" ] }, \"Graph\": { \"title\": \"Graph\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"vertices\": { \"title\": \"Vertices\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphNode\" } }, \"edges\": { \"title\": \"Edges\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphEdge\" } }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"name\", \"vertices\", \"edges\", \"params\" ] }, \"Level\": { \"title\": \"Level\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"elevation\": { \"title\": \"Elevation\", \"default\": 0, \"type\": \"number\" }, \"images\": { \"title\": \"Images\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AffineImage\" } }, \"places\": { \"title\": \"Places\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Place\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"nav_graphs\": { \"title\": \"Nav Graphs\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Graph\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] } }, \"required\": [ \"name\", \"elevation\", \"images\", \"places\", \"doors\", \"nav_graphs\", \"wall_graph\" ] }, \"Lift\": { \"title\": \"Lift\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] }, \"ref_x\": { \"title\": \"Ref X\", \"default\": 0, \"type\": \"number\" }, \"ref_y\": { \"title\": \"Ref Y\", \"default\": 0, \"type\": \"number\" }, \"ref_yaw\": { \"title\": \"Ref Yaw\", \"default\": 0, \"type\": \"number\" }, \"width\": { \"title\": \"Width\", \"default\": 0, \"type\": \"number\" }, \"depth\": { \"title\": \"Depth\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"levels\", \"doors\", \"wall_graph\", \"ref_x\", \"ref_y\", \"ref_yaw\", \"width\", \"depth\" ] } } } ``` ### /building_map/fire_alarm_trigger ``` { \"title\": \"FireAlarmTriggerState\", \"type\": \"object\", \"properties\": { \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"trigger\": { \"title\": \"Trigger\", \"type\": \"boolean\" } }, \"required\": [ \"unix_millis_time\", \"trigger\" ] } ``` ### /delivery_alerts ``` { \"title\": \"DeliveryAlert\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"action\": { \"$ref\": \"#/definitions/Action\" }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" } }, \"required\": [ \"id\", \"category\", \"tier\", \"action\", \"task_id\", \"message\" ], \"definitions\": { \"Category\": { \"title\": \"Category\", \"description\": \"An enumeration.\", \"enum\": [ \"missing\", \"wrong\", \"obstructed\", \"cancelled\" ], \"type\": \"string\" }, \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"warning\", \"error\" ], \"type\": \"string\" }, \"Action\": { \"title\": \"Action\", \"description\": \"An enumeration.\", \"enum\": [ \"waiting\", \"cancelled\", \"override\", \"resume\" ], \"type\": \"string\" } } } ``` ### /doors/{door_name}/state ``` { \"title\": \"DoorState\", \"type\": \"object\", \"properties\": { \"door_time\": { \"title\": \"Door Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"door_name\": { \"title\": \"Door Name\", \"default\": \"\", \"type\": \"string\" }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": { \"value\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/DoorMode\" } ] } }, \"required\": [ \"door_time\", \"door_name\", \"current_mode\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] }, \"DoorMode\": { \"title\": \"DoorMode\", \"type\": \"object\", \"properties\": { \"value\": { \"title\": \"Value\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"value\" ] } } } ``` ### /doors/{door_name}/health ``` { \"title\": \"DoorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /lifts/{lift_name}/state ``` { \"title\": \"LiftState\", \"type\": \"object\", \"properties\": { \"lift_time\": { \"title\": \"Lift Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"lift_name\": { \"title\": \"Lift Name\", \"default\": \"\", \"type\": \"string\" }, \"available_floors\": { \"title\": \"Available Floors\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"current_floor\": { \"title\": \"Current Floor\", \"default\": \"\", \"type\": \"string\" }, \"destination_floor\": { \"title\": \"Destination Floor\", \"default\": \"\", \"type\": \"string\" }, \"door_state\": { \"title\": \"Door State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_state\": { \"title\": \"Motion State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"available_modes\": { \"title\": \"Available Modes\", \"type\": \"array\", \"items\": { \"type\": \"integer\" } }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"session_id\": { \"title\": \"Session Id\", \"default\": \"\", \"type\": \"string\" } }, \"required\": [ \"lift_time\", \"lift_name\", \"available_floors\", \"current_floor\", \"destination_floor\", \"door_state\", \"motion_state\", \"available_modes\", \"current_mode\", \"session_id\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /lifts/{lift_name}/health ``` { \"title\": \"LiftHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /tasks/{task_id}/state ``` { \"title\": \"TaskState\", \"type\": \"object\", \"properties\": { \"booking\": { \"$ref\": \"#/definitions/Booking\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"assigned_to\": { \"title\": \"Assigned To\", \"description\": \"Which agent (robot) is the task assigned to\", \"allOf\": [ { \"$ref\": \"#/definitions/AssignedTo\" } ] }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"dispatch\": { \"$ref\": \"#/definitions/Dispatch\" }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary of the states of the phases of the task. The keys (property names) are phase IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phase\" } }, \"completed\": { \"title\": \"Completed\", \"description\": \"An array of the IDs of completed phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"active\": { \"title\": \"Active\", \"description\": \"The ID of the active phase for this task\", \"allOf\": [ { \"$ref\": \"#/definitions/Id\" } ] }, \"pending\": { \"title\": \"Pending\", \"description\": \"An array of the pending phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"interruptions\": { \"title\": \"Interruptions\", \"description\": \"A dictionary of interruptions that have been applied to this task. The keys (property names) are the unique token of the interruption request.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Interruption\" } }, \"cancellation\": { \"title\": \"Cancellation\", \"description\": \"If the task was cancelled, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Cancellation\" } ] }, \"killed\": { \"title\": \"Killed\", \"description\": \"If the task was killed, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Killed\" } ] } }, \"required\": [ \"booking\" ], \"definitions\": { \"Booking\": { \"title\": \"Booking\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"description\": \"The unique identifier for this task\", \"type\": \"string\" }, \"unix_millis_earliest_start_time\": { \"title\": \"Unix Millis Earliest Start Time\", \"type\": \"integer\" }, \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"type\": \"integer\" }, \"priority\": { \"title\": \"Priority\", \"description\": \"Priority information about this task\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"string\" } ] }, \"labels\": { \"title\": \"Labels\", \"description\": \"Information about how and why this task was booked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requester\": { \"title\": \"Requester\", \"description\": \"(Optional) An identifier for the entity that requested this task\", \"type\": \"string\" } }, \"required\": [ \"id\" ] }, \"Category\": { \"title\": \"Category\", \"description\": \"The category of this task or phase\", \"type\": \"string\" }, \"Detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about a task, phase, or event\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] }, \"EstimateMillis\": { \"title\": \"EstimateMillis\", \"description\": \"An estimate, in milliseconds, of how long the subject will take to complete\", \"minimum\": 0, \"type\": \"integer\" }, \"AssignedTo\": { \"title\": \"AssignedTo\", \"type\": \"object\", \"properties\": { \"group\": { \"title\": \"Group\", \"type\": \"string\" }, \"name\": { \"title\": \"Name\", \"type\": \"string\" } }, \"required\": [ \"group\", \"name\" ] }, \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"blocked\", \"error\", \"failed\", \"queued\", \"standby\", \"underway\", \"delayed\", \"skipped\", \"canceled\", \"killed\", \"completed\" ] }, \"Status1\": { \"title\": \"Status1\", \"description\": \"An enumeration.\", \"enum\": [ \"queued\", \"selected\", \"dispatched\", \"failed_to_assign\", \"canceled_in_flight\" ] }, \"Assignment\": { \"title\": \"Assignment\", \"type\": \"object\", \"properties\": { \"fleet_name\": { \"title\": \"Fleet Name\", \"type\": \"string\" }, \"expected_robot_name\": { \"title\": \"Expected Robot Name\", \"type\": \"string\" } } }, \"Error\": { \"title\": \"Error\", \"type\": \"object\", \"properties\": { \"code\": { \"title\": \"Code\", \"description\": \"A standard code for the kind of error that has occurred\", \"minimum\": 0, \"type\": \"integer\" }, \"category\": { \"title\": \"Category\", \"description\": \"The category of the error\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Details about the error\", \"type\": \"string\" } } }, \"Dispatch\": { \"title\": \"Dispatch\", \"type\": \"object\", \"properties\": { \"status\": { \"$ref\": \"#/definitions/Status1\" }, \"assignment\": { \"$ref\": \"#/definitions/Assignment\" }, \"errors\": { \"title\": \"Errors\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Error\" } } }, \"required\": [ \"status\" ] }, \"Id\": { \"title\": \"Id\", \"minimum\": 0, \"type\": \"integer\" }, \"EventState\": { \"title\": \"EventState\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"name\": { \"title\": \"Name\", \"description\": \"The brief name of the event\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the event\", \"allOf\": [ { \"$ref\": \"#/definitions/Detail\" } ] }, \"deps\": { \"title\": \"Deps\", \"description\": \"This event may depend on other events. This array contains the IDs of those other event dependencies.\", \"type\": \"array\", \"items\": { \"type\": \"integer\", \"minimum\": 0 } } }, \"required\": [ \"id\" ] }, \"Undo\": { \"title\": \"Undo\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the undo skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the undo skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"SkipPhaseRequest\": { \"title\": \"SkipPhaseRequest\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"undo\": { \"title\": \"Undo\", \"description\": \"Information about an undo skip request that applied to this request\", \"allOf\": [ { \"$ref\": \"#/definitions/Undo\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Phase\": { \"title\": \"Phase\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"final_event_id\": { \"$ref\": \"#/definitions/Id\" }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary of events for this phase. The keys (property names) are the event IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/EventState\" } }, \"skip_requests\": { \"title\": \"Skip Requests\", \"description\": \"Information about any skip requests that have been received\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/SkipPhaseRequest\" } } }, \"required\": [ \"id\" ] }, \"ResumedBy\": { \"title\": \"ResumedBy\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the resume request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the resume request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"labels\" ] }, \"Interruption\": { \"title\": \"Interruption\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the interruption request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the interruption\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"resumed_by\": { \"title\": \"Resumed By\", \"description\": \"Information about the resume request that ended this interruption. This field will be missing if the interruption is still active.\", \"allOf\": [ { \"$ref\": \"#/definitions/ResumedBy\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Cancellation\": { \"title\": \"Cancellation\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the cancel request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Killed\": { \"title\": \"Killed\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the kill request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] } } } ``` ### /tasks/{task_id}/log ``` { \"title\": \"TaskEventLog\", \"type\": \"object\", \"properties\": { \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary whose keys (property names) are the indices of a phase\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phases\" } } }, \"required\": [ \"task_id\" ], \"additionalProperties\": false, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] }, \"Phases\": { \"title\": \"Phases\", \"type\": \"object\", \"properties\": { \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall phase\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary whose keys (property names) are the indices of an event in the phase\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"additionalProperties\": false } } } ``` ### /dispensers/{guid}/state ``` { \"title\": \"DispenserState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /dispensers/{guid}/health ``` { \"title\": \"DispenserHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /ingestors/{guid}/state ``` { \"title\": \"IngestorState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /ingestors/{guid}/health ``` { \"title\": \"IngestorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /fleets/{name}/state ``` { \"title\": \"FleetState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"robots\": { \"title\": \"Robots\", \"description\": \"A dictionary of the states of the robots that belong to this fleet\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/RobotState\" } } }, \"definitions\": { \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"offline\", \"shutdown\", \"idle\", \"charging\", \"working\", \"error\" ] }, \"Location2D\": { \"title\": \"Location2D\", \"type\": \"object\", \"properties\": { \"map\": { \"title\": \"Map\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"type\": \"number\" } }, \"required\": [ \"map\", \"x\", \"y\", \"yaw\" ] }, \"Issue\": { \"title\": \"Issue\", \"type\": \"object\", \"properties\": { \"category\": { \"title\": \"Category\", \"description\": \"Category of the robot\'s issue\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the issue\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] } } }, \"Commission\": { \"title\": \"Commission\", \"type\": \"object\", \"properties\": { \"dispatch_tasks\": { \"title\": \"Dispatch Tasks\", \"description\": \"Should the robot accept dispatched tasks, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"direct_tasks\": { \"title\": \"Direct Tasks\", \"description\": \"Should the robot accept direct task requests, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"idle_behavior\": { \"title\": \"Idle Behavior\", \"description\": \"Should the robot perform its idle behavior, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" } } }, \"MutexGroups\": { \"title\": \"MutexGroups\", \"type\": \"object\", \"properties\": { \"locked\": { \"title\": \"Locked\", \"description\": \"A list of mutex groups that this robot has currently locked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requesting\": { \"title\": \"Requesting\", \"description\": \"A list of the mutex groups that this robot is currently requesting but has not lockd yet\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } } }, \"RobotState\": { \"title\": \"RobotState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"status\": { \"description\": \"A simple token representing the status of the robot\", \"allOf\": [ { \"$ref\": \"#/definitions/Status\" } ] }, \"task_id\": { \"title\": \"Task Id\", \"description\": \"The ID of the task this robot is currently working on. Empty string if the robot is not working on a task.\", \"type\": \"string\" }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"location\": { \"$ref\": \"#/definitions/Location2D\" }, \"battery\": { \"title\": \"Battery\", \"description\": \"State of charge of the battery. Values range from 0.0 (depleted) to 1.0 (fully charged)\", \"minimum\": 0.0, \"maximum\": 1.0, \"type\": \"number\" }, \"issues\": { \"title\": \"Issues\", \"description\": \"A list of issues with the robot that operators need to address\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Issue\" } }, \"commission\": { \"$ref\": \"#/definitions/Commission\" }, \"mutex_groups\": { \"title\": \"Mutex Groups\", \"description\": \"Information about the mutex groups that this robot is interacting with\", \"allOf\": [ { \"$ref\": \"#/definitions/MutexGroups\" } ] } } } } } ``` ### /fleets/{name}/log ``` { \"title\": \"FleetLog\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log for the overall fleet\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"robots\": { \"title\": \"Robots\", \"description\": \"Dictionary of logs for the individual robots. The keys (property names) are the robot names.\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] } } } ``` ### /rios ``` { \"title\": \"Rio\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"object\" } }, \"required\": [ \"id\", \"type\", \"data\" ] } ``` * @summary Socket.io endpoint * @param {*} [options] Override http request option. * @throws {RequiredError} @@ -6096,7 +6434,7 @@ export class DefaultApi extends BaseAPI { } /** - * # NOTE: This endpoint is here for documentation purposes only, this is _not_ a REST endpoint. ## About This exposes a minimal pubsub system built on top of socket.io. It works similar to a normal socket.io endpoint, except that are 2 special rooms which control subscriptions. ## Rooms ### subscribe Clients must send a message to this room to start receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### unsubscribe Clients can send a message to this room to stop receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### /alerts ``` { \"title\": \"Alert\", \"description\": \"General alert that can be triggered by events.\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"original_id\": { \"title\": \"Original Id\", \"maxLength\": 255, \"type\": \"string\" }, \"category\": { \"title\": \"Category\", \"description\": \"Default: default
Task: task
Fleet: fleet
Robot: robot\", \"maxLength\": 7, \"type\": \"string\" }, \"unix_millis_created_time\": { \"title\": \"Unix Millis Created Time\", \"minimum\": -9223372036854775808, \"maximum\": 9223372036854775807, \"type\": \"integer\" }, \"acknowledged_by\": { \"title\": \"Acknowledged By\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"unix_millis_acknowledged_time\": { \"title\": \"Unix Millis Acknowledged Time\", \"minimum\": -9223372036854775808, \"maximum\": 9223372036854775807, \"nullable\": true, \"type\": \"integer\" } }, \"required\": [ \"id\", \"original_id\", \"category\", \"unix_millis_created_time\" ], \"additionalProperties\": false } ``` ### /beacons ``` { \"title\": \"BeaconState\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"online\": { \"title\": \"Online\", \"type\": \"boolean\" }, \"category\": { \"title\": \"Category\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"activated\": { \"title\": \"Activated\", \"type\": \"boolean\" }, \"level\": { \"title\": \"Level\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" } }, \"required\": [ \"id\", \"online\", \"activated\" ], \"additionalProperties\": false } ``` ### /building_map ``` { \"title\": \"BuildingMap\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Level\" } }, \"lifts\": { \"title\": \"Lifts\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Lift\" } } }, \"required\": [ \"name\", \"levels\", \"lifts\" ], \"definitions\": { \"AffineImage\": { \"title\": \"AffineImage\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x_offset\": { \"title\": \"X Offset\", \"default\": 0, \"type\": \"number\" }, \"y_offset\": { \"title\": \"Y Offset\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"scale\": { \"title\": \"Scale\", \"default\": 0, \"type\": \"number\" }, \"encoding\": { \"title\": \"Encoding\", \"default\": \"\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"string\" } }, \"required\": [ \"name\", \"x_offset\", \"y_offset\", \"yaw\", \"scale\", \"encoding\", \"data\" ] }, \"Place\": { \"title\": \"Place\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"position_tolerance\": { \"title\": \"Position Tolerance\", \"default\": 0, \"type\": \"number\" }, \"yaw_tolerance\": { \"title\": \"Yaw Tolerance\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"x\", \"y\", \"yaw\", \"position_tolerance\", \"yaw_tolerance\" ] }, \"Door\": { \"title\": \"Door\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"v1_x\": { \"title\": \"V1 X\", \"default\": 0, \"type\": \"number\" }, \"v1_y\": { \"title\": \"V1 Y\", \"default\": 0, \"type\": \"number\" }, \"v2_x\": { \"title\": \"V2 X\", \"default\": 0, \"type\": \"number\" }, \"v2_y\": { \"title\": \"V2 Y\", \"default\": 0, \"type\": \"number\" }, \"door_type\": { \"title\": \"Door Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_range\": { \"title\": \"Motion Range\", \"default\": 0, \"type\": \"number\" }, \"motion_direction\": { \"title\": \"Motion Direction\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" } }, \"required\": [ \"name\", \"v1_x\", \"v1_y\", \"v2_x\", \"v2_y\", \"door_type\", \"motion_range\", \"motion_direction\" ] }, \"Param\": { \"title\": \"Param\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"value_int\": { \"title\": \"Value Int\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"value_float\": { \"title\": \"Value Float\", \"default\": 0, \"type\": \"number\" }, \"value_string\": { \"title\": \"Value String\", \"default\": \"\", \"type\": \"string\" }, \"value_bool\": { \"title\": \"Value Bool\", \"default\": false, \"type\": \"boolean\" } }, \"required\": [ \"name\", \"type\", \"value_int\", \"value_float\", \"value_string\", \"value_bool\" ] }, \"GraphNode\": { \"title\": \"GraphNode\", \"type\": \"object\", \"properties\": { \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"x\", \"y\", \"name\", \"params\" ] }, \"GraphEdge\": { \"title\": \"GraphEdge\", \"type\": \"object\", \"properties\": { \"v1_idx\": { \"title\": \"V1 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"v2_idx\": { \"title\": \"V2 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } }, \"edge_type\": { \"title\": \"Edge Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" } }, \"required\": [ \"v1_idx\", \"v2_idx\", \"params\", \"edge_type\" ] }, \"Graph\": { \"title\": \"Graph\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"vertices\": { \"title\": \"Vertices\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphNode\" } }, \"edges\": { \"title\": \"Edges\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphEdge\" } }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"name\", \"vertices\", \"edges\", \"params\" ] }, \"Level\": { \"title\": \"Level\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"elevation\": { \"title\": \"Elevation\", \"default\": 0, \"type\": \"number\" }, \"images\": { \"title\": \"Images\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AffineImage\" } }, \"places\": { \"title\": \"Places\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Place\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"nav_graphs\": { \"title\": \"Nav Graphs\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Graph\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] } }, \"required\": [ \"name\", \"elevation\", \"images\", \"places\", \"doors\", \"nav_graphs\", \"wall_graph\" ] }, \"Lift\": { \"title\": \"Lift\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] }, \"ref_x\": { \"title\": \"Ref X\", \"default\": 0, \"type\": \"number\" }, \"ref_y\": { \"title\": \"Ref Y\", \"default\": 0, \"type\": \"number\" }, \"ref_yaw\": { \"title\": \"Ref Yaw\", \"default\": 0, \"type\": \"number\" }, \"width\": { \"title\": \"Width\", \"default\": 0, \"type\": \"number\" }, \"depth\": { \"title\": \"Depth\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"levels\", \"doors\", \"wall_graph\", \"ref_x\", \"ref_y\", \"ref_yaw\", \"width\", \"depth\" ] } } } ``` ### /building_map/fire_alarm_trigger ``` { \"title\": \"FireAlarmTriggerState\", \"type\": \"object\", \"properties\": { \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"trigger\": { \"title\": \"Trigger\", \"type\": \"boolean\" } }, \"required\": [ \"unix_millis_time\", \"trigger\" ] } ``` ### /delivery_alerts ``` { \"title\": \"DeliveryAlert\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"action\": { \"$ref\": \"#/definitions/Action\" }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" } }, \"required\": [ \"id\", \"category\", \"tier\", \"action\", \"task_id\", \"message\" ], \"definitions\": { \"Category\": { \"title\": \"Category\", \"description\": \"An enumeration.\", \"enum\": [ \"missing\", \"wrong\", \"obstructed\", \"cancelled\" ], \"type\": \"string\" }, \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"warning\", \"error\" ], \"type\": \"string\" }, \"Action\": { \"title\": \"Action\", \"description\": \"An enumeration.\", \"enum\": [ \"waiting\", \"cancelled\", \"override\", \"resume\" ], \"type\": \"string\" } } } ``` ### /doors/{door_name}/state ``` { \"title\": \"DoorState\", \"type\": \"object\", \"properties\": { \"door_time\": { \"title\": \"Door Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"door_name\": { \"title\": \"Door Name\", \"default\": \"\", \"type\": \"string\" }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": { \"value\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/DoorMode\" } ] } }, \"required\": [ \"door_time\", \"door_name\", \"current_mode\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] }, \"DoorMode\": { \"title\": \"DoorMode\", \"type\": \"object\", \"properties\": { \"value\": { \"title\": \"Value\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"value\" ] } } } ``` ### /doors/{door_name}/health ``` { \"title\": \"DoorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /lifts/{lift_name}/state ``` { \"title\": \"LiftState\", \"type\": \"object\", \"properties\": { \"lift_time\": { \"title\": \"Lift Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"lift_name\": { \"title\": \"Lift Name\", \"default\": \"\", \"type\": \"string\" }, \"available_floors\": { \"title\": \"Available Floors\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"current_floor\": { \"title\": \"Current Floor\", \"default\": \"\", \"type\": \"string\" }, \"destination_floor\": { \"title\": \"Destination Floor\", \"default\": \"\", \"type\": \"string\" }, \"door_state\": { \"title\": \"Door State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_state\": { \"title\": \"Motion State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"available_modes\": { \"title\": \"Available Modes\", \"type\": \"array\", \"items\": { \"type\": \"integer\" } }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"session_id\": { \"title\": \"Session Id\", \"default\": \"\", \"type\": \"string\" } }, \"required\": [ \"lift_time\", \"lift_name\", \"available_floors\", \"current_floor\", \"destination_floor\", \"door_state\", \"motion_state\", \"available_modes\", \"current_mode\", \"session_id\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /lifts/{lift_name}/health ``` { \"title\": \"LiftHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /tasks/{task_id}/state ``` { \"title\": \"TaskState\", \"type\": \"object\", \"properties\": { \"booking\": { \"$ref\": \"#/definitions/Booking\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"assigned_to\": { \"title\": \"Assigned To\", \"description\": \"Which agent (robot) is the task assigned to\", \"allOf\": [ { \"$ref\": \"#/definitions/AssignedTo\" } ] }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"dispatch\": { \"$ref\": \"#/definitions/Dispatch\" }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary of the states of the phases of the task. The keys (property names) are phase IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phase\" } }, \"completed\": { \"title\": \"Completed\", \"description\": \"An array of the IDs of completed phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"active\": { \"title\": \"Active\", \"description\": \"The ID of the active phase for this task\", \"allOf\": [ { \"$ref\": \"#/definitions/Id\" } ] }, \"pending\": { \"title\": \"Pending\", \"description\": \"An array of the pending phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"interruptions\": { \"title\": \"Interruptions\", \"description\": \"A dictionary of interruptions that have been applied to this task. The keys (property names) are the unique token of the interruption request.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Interruption\" } }, \"cancellation\": { \"title\": \"Cancellation\", \"description\": \"If the task was cancelled, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Cancellation\" } ] }, \"killed\": { \"title\": \"Killed\", \"description\": \"If the task was killed, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Killed\" } ] } }, \"required\": [ \"booking\" ], \"definitions\": { \"Booking\": { \"title\": \"Booking\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"description\": \"The unique identifier for this task\", \"type\": \"string\" }, \"unix_millis_earliest_start_time\": { \"title\": \"Unix Millis Earliest Start Time\", \"type\": \"integer\" }, \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"type\": \"integer\" }, \"priority\": { \"title\": \"Priority\", \"description\": \"Priority information about this task\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"string\" } ] }, \"labels\": { \"title\": \"Labels\", \"description\": \"Information about how and why this task was booked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requester\": { \"title\": \"Requester\", \"description\": \"(Optional) An identifier for the entity that requested this task\", \"type\": \"string\" } }, \"required\": [ \"id\" ] }, \"Category\": { \"title\": \"Category\", \"description\": \"The category of this task or phase\", \"type\": \"string\" }, \"Detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about a task, phase, or event\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] }, \"EstimateMillis\": { \"title\": \"EstimateMillis\", \"description\": \"An estimate, in milliseconds, of how long the subject will take to complete\", \"minimum\": 0, \"type\": \"integer\" }, \"AssignedTo\": { \"title\": \"AssignedTo\", \"type\": \"object\", \"properties\": { \"group\": { \"title\": \"Group\", \"type\": \"string\" }, \"name\": { \"title\": \"Name\", \"type\": \"string\" } }, \"required\": [ \"group\", \"name\" ] }, \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"blocked\", \"error\", \"failed\", \"queued\", \"standby\", \"underway\", \"delayed\", \"skipped\", \"canceled\", \"killed\", \"completed\" ] }, \"Status1\": { \"title\": \"Status1\", \"description\": \"An enumeration.\", \"enum\": [ \"queued\", \"selected\", \"dispatched\", \"failed_to_assign\", \"canceled_in_flight\" ] }, \"Assignment\": { \"title\": \"Assignment\", \"type\": \"object\", \"properties\": { \"fleet_name\": { \"title\": \"Fleet Name\", \"type\": \"string\" }, \"expected_robot_name\": { \"title\": \"Expected Robot Name\", \"type\": \"string\" } } }, \"Error\": { \"title\": \"Error\", \"type\": \"object\", \"properties\": { \"code\": { \"title\": \"Code\", \"description\": \"A standard code for the kind of error that has occurred\", \"minimum\": 0, \"type\": \"integer\" }, \"category\": { \"title\": \"Category\", \"description\": \"The category of the error\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Details about the error\", \"type\": \"string\" } } }, \"Dispatch\": { \"title\": \"Dispatch\", \"type\": \"object\", \"properties\": { \"status\": { \"$ref\": \"#/definitions/Status1\" }, \"assignment\": { \"$ref\": \"#/definitions/Assignment\" }, \"errors\": { \"title\": \"Errors\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Error\" } } }, \"required\": [ \"status\" ] }, \"Id\": { \"title\": \"Id\", \"minimum\": 0, \"type\": \"integer\" }, \"EventState\": { \"title\": \"EventState\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"name\": { \"title\": \"Name\", \"description\": \"The brief name of the event\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the event\", \"allOf\": [ { \"$ref\": \"#/definitions/Detail\" } ] }, \"deps\": { \"title\": \"Deps\", \"description\": \"This event may depend on other events. This array contains the IDs of those other event dependencies.\", \"type\": \"array\", \"items\": { \"type\": \"integer\", \"minimum\": 0 } } }, \"required\": [ \"id\" ] }, \"Undo\": { \"title\": \"Undo\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the undo skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the undo skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"SkipPhaseRequest\": { \"title\": \"SkipPhaseRequest\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"undo\": { \"title\": \"Undo\", \"description\": \"Information about an undo skip request that applied to this request\", \"allOf\": [ { \"$ref\": \"#/definitions/Undo\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Phase\": { \"title\": \"Phase\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"final_event_id\": { \"$ref\": \"#/definitions/Id\" }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary of events for this phase. The keys (property names) are the event IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/EventState\" } }, \"skip_requests\": { \"title\": \"Skip Requests\", \"description\": \"Information about any skip requests that have been received\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/SkipPhaseRequest\" } } }, \"required\": [ \"id\" ] }, \"ResumedBy\": { \"title\": \"ResumedBy\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the resume request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the resume request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"labels\" ] }, \"Interruption\": { \"title\": \"Interruption\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the interruption request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the interruption\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"resumed_by\": { \"title\": \"Resumed By\", \"description\": \"Information about the resume request that ended this interruption. This field will be missing if the interruption is still active.\", \"allOf\": [ { \"$ref\": \"#/definitions/ResumedBy\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Cancellation\": { \"title\": \"Cancellation\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the cancel request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Killed\": { \"title\": \"Killed\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the kill request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] } } } ``` ### /tasks/{task_id}/log ``` { \"title\": \"TaskEventLog\", \"type\": \"object\", \"properties\": { \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary whose keys (property names) are the indices of a phase\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phases\" } } }, \"required\": [ \"task_id\" ], \"additionalProperties\": false, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] }, \"Phases\": { \"title\": \"Phases\", \"type\": \"object\", \"properties\": { \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall phase\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary whose keys (property names) are the indices of an event in the phase\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"additionalProperties\": false } } } ``` ### /dispensers/{guid}/state ``` { \"title\": \"DispenserState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /dispensers/{guid}/health ``` { \"title\": \"DispenserHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /ingestors/{guid}/state ``` { \"title\": \"IngestorState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /ingestors/{guid}/health ``` { \"title\": \"IngestorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /fleets/{name}/state ``` { \"title\": \"FleetState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"robots\": { \"title\": \"Robots\", \"description\": \"A dictionary of the states of the robots that belong to this fleet\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/RobotState\" } } }, \"definitions\": { \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"offline\", \"shutdown\", \"idle\", \"charging\", \"working\", \"error\" ] }, \"Location2D\": { \"title\": \"Location2D\", \"type\": \"object\", \"properties\": { \"map\": { \"title\": \"Map\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"type\": \"number\" } }, \"required\": [ \"map\", \"x\", \"y\", \"yaw\" ] }, \"Issue\": { \"title\": \"Issue\", \"type\": \"object\", \"properties\": { \"category\": { \"title\": \"Category\", \"description\": \"Category of the robot\'s issue\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the issue\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] } } }, \"Commission\": { \"title\": \"Commission\", \"type\": \"object\", \"properties\": { \"dispatch_tasks\": { \"title\": \"Dispatch Tasks\", \"description\": \"Should the robot accept dispatched tasks, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"direct_tasks\": { \"title\": \"Direct Tasks\", \"description\": \"Should the robot accept direct task requests, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"idle_behavior\": { \"title\": \"Idle Behavior\", \"description\": \"Should the robot perform its idle behavior, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" } } }, \"MutexGroups\": { \"title\": \"MutexGroups\", \"type\": \"object\", \"properties\": { \"locked\": { \"title\": \"Locked\", \"description\": \"A list of mutex groups that this robot has currently locked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requesting\": { \"title\": \"Requesting\", \"description\": \"A list of the mutex groups that this robot is currently requesting but has not lockd yet\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } } }, \"RobotState\": { \"title\": \"RobotState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"status\": { \"description\": \"A simple token representing the status of the robot\", \"allOf\": [ { \"$ref\": \"#/definitions/Status\" } ] }, \"task_id\": { \"title\": \"Task Id\", \"description\": \"The ID of the task this robot is currently working on. Empty string if the robot is not working on a task.\", \"type\": \"string\" }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"location\": { \"$ref\": \"#/definitions/Location2D\" }, \"battery\": { \"title\": \"Battery\", \"description\": \"State of charge of the battery. Values range from 0.0 (depleted) to 1.0 (fully charged)\", \"minimum\": 0.0, \"maximum\": 1.0, \"type\": \"number\" }, \"issues\": { \"title\": \"Issues\", \"description\": \"A list of issues with the robot that operators need to address\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Issue\" } }, \"commission\": { \"$ref\": \"#/definitions/Commission\" }, \"mutex_groups\": { \"title\": \"Mutex Groups\", \"description\": \"Information about the mutex groups that this robot is interacting with\", \"allOf\": [ { \"$ref\": \"#/definitions/MutexGroups\" } ] } } } } } ``` ### /fleets/{name}/log ``` { \"title\": \"FleetLog\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log for the overall fleet\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"robots\": { \"title\": \"Robots\", \"description\": \"Dictionary of logs for the individual robots. The keys (property names) are the robot names.\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] } } } ``` + * # NOTE: This endpoint is here for documentation purposes only, this is _not_ a REST endpoint. ## About This exposes a minimal pubsub system built on top of socket.io. It works similar to a normal socket.io endpoint, except that are 2 special rooms which control subscriptions. ## Rooms ### subscribe Clients must send a message to this room to start receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### unsubscribe Clients can send a message to this room to stop receiving messages on other rooms. The message must be of the form: ``` { \"room\": \"\" } ``` ### /alerts/requests ``` { \"title\": \"AlertRequest\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"unix_millis_alert_time\": { \"title\": \"Unix Millis Alert Time\", \"type\": \"integer\" }, \"title\": { \"title\": \"Title\", \"type\": \"string\" }, \"subtitle\": { \"title\": \"Subtitle\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" }, \"display\": { \"title\": \"Display\", \"type\": \"boolean\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"responses_available\": { \"title\": \"Responses Available\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"alert_parameters\": { \"title\": \"Alert Parameters\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AlertParameter\" } }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" } }, \"required\": [ \"id\", \"unix_millis_alert_time\", \"title\", \"subtitle\", \"message\", \"display\", \"tier\", \"responses_available\", \"alert_parameters\" ], \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"info\", \"warning\", \"error\" ], \"type\": \"string\" }, \"AlertParameter\": { \"title\": \"AlertParameter\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"value\": { \"title\": \"Value\", \"type\": \"string\" } }, \"required\": [ \"name\", \"value\" ] } } } ``` ### /alerts/responses ``` { \"title\": \"AlertResponse\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"unix_millis_response_time\": { \"title\": \"Unix Millis Response Time\", \"type\": \"integer\" }, \"response\": { \"title\": \"Response\", \"type\": \"string\" } }, \"required\": [ \"id\", \"unix_millis_response_time\", \"response\" ] } ``` ### /beacons ``` { \"title\": \"BeaconState\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"maxLength\": 255, \"type\": \"string\" }, \"online\": { \"title\": \"Online\", \"type\": \"boolean\" }, \"category\": { \"title\": \"Category\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"activated\": { \"title\": \"Activated\", \"type\": \"boolean\" }, \"level\": { \"title\": \"Level\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" } }, \"required\": [ \"id\", \"online\", \"activated\" ], \"additionalProperties\": false } ``` ### /building_map ``` { \"title\": \"BuildingMap\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Level\" } }, \"lifts\": { \"title\": \"Lifts\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Lift\" } } }, \"required\": [ \"name\", \"levels\", \"lifts\" ], \"definitions\": { \"AffineImage\": { \"title\": \"AffineImage\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x_offset\": { \"title\": \"X Offset\", \"default\": 0, \"type\": \"number\" }, \"y_offset\": { \"title\": \"Y Offset\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"scale\": { \"title\": \"Scale\", \"default\": 0, \"type\": \"number\" }, \"encoding\": { \"title\": \"Encoding\", \"default\": \"\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"string\" } }, \"required\": [ \"name\", \"x_offset\", \"y_offset\", \"yaw\", \"scale\", \"encoding\", \"data\" ] }, \"Place\": { \"title\": \"Place\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"default\": 0, \"type\": \"number\" }, \"position_tolerance\": { \"title\": \"Position Tolerance\", \"default\": 0, \"type\": \"number\" }, \"yaw_tolerance\": { \"title\": \"Yaw Tolerance\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"x\", \"y\", \"yaw\", \"position_tolerance\", \"yaw_tolerance\" ] }, \"Door\": { \"title\": \"Door\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"v1_x\": { \"title\": \"V1 X\", \"default\": 0, \"type\": \"number\" }, \"v1_y\": { \"title\": \"V1 Y\", \"default\": 0, \"type\": \"number\" }, \"v2_x\": { \"title\": \"V2 X\", \"default\": 0, \"type\": \"number\" }, \"v2_y\": { \"title\": \"V2 Y\", \"default\": 0, \"type\": \"number\" }, \"door_type\": { \"title\": \"Door Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_range\": { \"title\": \"Motion Range\", \"default\": 0, \"type\": \"number\" }, \"motion_direction\": { \"title\": \"Motion Direction\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" } }, \"required\": [ \"name\", \"v1_x\", \"v1_y\", \"v2_x\", \"v2_y\", \"door_type\", \"motion_range\", \"motion_direction\" ] }, \"Param\": { \"title\": \"Param\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"value_int\": { \"title\": \"Value Int\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"value_float\": { \"title\": \"Value Float\", \"default\": 0, \"type\": \"number\" }, \"value_string\": { \"title\": \"Value String\", \"default\": \"\", \"type\": \"string\" }, \"value_bool\": { \"title\": \"Value Bool\", \"default\": false, \"type\": \"boolean\" } }, \"required\": [ \"name\", \"type\", \"value_int\", \"value_float\", \"value_string\", \"value_bool\" ] }, \"GraphNode\": { \"title\": \"GraphNode\", \"type\": \"object\", \"properties\": { \"x\": { \"title\": \"X\", \"default\": 0, \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"default\": 0, \"type\": \"number\" }, \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"x\", \"y\", \"name\", \"params\" ] }, \"GraphEdge\": { \"title\": \"GraphEdge\", \"type\": \"object\", \"properties\": { \"v1_idx\": { \"title\": \"V1 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"v2_idx\": { \"title\": \"V2 Idx\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } }, \"edge_type\": { \"title\": \"Edge Type\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" } }, \"required\": [ \"v1_idx\", \"v2_idx\", \"params\", \"edge_type\" ] }, \"Graph\": { \"title\": \"Graph\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"vertices\": { \"title\": \"Vertices\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphNode\" } }, \"edges\": { \"title\": \"Edges\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/GraphEdge\" } }, \"params\": { \"title\": \"Params\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Param\" } } }, \"required\": [ \"name\", \"vertices\", \"edges\", \"params\" ] }, \"Level\": { \"title\": \"Level\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"elevation\": { \"title\": \"Elevation\", \"default\": 0, \"type\": \"number\" }, \"images\": { \"title\": \"Images\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/AffineImage\" } }, \"places\": { \"title\": \"Places\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Place\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"nav_graphs\": { \"title\": \"Nav Graphs\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Graph\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] } }, \"required\": [ \"name\", \"elevation\", \"images\", \"places\", \"doors\", \"nav_graphs\", \"wall_graph\" ] }, \"Lift\": { \"title\": \"Lift\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"default\": \"\", \"type\": \"string\" }, \"levels\": { \"title\": \"Levels\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"doors\": { \"title\": \"Doors\", \"default\": [], \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Door\" } }, \"wall_graph\": { \"title\": \"Wall Graph\", \"default\": { \"name\": \"\", \"vertices\": [], \"edges\": [], \"params\": [] }, \"allOf\": [ { \"$ref\": \"#/definitions/Graph\" } ] }, \"ref_x\": { \"title\": \"Ref X\", \"default\": 0, \"type\": \"number\" }, \"ref_y\": { \"title\": \"Ref Y\", \"default\": 0, \"type\": \"number\" }, \"ref_yaw\": { \"title\": \"Ref Yaw\", \"default\": 0, \"type\": \"number\" }, \"width\": { \"title\": \"Width\", \"default\": 0, \"type\": \"number\" }, \"depth\": { \"title\": \"Depth\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"name\", \"levels\", \"doors\", \"wall_graph\", \"ref_x\", \"ref_y\", \"ref_yaw\", \"width\", \"depth\" ] } } } ``` ### /building_map/fire_alarm_trigger ``` { \"title\": \"FireAlarmTriggerState\", \"type\": \"object\", \"properties\": { \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"trigger\": { \"title\": \"Trigger\", \"type\": \"boolean\" } }, \"required\": [ \"unix_millis_time\", \"trigger\" ] } ``` ### /delivery_alerts ``` { \"title\": \"DeliveryAlert\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"tier\": { \"$ref\": \"#/definitions/Tier\" }, \"action\": { \"$ref\": \"#/definitions/Action\" }, \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"message\": { \"title\": \"Message\", \"type\": \"string\" } }, \"required\": [ \"id\", \"category\", \"tier\", \"action\", \"task_id\", \"message\" ], \"definitions\": { \"Category\": { \"title\": \"Category\", \"description\": \"An enumeration.\", \"enum\": [ \"missing\", \"wrong\", \"obstructed\", \"cancelled\" ], \"type\": \"string\" }, \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"warning\", \"error\" ], \"type\": \"string\" }, \"Action\": { \"title\": \"Action\", \"description\": \"An enumeration.\", \"enum\": [ \"waiting\", \"cancelled\", \"override\", \"resume\" ], \"type\": \"string\" } } } ``` ### /doors/{door_name}/state ``` { \"title\": \"DoorState\", \"type\": \"object\", \"properties\": { \"door_time\": { \"title\": \"Door Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"door_name\": { \"title\": \"Door Name\", \"default\": \"\", \"type\": \"string\" }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": { \"value\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/DoorMode\" } ] } }, \"required\": [ \"door_time\", \"door_name\", \"current_mode\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] }, \"DoorMode\": { \"title\": \"DoorMode\", \"type\": \"object\", \"properties\": { \"value\": { \"title\": \"Value\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"value\" ] } } } ``` ### /doors/{door_name}/health ``` { \"title\": \"DoorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /lifts/{lift_name}/state ``` { \"title\": \"LiftState\", \"type\": \"object\", \"properties\": { \"lift_time\": { \"title\": \"Lift Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"lift_name\": { \"title\": \"Lift Name\", \"default\": \"\", \"type\": \"string\" }, \"available_floors\": { \"title\": \"Available Floors\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"current_floor\": { \"title\": \"Current Floor\", \"default\": \"\", \"type\": \"string\" }, \"destination_floor\": { \"title\": \"Destination Floor\", \"default\": \"\", \"type\": \"string\" }, \"door_state\": { \"title\": \"Door State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"motion_state\": { \"title\": \"Motion State\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"available_modes\": { \"title\": \"Available Modes\", \"type\": \"array\", \"items\": { \"type\": \"integer\" } }, \"current_mode\": { \"title\": \"Current Mode\", \"default\": 0, \"minimum\": 0, \"maximum\": 255, \"type\": \"integer\" }, \"session_id\": { \"title\": \"Session Id\", \"default\": \"\", \"type\": \"string\" } }, \"required\": [ \"lift_time\", \"lift_name\", \"available_floors\", \"current_floor\", \"destination_floor\", \"door_state\", \"motion_state\", \"available_modes\", \"current_mode\", \"session_id\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /lifts/{lift_name}/health ``` { \"title\": \"LiftHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /tasks/{task_id}/state ``` { \"title\": \"TaskState\", \"type\": \"object\", \"properties\": { \"booking\": { \"$ref\": \"#/definitions/Booking\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"assigned_to\": { \"title\": \"Assigned To\", \"description\": \"Which agent (robot) is the task assigned to\", \"allOf\": [ { \"$ref\": \"#/definitions/AssignedTo\" } ] }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"dispatch\": { \"$ref\": \"#/definitions/Dispatch\" }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary of the states of the phases of the task. The keys (property names) are phase IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phase\" } }, \"completed\": { \"title\": \"Completed\", \"description\": \"An array of the IDs of completed phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"active\": { \"title\": \"Active\", \"description\": \"The ID of the active phase for this task\", \"allOf\": [ { \"$ref\": \"#/definitions/Id\" } ] }, \"pending\": { \"title\": \"Pending\", \"description\": \"An array of the pending phases of this task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Id\" } }, \"interruptions\": { \"title\": \"Interruptions\", \"description\": \"A dictionary of interruptions that have been applied to this task. The keys (property names) are the unique token of the interruption request.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Interruption\" } }, \"cancellation\": { \"title\": \"Cancellation\", \"description\": \"If the task was cancelled, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Cancellation\" } ] }, \"killed\": { \"title\": \"Killed\", \"description\": \"If the task was killed, this will describe information about the request.\", \"allOf\": [ { \"$ref\": \"#/definitions/Killed\" } ] } }, \"required\": [ \"booking\" ], \"definitions\": { \"Booking\": { \"title\": \"Booking\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"description\": \"The unique identifier for this task\", \"type\": \"string\" }, \"unix_millis_earliest_start_time\": { \"title\": \"Unix Millis Earliest Start Time\", \"type\": \"integer\" }, \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"type\": \"integer\" }, \"priority\": { \"title\": \"Priority\", \"description\": \"Priority information about this task\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"string\" } ] }, \"labels\": { \"title\": \"Labels\", \"description\": \"Information about how and why this task was booked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requester\": { \"title\": \"Requester\", \"description\": \"(Optional) An identifier for the entity that requested this task\", \"type\": \"string\" } }, \"required\": [ \"id\" ] }, \"Category\": { \"title\": \"Category\", \"description\": \"The category of this task or phase\", \"type\": \"string\" }, \"Detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about a task, phase, or event\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] }, \"EstimateMillis\": { \"title\": \"EstimateMillis\", \"description\": \"An estimate, in milliseconds, of how long the subject will take to complete\", \"minimum\": 0, \"type\": \"integer\" }, \"AssignedTo\": { \"title\": \"AssignedTo\", \"type\": \"object\", \"properties\": { \"group\": { \"title\": \"Group\", \"type\": \"string\" }, \"name\": { \"title\": \"Name\", \"type\": \"string\" } }, \"required\": [ \"group\", \"name\" ] }, \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"blocked\", \"error\", \"failed\", \"queued\", \"standby\", \"underway\", \"delayed\", \"skipped\", \"canceled\", \"killed\", \"completed\" ] }, \"Status1\": { \"title\": \"Status1\", \"description\": \"An enumeration.\", \"enum\": [ \"queued\", \"selected\", \"dispatched\", \"failed_to_assign\", \"canceled_in_flight\" ] }, \"Assignment\": { \"title\": \"Assignment\", \"type\": \"object\", \"properties\": { \"fleet_name\": { \"title\": \"Fleet Name\", \"type\": \"string\" }, \"expected_robot_name\": { \"title\": \"Expected Robot Name\", \"type\": \"string\" } } }, \"Error\": { \"title\": \"Error\", \"type\": \"object\", \"properties\": { \"code\": { \"title\": \"Code\", \"description\": \"A standard code for the kind of error that has occurred\", \"minimum\": 0, \"type\": \"integer\" }, \"category\": { \"title\": \"Category\", \"description\": \"The category of the error\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Details about the error\", \"type\": \"string\" } } }, \"Dispatch\": { \"title\": \"Dispatch\", \"type\": \"object\", \"properties\": { \"status\": { \"$ref\": \"#/definitions/Status1\" }, \"assignment\": { \"$ref\": \"#/definitions/Assignment\" }, \"errors\": { \"title\": \"Errors\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Error\" } } }, \"required\": [ \"status\" ] }, \"Id\": { \"title\": \"Id\", \"minimum\": 0, \"type\": \"integer\" }, \"EventState\": { \"title\": \"EventState\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"status\": { \"$ref\": \"#/definitions/Status\" }, \"name\": { \"title\": \"Name\", \"description\": \"The brief name of the event\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the event\", \"allOf\": [ { \"$ref\": \"#/definitions/Detail\" } ] }, \"deps\": { \"title\": \"Deps\", \"description\": \"This event may depend on other events. This array contains the IDs of those other event dependencies.\", \"type\": \"array\", \"items\": { \"type\": \"integer\", \"minimum\": 0 } } }, \"required\": [ \"id\" ] }, \"Undo\": { \"title\": \"Undo\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the undo skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the undo skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"SkipPhaseRequest\": { \"title\": \"SkipPhaseRequest\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the skip request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the skip request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"undo\": { \"title\": \"Undo\", \"description\": \"Information about an undo skip request that applied to this request\", \"allOf\": [ { \"$ref\": \"#/definitions/Undo\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Phase\": { \"title\": \"Phase\", \"type\": \"object\", \"properties\": { \"id\": { \"$ref\": \"#/definitions/Id\" }, \"category\": { \"$ref\": \"#/definitions/Category\" }, \"detail\": { \"$ref\": \"#/definitions/Detail\" }, \"unix_millis_start_time\": { \"title\": \"Unix Millis Start Time\", \"type\": \"integer\" }, \"unix_millis_finish_time\": { \"title\": \"Unix Millis Finish Time\", \"type\": \"integer\" }, \"original_estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"estimate_millis\": { \"$ref\": \"#/definitions/EstimateMillis\" }, \"final_event_id\": { \"$ref\": \"#/definitions/Id\" }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary of events for this phase. The keys (property names) are the event IDs, which are integers.\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/EventState\" } }, \"skip_requests\": { \"title\": \"Skip Requests\", \"description\": \"Information about any skip requests that have been received\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/SkipPhaseRequest\" } } }, \"required\": [ \"id\" ] }, \"ResumedBy\": { \"title\": \"ResumedBy\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the resume request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the resume request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"labels\" ] }, \"Interruption\": { \"title\": \"Interruption\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the interruption request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the purpose of the interruption\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"resumed_by\": { \"title\": \"Resumed By\", \"description\": \"Information about the resume request that ended this interruption. This field will be missing if the interruption is still active.\", \"allOf\": [ { \"$ref\": \"#/definitions/ResumedBy\" } ] } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Cancellation\": { \"title\": \"Cancellation\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the cancel request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] }, \"Killed\": { \"title\": \"Killed\", \"type\": \"object\", \"properties\": { \"unix_millis_request_time\": { \"title\": \"Unix Millis Request Time\", \"description\": \"The time that the cancellation request arrived\", \"type\": \"integer\" }, \"labels\": { \"title\": \"Labels\", \"description\": \"Labels to describe the kill request\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } }, \"required\": [ \"unix_millis_request_time\", \"labels\" ] } } } ``` ### /tasks/{task_id}/log ``` { \"title\": \"TaskEventLog\", \"type\": \"object\", \"properties\": { \"task_id\": { \"title\": \"Task Id\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall task\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"phases\": { \"title\": \"Phases\", \"description\": \"A dictionary whose keys (property names) are the indices of a phase\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/Phases\" } } }, \"required\": [ \"task_id\" ], \"additionalProperties\": false, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] }, \"Phases\": { \"title\": \"Phases\", \"type\": \"object\", \"properties\": { \"log\": { \"title\": \"Log\", \"description\": \"Log entries related to the overall phase\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"events\": { \"title\": \"Events\", \"description\": \"A dictionary whose keys (property names) are the indices of an event in the phase\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"additionalProperties\": false } } } ``` ### /dispensers/{guid}/state ``` { \"title\": \"DispenserState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /dispensers/{guid}/health ``` { \"title\": \"DispenserHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /ingestors/{guid}/state ``` { \"title\": \"IngestorState\", \"type\": \"object\", \"properties\": { \"time\": { \"title\": \"Time\", \"default\": { \"sec\": 0, \"nanosec\": 0 }, \"allOf\": [ { \"$ref\": \"#/definitions/Time\" } ] }, \"guid\": { \"title\": \"Guid\", \"default\": \"\", \"type\": \"string\" }, \"mode\": { \"title\": \"Mode\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"request_guid_queue\": { \"title\": \"Request Guid Queue\", \"default\": [], \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"seconds_remaining\": { \"title\": \"Seconds Remaining\", \"default\": 0, \"type\": \"number\" } }, \"required\": [ \"time\", \"guid\", \"mode\", \"request_guid_queue\", \"seconds_remaining\" ], \"definitions\": { \"Time\": { \"title\": \"Time\", \"type\": \"object\", \"properties\": { \"sec\": { \"title\": \"Sec\", \"default\": 0, \"minimum\": -2147483648, \"maximum\": 2147483647, \"type\": \"integer\" }, \"nanosec\": { \"title\": \"Nanosec\", \"default\": 0, \"minimum\": 0, \"maximum\": 4294967295, \"type\": \"integer\" } }, \"required\": [ \"sec\", \"nanosec\" ] } } } ``` ### /ingestors/{guid}/health ``` { \"title\": \"IngestorHealth\", \"type\": \"object\", \"properties\": { \"health_status\": { \"title\": \"Health Status\", \"maxLength\": 255, \"nullable\": true, \"type\": \"string\" }, \"health_message\": { \"title\": \"Health Message\", \"nullable\": true, \"type\": \"string\" }, \"id_\": { \"title\": \"Id \", \"maxLength\": 255, \"type\": \"string\" } }, \"required\": [ \"health_status\", \"id_\" ], \"additionalProperties\": false } ``` ### /fleets/{name}/state ``` { \"title\": \"FleetState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"robots\": { \"title\": \"Robots\", \"description\": \"A dictionary of the states of the robots that belong to this fleet\", \"type\": \"object\", \"additionalProperties\": { \"$ref\": \"#/definitions/RobotState\" } } }, \"definitions\": { \"Status\": { \"title\": \"Status\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"offline\", \"shutdown\", \"idle\", \"charging\", \"working\", \"error\" ] }, \"Location2D\": { \"title\": \"Location2D\", \"type\": \"object\", \"properties\": { \"map\": { \"title\": \"Map\", \"type\": \"string\" }, \"x\": { \"title\": \"X\", \"type\": \"number\" }, \"y\": { \"title\": \"Y\", \"type\": \"number\" }, \"yaw\": { \"title\": \"Yaw\", \"type\": \"number\" } }, \"required\": [ \"map\", \"x\", \"y\", \"yaw\" ] }, \"Issue\": { \"title\": \"Issue\", \"type\": \"object\", \"properties\": { \"category\": { \"title\": \"Category\", \"description\": \"Category of the robot\'s issue\", \"type\": \"string\" }, \"detail\": { \"title\": \"Detail\", \"description\": \"Detailed information about the issue\", \"anyOf\": [ { \"type\": \"object\" }, { \"type\": \"array\", \"items\": {} }, { \"type\": \"string\" } ] } } }, \"Commission\": { \"title\": \"Commission\", \"type\": \"object\", \"properties\": { \"dispatch_tasks\": { \"title\": \"Dispatch Tasks\", \"description\": \"Should the robot accept dispatched tasks, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"direct_tasks\": { \"title\": \"Direct Tasks\", \"description\": \"Should the robot accept direct task requests, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" }, \"idle_behavior\": { \"title\": \"Idle Behavior\", \"description\": \"Should the robot perform its idle behavior, true/false. When used in a request, leave this unset to not change the robot\'s current value.\", \"type\": \"boolean\" } } }, \"MutexGroups\": { \"title\": \"MutexGroups\", \"type\": \"object\", \"properties\": { \"locked\": { \"title\": \"Locked\", \"description\": \"A list of mutex groups that this robot has currently locked\", \"type\": \"array\", \"items\": { \"type\": \"string\" } }, \"requesting\": { \"title\": \"Requesting\", \"description\": \"A list of the mutex groups that this robot is currently requesting but has not lockd yet\", \"type\": \"array\", \"items\": { \"type\": \"string\" } } } }, \"RobotState\": { \"title\": \"RobotState\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"status\": { \"description\": \"A simple token representing the status of the robot\", \"allOf\": [ { \"$ref\": \"#/definitions/Status\" } ] }, \"task_id\": { \"title\": \"Task Id\", \"description\": \"The ID of the task this robot is currently working on. Empty string if the robot is not working on a task.\", \"type\": \"string\" }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"location\": { \"$ref\": \"#/definitions/Location2D\" }, \"battery\": { \"title\": \"Battery\", \"description\": \"State of charge of the battery. Values range from 0.0 (depleted) to 1.0 (fully charged)\", \"minimum\": 0.0, \"maximum\": 1.0, \"type\": \"number\" }, \"issues\": { \"title\": \"Issues\", \"description\": \"A list of issues with the robot that operators need to address\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/Issue\" } }, \"commission\": { \"$ref\": \"#/definitions/Commission\" }, \"mutex_groups\": { \"title\": \"Mutex Groups\", \"description\": \"Information about the mutex groups that this robot is interacting with\", \"allOf\": [ { \"$ref\": \"#/definitions/MutexGroups\" } ] } } } } } ``` ### /fleets/{name}/log ``` { \"title\": \"FleetLog\", \"type\": \"object\", \"properties\": { \"name\": { \"title\": \"Name\", \"type\": \"string\" }, \"log\": { \"title\": \"Log\", \"description\": \"Log for the overall fleet\", \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } }, \"robots\": { \"title\": \"Robots\", \"description\": \"Dictionary of logs for the individual robots. The keys (property names) are the robot names.\", \"type\": \"object\", \"additionalProperties\": { \"type\": \"array\", \"items\": { \"$ref\": \"#/definitions/LogEntry\" } } } }, \"definitions\": { \"Tier\": { \"title\": \"Tier\", \"description\": \"An enumeration.\", \"enum\": [ \"uninitialized\", \"info\", \"warning\", \"error\" ] }, \"LogEntry\": { \"title\": \"LogEntry\", \"type\": \"object\", \"properties\": { \"seq\": { \"title\": \"Seq\", \"description\": \"Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.\", \"exclusiveMaximum\": 4294967296, \"minimum\": 0, \"type\": \"integer\" }, \"tier\": { \"description\": \"The importance level of the log entry\", \"allOf\": [ { \"$ref\": \"#/definitions/Tier\" } ] }, \"unix_millis_time\": { \"title\": \"Unix Millis Time\", \"type\": \"integer\" }, \"text\": { \"title\": \"Text\", \"description\": \"The text of the log entry\", \"type\": \"string\" } }, \"required\": [ \"seq\", \"tier\", \"unix_millis_time\", \"text\" ] } } } ``` ### /rios ``` { \"title\": \"Rio\", \"type\": \"object\", \"properties\": { \"id\": { \"title\": \"Id\", \"type\": \"string\" }, \"type\": { \"title\": \"Type\", \"type\": \"string\" }, \"data\": { \"title\": \"Data\", \"type\": \"object\" } }, \"required\": [ \"id\", \"type\", \"data\" ] } ``` * @summary Socket.io endpoint * @param {*} [options] Override http request option. * @throws {RequiredError} @@ -8359,6 +8697,217 @@ export class LiftsApi extends BaseAPI { } } +/** + * RIOsApi - axios parameter creator + * @export + */ +export const RIOsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Put Rio + * @param {Rio} rio + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + putRioRiosPut: async (rio: Rio, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'rio' is not null or undefined + assertParamExists('putRioRiosPut', 'rio', rio); + const localVarPath = `/rios`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options }; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = { + ...localVarHeaderParameter, + ...headersFromBaseOptions, + ...options.headers, + }; + localVarRequestOptions.data = serializeDataIfNeeded( + rio, + localVarRequestOptions, + configuration, + ); + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Query Rios + * @param {string} [id] + * @param {string} [type] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + queryRiosRiosGet: async ( + id?: string, + type?: string, + options: AxiosRequestConfig = {}, + ): Promise => { + const localVarPath = `/rios`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options }; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (id !== undefined) { + localVarQueryParameter['id_'] = id; + } + + if (type !== undefined) { + localVarQueryParameter['type_'] = type; + } + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = { + ...localVarHeaderParameter, + ...headersFromBaseOptions, + ...options.headers, + }; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + }; +}; + +/** + * RIOsApi - functional programming interface + * @export + */ +export const RIOsApiFp = function (configuration?: Configuration) { + const localVarAxiosParamCreator = RIOsApiAxiosParamCreator(configuration); + return { + /** + * + * @summary Put Rio + * @param {Rio} rio + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async putRioRiosPut( + rio: Rio, + options?: AxiosRequestConfig, + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.putRioRiosPut(rio, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Query Rios + * @param {string} [id] + * @param {string} [type] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async queryRiosRiosGet( + id?: string, + type?: string, + options?: AxiosRequestConfig, + ): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.queryRiosRiosGet(id, type, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + }; +}; + +/** + * RIOsApi - factory interface + * @export + */ +export const RIOsApiFactory = function ( + configuration?: Configuration, + basePath?: string, + axios?: AxiosInstance, +) { + const localVarFp = RIOsApiFp(configuration); + return { + /** + * + * @summary Put Rio + * @param {Rio} rio + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + putRioRiosPut(rio: Rio, options?: any): AxiosPromise { + return localVarFp.putRioRiosPut(rio, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Query Rios + * @param {string} [id] + * @param {string} [type] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + queryRiosRiosGet(id?: string, type?: string, options?: any): AxiosPromise> { + return localVarFp + .queryRiosRiosGet(id, type, options) + .then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * RIOsApi - object-oriented interface + * @export + * @class RIOsApi + * @extends {BaseAPI} + */ +export class RIOsApi extends BaseAPI { + /** + * + * @summary Put Rio + * @param {Rio} rio + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof RIOsApi + */ + public putRioRiosPut(rio: Rio, options?: AxiosRequestConfig) { + return RIOsApiFp(this.configuration) + .putRioRiosPut(rio, options) + .then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Query Rios + * @param {string} [id] + * @param {string} [type] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof RIOsApi + */ + public queryRiosRiosGet(id?: string, type?: string, options?: AxiosRequestConfig) { + return RIOsApiFp(this.configuration) + .queryRiosRiosGet(id, type, options) + .then((request) => request(this.axios, this.basePath)); + } +} + /** * TasksApi - axios parameter creator * @export @@ -9486,13 +10035,13 @@ export const TasksApiAxiosParamCreator = function (configuration?: Configuration }; }, /** - * Note that sorting by `pickup` and `destination` is mutually exclusive and sorting by either of them will filter only tasks which has those labels. + * * @summary Query Task States * @param {string} [taskId] comma separated list of task ids * @param {string} [category] comma separated list of task categories * @param {string} [requester] comma separated list of requester names - * @param {string} [pickup] comma separated list of pickup names. [deprecated] use `label` instead - * @param {string} [destination] comma separated list of destination names, [deprecated] use `label` instead + * @param {string} [pickup] pickup name. [deprecated] use `label` instead + * @param {string} [destination] destination name, [deprecated] use `label` instead * @param {string} [assignedTo] comma separated list of assigned robot names * @param {string} [status] comma separated list of statuses * @param {string} [label] comma separated list of labels, each item must be in the form <key>=<value>, multiple items will filter tasks with all the labels @@ -10126,13 +10675,13 @@ export const TasksApiFp = function (configuration?: Configuration) { return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** - * Note that sorting by `pickup` and `destination` is mutually exclusive and sorting by either of them will filter only tasks which has those labels. + * * @summary Query Task States * @param {string} [taskId] comma separated list of task ids * @param {string} [category] comma separated list of task categories * @param {string} [requester] comma separated list of requester names - * @param {string} [pickup] comma separated list of pickup names. [deprecated] use `label` instead - * @param {string} [destination] comma separated list of destination names, [deprecated] use `label` instead + * @param {string} [pickup] pickup name. [deprecated] use `label` instead + * @param {string} [destination] destination name, [deprecated] use `label` instead * @param {string} [assignedTo] comma separated list of assigned robot names * @param {string} [status] comma separated list of statuses * @param {string} [label] comma separated list of labels, each item must be in the form <key>=<value>, multiple items will filter tasks with all the labels @@ -10591,13 +11140,13 @@ export const TasksApiFactory = function ( .then((request) => request(axios, basePath)); }, /** - * Note that sorting by `pickup` and `destination` is mutually exclusive and sorting by either of them will filter only tasks which has those labels. + * * @summary Query Task States * @param {string} [taskId] comma separated list of task ids * @param {string} [category] comma separated list of task categories * @param {string} [requester] comma separated list of requester names - * @param {string} [pickup] comma separated list of pickup names. [deprecated] use `label` instead - * @param {string} [destination] comma separated list of destination names, [deprecated] use `label` instead + * @param {string} [pickup] pickup name. [deprecated] use `label` instead + * @param {string} [destination] destination name, [deprecated] use `label` instead * @param {string} [assignedTo] comma separated list of assigned robot names * @param {string} [status] comma separated list of statuses * @param {string} [label] comma separated list of labels, each item must be in the form <key>=<value>, multiple items will filter tasks with all the labels @@ -11083,13 +11632,13 @@ export class TasksApi extends BaseAPI { } /** - * Note that sorting by `pickup` and `destination` is mutually exclusive and sorting by either of them will filter only tasks which has those labels. + * * @summary Query Task States * @param {string} [taskId] comma separated list of task ids * @param {string} [category] comma separated list of task categories * @param {string} [requester] comma separated list of requester names - * @param {string} [pickup] comma separated list of pickup names. [deprecated] use `label` instead - * @param {string} [destination] comma separated list of destination names, [deprecated] use `label` instead + * @param {string} [pickup] pickup name. [deprecated] use `label` instead + * @param {string} [destination] destination name, [deprecated] use `label` instead * @param {string} [assignedTo] comma separated list of assigned robot names * @param {string} [status] comma separated list of statuses * @param {string} [label] comma separated list of labels, each item must be in the form <key>=<value>, multiple items will filter tasks with all the labels diff --git a/packages/api-client/lib/version.ts b/packages/api-client/lib/version.ts index 889b1a0fa..c3c766609 100644 --- a/packages/api-client/lib/version.ts +++ b/packages/api-client/lib/version.ts @@ -3,6 +3,6 @@ import { version as rmfModelVer } from 'rmf-models'; export const version = { rmfModels: rmfModelVer, - rmfServer: '76d155a524e21ec399b1cb7ac058086a154a373c', + rmfServer: '2e78fded62245f24a712e0c34127cc28d0b36aad', openapiGenerator: '6.2.1', }; diff --git a/packages/api-client/schema/index.ts b/packages/api-client/schema/index.ts index 80f8bbc52..1ec93a1d2 100644 --- a/packages/api-client/schema/index.ts +++ b/packages/api-client/schema/index.ts @@ -6,7 +6,7 @@ export default { get: { summary: 'Socket.io endpoint', description: - '\n# NOTE: This endpoint is here for documentation purposes only, this is _not_ a REST endpoint.\n\n## About\nThis exposes a minimal pubsub system built on top of socket.io.\nIt works similar to a normal socket.io endpoint, except that are 2 special\nrooms which control subscriptions.\n\n## Rooms\n### subscribe\nClients must send a message to this room to start receiving messages on other rooms.\nThe message must be of the form:\n\n```\n{\n "room": ""\n}\n```\n\n### unsubscribe\nClients can send a message to this room to stop receiving messages on other rooms.\nThe message must be of the form:\n\n```\n{\n "room": ""\n}\n```\n \n### /alerts\n\n\n```\n{\n "title": "Alert",\n "description": "General alert that can be triggered by events.",\n "type": "object",\n "properties": {\n "id": {\n "title": "Id",\n "maxLength": 255,\n "type": "string"\n },\n "original_id": {\n "title": "Original Id",\n "maxLength": 255,\n "type": "string"\n },\n "category": {\n "title": "Category",\n "description": "Default: default
Task: task
Fleet: fleet
Robot: robot",\n "maxLength": 7,\n "type": "string"\n },\n "unix_millis_created_time": {\n "title": "Unix Millis Created Time",\n "minimum": -9223372036854775808,\n "maximum": 9223372036854775807,\n "type": "integer"\n },\n "acknowledged_by": {\n "title": "Acknowledged By",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "unix_millis_acknowledged_time": {\n "title": "Unix Millis Acknowledged Time",\n "minimum": -9223372036854775808,\n "maximum": 9223372036854775807,\n "nullable": true,\n "type": "integer"\n }\n },\n "required": [\n "id",\n "original_id",\n "category",\n "unix_millis_created_time"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /beacons\n\n\n```\n{\n "title": "BeaconState",\n "type": "object",\n "properties": {\n "id": {\n "title": "Id",\n "maxLength": 255,\n "type": "string"\n },\n "online": {\n "title": "Online",\n "type": "boolean"\n },\n "category": {\n "title": "Category",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "activated": {\n "title": "Activated",\n "type": "boolean"\n },\n "level": {\n "title": "Level",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n }\n },\n "required": [\n "id",\n "online",\n "activated"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /building_map\n\n\n```\n{\n "title": "BuildingMap",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "levels": {\n "title": "Levels",\n "type": "array",\n "items": {\n "$ref": "#/definitions/Level"\n }\n },\n "lifts": {\n "title": "Lifts",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Lift"\n }\n }\n },\n "required": [\n "name",\n "levels",\n "lifts"\n ],\n "definitions": {\n "AffineImage": {\n "title": "AffineImage",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "x_offset": {\n "title": "X Offset",\n "default": 0,\n "type": "number"\n },\n "y_offset": {\n "title": "Y Offset",\n "default": 0,\n "type": "number"\n },\n "yaw": {\n "title": "Yaw",\n "default": 0,\n "type": "number"\n },\n "scale": {\n "title": "Scale",\n "default": 0,\n "type": "number"\n },\n "encoding": {\n "title": "Encoding",\n "default": "",\n "type": "string"\n },\n "data": {\n "title": "Data",\n "type": "string"\n }\n },\n "required": [\n "name",\n "x_offset",\n "y_offset",\n "yaw",\n "scale",\n "encoding",\n "data"\n ]\n },\n "Place": {\n "title": "Place",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "x": {\n "title": "X",\n "default": 0,\n "type": "number"\n },\n "y": {\n "title": "Y",\n "default": 0,\n "type": "number"\n },\n "yaw": {\n "title": "Yaw",\n "default": 0,\n "type": "number"\n },\n "position_tolerance": {\n "title": "Position Tolerance",\n "default": 0,\n "type": "number"\n },\n "yaw_tolerance": {\n "title": "Yaw Tolerance",\n "default": 0,\n "type": "number"\n }\n },\n "required": [\n "name",\n "x",\n "y",\n "yaw",\n "position_tolerance",\n "yaw_tolerance"\n ]\n },\n "Door": {\n "title": "Door",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "v1_x": {\n "title": "V1 X",\n "default": 0,\n "type": "number"\n },\n "v1_y": {\n "title": "V1 Y",\n "default": 0,\n "type": "number"\n },\n "v2_x": {\n "title": "V2 X",\n "default": 0,\n "type": "number"\n },\n "v2_y": {\n "title": "V2 Y",\n "default": 0,\n "type": "number"\n },\n "door_type": {\n "title": "Door Type",\n "default": 0,\n "minimum": 0,\n "maximum": 255,\n "type": "integer"\n },\n "motion_range": {\n "title": "Motion Range",\n "default": 0,\n "type": "number"\n },\n "motion_direction": {\n "title": "Motion Direction",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n }\n },\n "required": [\n "name",\n "v1_x",\n "v1_y",\n "v2_x",\n "v2_y",\n "door_type",\n "motion_range",\n "motion_direction"\n ]\n },\n "Param": {\n "title": "Param",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "type": {\n "title": "Type",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n },\n "value_int": {\n "title": "Value Int",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "value_float": {\n "title": "Value Float",\n "default": 0,\n "type": "number"\n },\n "value_string": {\n "title": "Value String",\n "default": "",\n "type": "string"\n },\n "value_bool": {\n "title": "Value Bool",\n "default": false,\n "type": "boolean"\n }\n },\n "required": [\n "name",\n "type",\n "value_int",\n "value_float",\n "value_string",\n "value_bool"\n ]\n },\n "GraphNode": {\n "title": "GraphNode",\n "type": "object",\n "properties": {\n "x": {\n "title": "X",\n "default": 0,\n "type": "number"\n },\n "y": {\n "title": "Y",\n "default": 0,\n "type": "number"\n },\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "params": {\n "title": "Params",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Param"\n }\n }\n },\n "required": [\n "x",\n "y",\n "name",\n "params"\n ]\n },\n "GraphEdge": {\n "title": "GraphEdge",\n "type": "object",\n "properties": {\n "v1_idx": {\n "title": "V1 Idx",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n },\n "v2_idx": {\n "title": "V2 Idx",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n },\n "params": {\n "title": "Params",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Param"\n }\n },\n "edge_type": {\n "title": "Edge Type",\n "default": 0,\n "minimum": 0,\n "maximum": 255,\n "type": "integer"\n }\n },\n "required": [\n "v1_idx",\n "v2_idx",\n "params",\n "edge_type"\n ]\n },\n "Graph": {\n "title": "Graph",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "vertices": {\n "title": "Vertices",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/GraphNode"\n }\n },\n "edges": {\n "title": "Edges",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/GraphEdge"\n }\n },\n "params": {\n "title": "Params",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Param"\n }\n }\n },\n "required": [\n "name",\n "vertices",\n "edges",\n "params"\n ]\n },\n "Level": {\n "title": "Level",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "elevation": {\n "title": "Elevation",\n "default": 0,\n "type": "number"\n },\n "images": {\n "title": "Images",\n "type": "array",\n "items": {\n "$ref": "#/definitions/AffineImage"\n }\n },\n "places": {\n "title": "Places",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Place"\n }\n },\n "doors": {\n "title": "Doors",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Door"\n }\n },\n "nav_graphs": {\n "title": "Nav Graphs",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Graph"\n }\n },\n "wall_graph": {\n "title": "Wall Graph",\n "default": {\n "name": "",\n "vertices": [],\n "edges": [],\n "params": []\n },\n "allOf": [\n {\n "$ref": "#/definitions/Graph"\n }\n ]\n }\n },\n "required": [\n "name",\n "elevation",\n "images",\n "places",\n "doors",\n "nav_graphs",\n "wall_graph"\n ]\n },\n "Lift": {\n "title": "Lift",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "levels": {\n "title": "Levels",\n "default": [],\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "doors": {\n "title": "Doors",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Door"\n }\n },\n "wall_graph": {\n "title": "Wall Graph",\n "default": {\n "name": "",\n "vertices": [],\n "edges": [],\n "params": []\n },\n "allOf": [\n {\n "$ref": "#/definitions/Graph"\n }\n ]\n },\n "ref_x": {\n "title": "Ref X",\n "default": 0,\n "type": "number"\n },\n "ref_y": {\n "title": "Ref Y",\n "default": 0,\n "type": "number"\n },\n "ref_yaw": {\n "title": "Ref Yaw",\n "default": 0,\n "type": "number"\n },\n "width": {\n "title": "Width",\n "default": 0,\n "type": "number"\n },\n "depth": {\n "title": "Depth",\n "default": 0,\n "type": "number"\n }\n },\n "required": [\n "name",\n "levels",\n "doors",\n "wall_graph",\n "ref_x",\n "ref_y",\n "ref_yaw",\n "width",\n "depth"\n ]\n }\n }\n}\n```\n\n\n### /building_map/fire_alarm_trigger\n\n\n```\n{\n "title": "FireAlarmTriggerState",\n "type": "object",\n "properties": {\n "unix_millis_time": {\n "title": "Unix Millis Time",\n "type": "integer"\n },\n "trigger": {\n "title": "Trigger",\n "type": "boolean"\n }\n },\n "required": [\n "unix_millis_time",\n "trigger"\n ]\n}\n```\n\n\n### /delivery_alerts\n\n\n```\n{\n "title": "DeliveryAlert",\n "type": "object",\n "properties": {\n "id": {\n "title": "Id",\n "type": "string"\n },\n "category": {\n "$ref": "#/definitions/Category"\n },\n "tier": {\n "$ref": "#/definitions/Tier"\n },\n "action": {\n "$ref": "#/definitions/Action"\n },\n "task_id": {\n "title": "Task Id",\n "type": "string"\n },\n "message": {\n "title": "Message",\n "type": "string"\n }\n },\n "required": [\n "id",\n "category",\n "tier",\n "action",\n "task_id",\n "message"\n ],\n "definitions": {\n "Category": {\n "title": "Category",\n "description": "An enumeration.",\n "enum": [\n "missing",\n "wrong",\n "obstructed",\n "cancelled"\n ],\n "type": "string"\n },\n "Tier": {\n "title": "Tier",\n "description": "An enumeration.",\n "enum": [\n "warning",\n "error"\n ],\n "type": "string"\n },\n "Action": {\n "title": "Action",\n "description": "An enumeration.",\n "enum": [\n "waiting",\n "cancelled",\n "override",\n "resume"\n ],\n "type": "string"\n }\n }\n}\n```\n\n\n### /doors/{door_name}/state\n\n\n```\n{\n "title": "DoorState",\n "type": "object",\n "properties": {\n "door_time": {\n "title": "Door Time",\n "default": {\n "sec": 0,\n "nanosec": 0\n },\n "allOf": [\n {\n "$ref": "#/definitions/Time"\n }\n ]\n },\n "door_name": {\n "title": "Door Name",\n "default": "",\n "type": "string"\n },\n "current_mode": {\n "title": "Current Mode",\n "default": {\n "value": 0\n },\n "allOf": [\n {\n "$ref": "#/definitions/DoorMode"\n }\n ]\n }\n },\n "required": [\n "door_time",\n "door_name",\n "current_mode"\n ],\n "definitions": {\n "Time": {\n "title": "Time",\n "type": "object",\n "properties": {\n "sec": {\n "title": "Sec",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "nanosec": {\n "title": "Nanosec",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n }\n },\n "required": [\n "sec",\n "nanosec"\n ]\n },\n "DoorMode": {\n "title": "DoorMode",\n "type": "object",\n "properties": {\n "value": {\n "title": "Value",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n }\n },\n "required": [\n "value"\n ]\n }\n }\n}\n```\n\n\n### /doors/{door_name}/health\n\n\n```\n{\n "title": "DoorHealth",\n "type": "object",\n "properties": {\n "health_status": {\n "title": "Health Status",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "health_message": {\n "title": "Health Message",\n "nullable": true,\n "type": "string"\n },\n "id_": {\n "title": "Id ",\n "maxLength": 255,\n "type": "string"\n }\n },\n "required": [\n "health_status",\n "id_"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /lifts/{lift_name}/state\n\n\n```\n{\n "title": "LiftState",\n "type": "object",\n "properties": {\n "lift_time": {\n "title": "Lift Time",\n "default": {\n "sec": 0,\n "nanosec": 0\n },\n "allOf": [\n {\n "$ref": "#/definitions/Time"\n }\n ]\n },\n "lift_name": {\n "title": "Lift Name",\n "default": "",\n "type": "string"\n },\n "available_floors": {\n "title": "Available Floors",\n "default": [],\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "current_floor": {\n "title": "Current Floor",\n "default": "",\n "type": "string"\n },\n "destination_floor": {\n "title": "Destination Floor",\n "default": "",\n "type": "string"\n },\n "door_state": {\n "title": "Door State",\n "default": 0,\n "minimum": 0,\n "maximum": 255,\n "type": "integer"\n },\n "motion_state": {\n "title": "Motion State",\n "default": 0,\n "minimum": 0,\n "maximum": 255,\n "type": "integer"\n },\n "available_modes": {\n "title": "Available Modes",\n "type": "array",\n "items": {\n "type": "integer"\n }\n },\n "current_mode": {\n "title": "Current Mode",\n "default": 0,\n "minimum": 0,\n "maximum": 255,\n "type": "integer"\n },\n "session_id": {\n "title": "Session Id",\n "default": "",\n "type": "string"\n }\n },\n "required": [\n "lift_time",\n "lift_name",\n "available_floors",\n "current_floor",\n "destination_floor",\n "door_state",\n "motion_state",\n "available_modes",\n "current_mode",\n "session_id"\n ],\n "definitions": {\n "Time": {\n "title": "Time",\n "type": "object",\n "properties": {\n "sec": {\n "title": "Sec",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "nanosec": {\n "title": "Nanosec",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n }\n },\n "required": [\n "sec",\n "nanosec"\n ]\n }\n }\n}\n```\n\n\n### /lifts/{lift_name}/health\n\n\n```\n{\n "title": "LiftHealth",\n "type": "object",\n "properties": {\n "health_status": {\n "title": "Health Status",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "health_message": {\n "title": "Health Message",\n "nullable": true,\n "type": "string"\n },\n "id_": {\n "title": "Id ",\n "maxLength": 255,\n "type": "string"\n }\n },\n "required": [\n "health_status",\n "id_"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /tasks/{task_id}/state\n\n\n```\n{\n "title": "TaskState",\n "type": "object",\n "properties": {\n "booking": {\n "$ref": "#/definitions/Booking"\n },\n "category": {\n "$ref": "#/definitions/Category"\n },\n "detail": {\n "$ref": "#/definitions/Detail"\n },\n "unix_millis_start_time": {\n "title": "Unix Millis Start Time",\n "type": "integer"\n },\n "unix_millis_finish_time": {\n "title": "Unix Millis Finish Time",\n "type": "integer"\n },\n "original_estimate_millis": {\n "$ref": "#/definitions/EstimateMillis"\n },\n "estimate_millis": {\n "$ref": "#/definitions/EstimateMillis"\n },\n "assigned_to": {\n "title": "Assigned To",\n "description": "Which agent (robot) is the task assigned to",\n "allOf": [\n {\n "$ref": "#/definitions/AssignedTo"\n }\n ]\n },\n "status": {\n "$ref": "#/definitions/Status"\n },\n "dispatch": {\n "$ref": "#/definitions/Dispatch"\n },\n "phases": {\n "title": "Phases",\n "description": "A dictionary of the states of the phases of the task. The keys (property names) are phase IDs, which are integers.",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/Phase"\n }\n },\n "completed": {\n "title": "Completed",\n "description": "An array of the IDs of completed phases of this task",\n "type": "array",\n "items": {\n "$ref": "#/definitions/Id"\n }\n },\n "active": {\n "title": "Active",\n "description": "The ID of the active phase for this task",\n "allOf": [\n {\n "$ref": "#/definitions/Id"\n }\n ]\n },\n "pending": {\n "title": "Pending",\n "description": "An array of the pending phases of this task",\n "type": "array",\n "items": {\n "$ref": "#/definitions/Id"\n }\n },\n "interruptions": {\n "title": "Interruptions",\n "description": "A dictionary of interruptions that have been applied to this task. The keys (property names) are the unique token of the interruption request.",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/Interruption"\n }\n },\n "cancellation": {\n "title": "Cancellation",\n "description": "If the task was cancelled, this will describe information about the request.",\n "allOf": [\n {\n "$ref": "#/definitions/Cancellation"\n }\n ]\n },\n "killed": {\n "title": "Killed",\n "description": "If the task was killed, this will describe information about the request.",\n "allOf": [\n {\n "$ref": "#/definitions/Killed"\n }\n ]\n }\n },\n "required": [\n "booking"\n ],\n "definitions": {\n "Booking": {\n "title": "Booking",\n "type": "object",\n "properties": {\n "id": {\n "title": "Id",\n "description": "The unique identifier for this task",\n "type": "string"\n },\n "unix_millis_earliest_start_time": {\n "title": "Unix Millis Earliest Start Time",\n "type": "integer"\n },\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "type": "integer"\n },\n "priority": {\n "title": "Priority",\n "description": "Priority information about this task",\n "anyOf": [\n {\n "type": "object"\n },\n {\n "type": "string"\n }\n ]\n },\n "labels": {\n "title": "Labels",\n "description": "Information about how and why this task was booked",\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "requester": {\n "title": "Requester",\n "description": "(Optional) An identifier for the entity that requested this task",\n "type": "string"\n }\n },\n "required": [\n "id"\n ]\n },\n "Category": {\n "title": "Category",\n "description": "The category of this task or phase",\n "type": "string"\n },\n "Detail": {\n "title": "Detail",\n "description": "Detailed information about a task, phase, or event",\n "anyOf": [\n {\n "type": "object"\n },\n {\n "type": "array",\n "items": {}\n },\n {\n "type": "string"\n }\n ]\n },\n "EstimateMillis": {\n "title": "EstimateMillis",\n "description": "An estimate, in milliseconds, of how long the subject will take to complete",\n "minimum": 0,\n "type": "integer"\n },\n "AssignedTo": {\n "title": "AssignedTo",\n "type": "object",\n "properties": {\n "group": {\n "title": "Group",\n "type": "string"\n },\n "name": {\n "title": "Name",\n "type": "string"\n }\n },\n "required": [\n "group",\n "name"\n ]\n },\n "Status": {\n "title": "Status",\n "description": "An enumeration.",\n "enum": [\n "uninitialized",\n "blocked",\n "error",\n "failed",\n "queued",\n "standby",\n "underway",\n "delayed",\n "skipped",\n "canceled",\n "killed",\n "completed"\n ]\n },\n "Status1": {\n "title": "Status1",\n "description": "An enumeration.",\n "enum": [\n "queued",\n "selected",\n "dispatched",\n "failed_to_assign",\n "canceled_in_flight"\n ]\n },\n "Assignment": {\n "title": "Assignment",\n "type": "object",\n "properties": {\n "fleet_name": {\n "title": "Fleet Name",\n "type": "string"\n },\n "expected_robot_name": {\n "title": "Expected Robot Name",\n "type": "string"\n }\n }\n },\n "Error": {\n "title": "Error",\n "type": "object",\n "properties": {\n "code": {\n "title": "Code",\n "description": "A standard code for the kind of error that has occurred",\n "minimum": 0,\n "type": "integer"\n },\n "category": {\n "title": "Category",\n "description": "The category of the error",\n "type": "string"\n },\n "detail": {\n "title": "Detail",\n "description": "Details about the error",\n "type": "string"\n }\n }\n },\n "Dispatch": {\n "title": "Dispatch",\n "type": "object",\n "properties": {\n "status": {\n "$ref": "#/definitions/Status1"\n },\n "assignment": {\n "$ref": "#/definitions/Assignment"\n },\n "errors": {\n "title": "Errors",\n "type": "array",\n "items": {\n "$ref": "#/definitions/Error"\n }\n }\n },\n "required": [\n "status"\n ]\n },\n "Id": {\n "title": "Id",\n "minimum": 0,\n "type": "integer"\n },\n "EventState": {\n "title": "EventState",\n "type": "object",\n "properties": {\n "id": {\n "$ref": "#/definitions/Id"\n },\n "status": {\n "$ref": "#/definitions/Status"\n },\n "name": {\n "title": "Name",\n "description": "The brief name of the event",\n "type": "string"\n },\n "detail": {\n "title": "Detail",\n "description": "Detailed information about the event",\n "allOf": [\n {\n "$ref": "#/definitions/Detail"\n }\n ]\n },\n "deps": {\n "title": "Deps",\n "description": "This event may depend on other events. This array contains the IDs of those other event dependencies.",\n "type": "array",\n "items": {\n "type": "integer",\n "minimum": 0\n }\n }\n },\n "required": [\n "id"\n ]\n },\n "Undo": {\n "title": "Undo",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the undo skip request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the undo skip request",\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n },\n "required": [\n "unix_millis_request_time",\n "labels"\n ]\n },\n "SkipPhaseRequest": {\n "title": "SkipPhaseRequest",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the skip request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the purpose of the skip request",\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "undo": {\n "title": "Undo",\n "description": "Information about an undo skip request that applied to this request",\n "allOf": [\n {\n "$ref": "#/definitions/Undo"\n }\n ]\n }\n },\n "required": [\n "unix_millis_request_time",\n "labels"\n ]\n },\n "Phase": {\n "title": "Phase",\n "type": "object",\n "properties": {\n "id": {\n "$ref": "#/definitions/Id"\n },\n "category": {\n "$ref": "#/definitions/Category"\n },\n "detail": {\n "$ref": "#/definitions/Detail"\n },\n "unix_millis_start_time": {\n "title": "Unix Millis Start Time",\n "type": "integer"\n },\n "unix_millis_finish_time": {\n "title": "Unix Millis Finish Time",\n "type": "integer"\n },\n "original_estimate_millis": {\n "$ref": "#/definitions/EstimateMillis"\n },\n "estimate_millis": {\n "$ref": "#/definitions/EstimateMillis"\n },\n "final_event_id": {\n "$ref": "#/definitions/Id"\n },\n "events": {\n "title": "Events",\n "description": "A dictionary of events for this phase. The keys (property names) are the event IDs, which are integers.",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/EventState"\n }\n },\n "skip_requests": {\n "title": "Skip Requests",\n "description": "Information about any skip requests that have been received",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/SkipPhaseRequest"\n }\n }\n },\n "required": [\n "id"\n ]\n },\n "ResumedBy": {\n "title": "ResumedBy",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the resume request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the resume request",\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n },\n "required": [\n "labels"\n ]\n },\n "Interruption": {\n "title": "Interruption",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the interruption request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the purpose of the interruption",\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "resumed_by": {\n "title": "Resumed By",\n "description": "Information about the resume request that ended this interruption. This field will be missing if the interruption is still active.",\n "allOf": [\n {\n "$ref": "#/definitions/ResumedBy"\n }\n ]\n }\n },\n "required": [\n "unix_millis_request_time",\n "labels"\n ]\n },\n "Cancellation": {\n "title": "Cancellation",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the cancellation request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the cancel request",\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n },\n "required": [\n "unix_millis_request_time",\n "labels"\n ]\n },\n "Killed": {\n "title": "Killed",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the cancellation request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the kill request",\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n },\n "required": [\n "unix_millis_request_time",\n "labels"\n ]\n }\n }\n}\n```\n\n\n### /tasks/{task_id}/log\n\n\n```\n{\n "title": "TaskEventLog",\n "type": "object",\n "properties": {\n "task_id": {\n "title": "Task Id",\n "type": "string"\n },\n "log": {\n "title": "Log",\n "description": "Log entries related to the overall task",\n "type": "array",\n "items": {\n "$ref": "#/definitions/LogEntry"\n }\n },\n "phases": {\n "title": "Phases",\n "description": "A dictionary whose keys (property names) are the indices of a phase",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/Phases"\n }\n }\n },\n "required": [\n "task_id"\n ],\n "additionalProperties": false,\n "definitions": {\n "Tier": {\n "title": "Tier",\n "description": "An enumeration.",\n "enum": [\n "uninitialized",\n "info",\n "warning",\n "error"\n ]\n },\n "LogEntry": {\n "title": "LogEntry",\n "type": "object",\n "properties": {\n "seq": {\n "title": "Seq",\n "description": "Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.",\n "exclusiveMaximum": 4294967296,\n "minimum": 0,\n "type": "integer"\n },\n "tier": {\n "description": "The importance level of the log entry",\n "allOf": [\n {\n "$ref": "#/definitions/Tier"\n }\n ]\n },\n "unix_millis_time": {\n "title": "Unix Millis Time",\n "type": "integer"\n },\n "text": {\n "title": "Text",\n "description": "The text of the log entry",\n "type": "string"\n }\n },\n "required": [\n "seq",\n "tier",\n "unix_millis_time",\n "text"\n ]\n },\n "Phases": {\n "title": "Phases",\n "type": "object",\n "properties": {\n "log": {\n "title": "Log",\n "description": "Log entries related to the overall phase",\n "type": "array",\n "items": {\n "$ref": "#/definitions/LogEntry"\n }\n },\n "events": {\n "title": "Events",\n "description": "A dictionary whose keys (property names) are the indices of an event in the phase",\n "type": "object",\n "additionalProperties": {\n "type": "array",\n "items": {\n "$ref": "#/definitions/LogEntry"\n }\n }\n }\n },\n "additionalProperties": false\n }\n }\n}\n```\n\n\n### /dispensers/{guid}/state\n\n\n```\n{\n "title": "DispenserState",\n "type": "object",\n "properties": {\n "time": {\n "title": "Time",\n "default": {\n "sec": 0,\n "nanosec": 0\n },\n "allOf": [\n {\n "$ref": "#/definitions/Time"\n }\n ]\n },\n "guid": {\n "title": "Guid",\n "default": "",\n "type": "string"\n },\n "mode": {\n "title": "Mode",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "request_guid_queue": {\n "title": "Request Guid Queue",\n "default": [],\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "seconds_remaining": {\n "title": "Seconds Remaining",\n "default": 0,\n "type": "number"\n }\n },\n "required": [\n "time",\n "guid",\n "mode",\n "request_guid_queue",\n "seconds_remaining"\n ],\n "definitions": {\n "Time": {\n "title": "Time",\n "type": "object",\n "properties": {\n "sec": {\n "title": "Sec",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "nanosec": {\n "title": "Nanosec",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n }\n },\n "required": [\n "sec",\n "nanosec"\n ]\n }\n }\n}\n```\n\n\n### /dispensers/{guid}/health\n\n\n```\n{\n "title": "DispenserHealth",\n "type": "object",\n "properties": {\n "health_status": {\n "title": "Health Status",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "health_message": {\n "title": "Health Message",\n "nullable": true,\n "type": "string"\n },\n "id_": {\n "title": "Id ",\n "maxLength": 255,\n "type": "string"\n }\n },\n "required": [\n "health_status",\n "id_"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /ingestors/{guid}/state\n\n\n```\n{\n "title": "IngestorState",\n "type": "object",\n "properties": {\n "time": {\n "title": "Time",\n "default": {\n "sec": 0,\n "nanosec": 0\n },\n "allOf": [\n {\n "$ref": "#/definitions/Time"\n }\n ]\n },\n "guid": {\n "title": "Guid",\n "default": "",\n "type": "string"\n },\n "mode": {\n "title": "Mode",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "request_guid_queue": {\n "title": "Request Guid Queue",\n "default": [],\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "seconds_remaining": {\n "title": "Seconds Remaining",\n "default": 0,\n "type": "number"\n }\n },\n "required": [\n "time",\n "guid",\n "mode",\n "request_guid_queue",\n "seconds_remaining"\n ],\n "definitions": {\n "Time": {\n "title": "Time",\n "type": "object",\n "properties": {\n "sec": {\n "title": "Sec",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "nanosec": {\n "title": "Nanosec",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n }\n },\n "required": [\n "sec",\n "nanosec"\n ]\n }\n }\n}\n```\n\n\n### /ingestors/{guid}/health\n\n\n```\n{\n "title": "IngestorHealth",\n "type": "object",\n "properties": {\n "health_status": {\n "title": "Health Status",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "health_message": {\n "title": "Health Message",\n "nullable": true,\n "type": "string"\n },\n "id_": {\n "title": "Id ",\n "maxLength": 255,\n "type": "string"\n }\n },\n "required": [\n "health_status",\n "id_"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /fleets/{name}/state\n\n\n```\n{\n "title": "FleetState",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "type": "string"\n },\n "robots": {\n "title": "Robots",\n "description": "A dictionary of the states of the robots that belong to this fleet",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/RobotState"\n }\n }\n },\n "definitions": {\n "Status": {\n "title": "Status",\n "description": "An enumeration.",\n "enum": [\n "uninitialized",\n "offline",\n "shutdown",\n "idle",\n "charging",\n "working",\n "error"\n ]\n },\n "Location2D": {\n "title": "Location2D",\n "type": "object",\n "properties": {\n "map": {\n "title": "Map",\n "type": "string"\n },\n "x": {\n "title": "X",\n "type": "number"\n },\n "y": {\n "title": "Y",\n "type": "number"\n },\n "yaw": {\n "title": "Yaw",\n "type": "number"\n }\n },\n "required": [\n "map",\n "x",\n "y",\n "yaw"\n ]\n },\n "Issue": {\n "title": "Issue",\n "type": "object",\n "properties": {\n "category": {\n "title": "Category",\n "description": "Category of the robot\'s issue",\n "type": "string"\n },\n "detail": {\n "title": "Detail",\n "description": "Detailed information about the issue",\n "anyOf": [\n {\n "type": "object"\n },\n {\n "type": "array",\n "items": {}\n },\n {\n "type": "string"\n }\n ]\n }\n }\n },\n "Commission": {\n "title": "Commission",\n "type": "object",\n "properties": {\n "dispatch_tasks": {\n "title": "Dispatch Tasks",\n "description": "Should the robot accept dispatched tasks, true/false. When used in a request, leave this unset to not change the robot\'s current value.",\n "type": "boolean"\n },\n "direct_tasks": {\n "title": "Direct Tasks",\n "description": "Should the robot accept direct task requests, true/false. When used in a request, leave this unset to not change the robot\'s current value.",\n "type": "boolean"\n },\n "idle_behavior": {\n "title": "Idle Behavior",\n "description": "Should the robot perform its idle behavior, true/false. When used in a request, leave this unset to not change the robot\'s current value.",\n "type": "boolean"\n }\n }\n },\n "MutexGroups": {\n "title": "MutexGroups",\n "type": "object",\n "properties": {\n "locked": {\n "title": "Locked",\n "description": "A list of mutex groups that this robot has currently locked",\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "requesting": {\n "title": "Requesting",\n "description": "A list of the mutex groups that this robot is currently requesting but has not lockd yet",\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n }\n },\n "RobotState": {\n "title": "RobotState",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "type": "string"\n },\n "status": {\n "description": "A simple token representing the status of the robot",\n "allOf": [\n {\n "$ref": "#/definitions/Status"\n }\n ]\n },\n "task_id": {\n "title": "Task Id",\n "description": "The ID of the task this robot is currently working on. Empty string if the robot is not working on a task.",\n "type": "string"\n },\n "unix_millis_time": {\n "title": "Unix Millis Time",\n "type": "integer"\n },\n "location": {\n "$ref": "#/definitions/Location2D"\n },\n "battery": {\n "title": "Battery",\n "description": "State of charge of the battery. Values range from 0.0 (depleted) to 1.0 (fully charged)",\n "minimum": 0.0,\n "maximum": 1.0,\n "type": "number"\n },\n "issues": {\n "title": "Issues",\n "description": "A list of issues with the robot that operators need to address",\n "type": "array",\n "items": {\n "$ref": "#/definitions/Issue"\n }\n },\n "commission": {\n "$ref": "#/definitions/Commission"\n },\n "mutex_groups": {\n "title": "Mutex Groups",\n "description": "Information about the mutex groups that this robot is interacting with",\n "allOf": [\n {\n "$ref": "#/definitions/MutexGroups"\n }\n ]\n }\n }\n }\n }\n}\n```\n\n\n### /fleets/{name}/log\n\n\n```\n{\n "title": "FleetLog",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "type": "string"\n },\n "log": {\n "title": "Log",\n "description": "Log for the overall fleet",\n "type": "array",\n "items": {\n "$ref": "#/definitions/LogEntry"\n }\n },\n "robots": {\n "title": "Robots",\n "description": "Dictionary of logs for the individual robots. The keys (property names) are the robot names.",\n "type": "object",\n "additionalProperties": {\n "type": "array",\n "items": {\n "$ref": "#/definitions/LogEntry"\n }\n }\n }\n },\n "definitions": {\n "Tier": {\n "title": "Tier",\n "description": "An enumeration.",\n "enum": [\n "uninitialized",\n "info",\n "warning",\n "error"\n ]\n },\n "LogEntry": {\n "title": "LogEntry",\n "type": "object",\n "properties": {\n "seq": {\n "title": "Seq",\n "description": "Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.",\n "exclusiveMaximum": 4294967296,\n "minimum": 0,\n "type": "integer"\n },\n "tier": {\n "description": "The importance level of the log entry",\n "allOf": [\n {\n "$ref": "#/definitions/Tier"\n }\n ]\n },\n "unix_millis_time": {\n "title": "Unix Millis Time",\n "type": "integer"\n },\n "text": {\n "title": "Text",\n "description": "The text of the log entry",\n "type": "string"\n }\n },\n "required": [\n "seq",\n "tier",\n "unix_millis_time",\n "text"\n ]\n }\n }\n}\n```\n\n', + '\n# NOTE: This endpoint is here for documentation purposes only, this is _not_ a REST endpoint.\n\n## About\nThis exposes a minimal pubsub system built on top of socket.io.\nIt works similar to a normal socket.io endpoint, except that are 2 special\nrooms which control subscriptions.\n\n## Rooms\n### subscribe\nClients must send a message to this room to start receiving messages on other rooms.\nThe message must be of the form:\n\n```\n{\n "room": ""\n}\n```\n\n### unsubscribe\nClients can send a message to this room to stop receiving messages on other rooms.\nThe message must be of the form:\n\n```\n{\n "room": ""\n}\n```\n \n### /alerts/requests\n\n\n```\n{\n "title": "AlertRequest",\n "type": "object",\n "properties": {\n "id": {\n "title": "Id",\n "type": "string"\n },\n "unix_millis_alert_time": {\n "title": "Unix Millis Alert Time",\n "type": "integer"\n },\n "title": {\n "title": "Title",\n "type": "string"\n },\n "subtitle": {\n "title": "Subtitle",\n "type": "string"\n },\n "message": {\n "title": "Message",\n "type": "string"\n },\n "display": {\n "title": "Display",\n "type": "boolean"\n },\n "tier": {\n "$ref": "#/definitions/Tier"\n },\n "responses_available": {\n "title": "Responses Available",\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "alert_parameters": {\n "title": "Alert Parameters",\n "type": "array",\n "items": {\n "$ref": "#/definitions/AlertParameter"\n }\n },\n "task_id": {\n "title": "Task Id",\n "type": "string"\n }\n },\n "required": [\n "id",\n "unix_millis_alert_time",\n "title",\n "subtitle",\n "message",\n "display",\n "tier",\n "responses_available",\n "alert_parameters"\n ],\n "definitions": {\n "Tier": {\n "title": "Tier",\n "description": "An enumeration.",\n "enum": [\n "info",\n "warning",\n "error"\n ],\n "type": "string"\n },\n "AlertParameter": {\n "title": "AlertParameter",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "type": "string"\n },\n "value": {\n "title": "Value",\n "type": "string"\n }\n },\n "required": [\n "name",\n "value"\n ]\n }\n }\n}\n```\n\n\n### /alerts/responses\n\n\n```\n{\n "title": "AlertResponse",\n "type": "object",\n "properties": {\n "id": {\n "title": "Id",\n "type": "string"\n },\n "unix_millis_response_time": {\n "title": "Unix Millis Response Time",\n "type": "integer"\n },\n "response": {\n "title": "Response",\n "type": "string"\n }\n },\n "required": [\n "id",\n "unix_millis_response_time",\n "response"\n ]\n}\n```\n\n\n### /beacons\n\n\n```\n{\n "title": "BeaconState",\n "type": "object",\n "properties": {\n "id": {\n "title": "Id",\n "maxLength": 255,\n "type": "string"\n },\n "online": {\n "title": "Online",\n "type": "boolean"\n },\n "category": {\n "title": "Category",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "activated": {\n "title": "Activated",\n "type": "boolean"\n },\n "level": {\n "title": "Level",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n }\n },\n "required": [\n "id",\n "online",\n "activated"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /building_map\n\n\n```\n{\n "title": "BuildingMap",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "levels": {\n "title": "Levels",\n "type": "array",\n "items": {\n "$ref": "#/definitions/Level"\n }\n },\n "lifts": {\n "title": "Lifts",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Lift"\n }\n }\n },\n "required": [\n "name",\n "levels",\n "lifts"\n ],\n "definitions": {\n "AffineImage": {\n "title": "AffineImage",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "x_offset": {\n "title": "X Offset",\n "default": 0,\n "type": "number"\n },\n "y_offset": {\n "title": "Y Offset",\n "default": 0,\n "type": "number"\n },\n "yaw": {\n "title": "Yaw",\n "default": 0,\n "type": "number"\n },\n "scale": {\n "title": "Scale",\n "default": 0,\n "type": "number"\n },\n "encoding": {\n "title": "Encoding",\n "default": "",\n "type": "string"\n },\n "data": {\n "title": "Data",\n "type": "string"\n }\n },\n "required": [\n "name",\n "x_offset",\n "y_offset",\n "yaw",\n "scale",\n "encoding",\n "data"\n ]\n },\n "Place": {\n "title": "Place",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "x": {\n "title": "X",\n "default": 0,\n "type": "number"\n },\n "y": {\n "title": "Y",\n "default": 0,\n "type": "number"\n },\n "yaw": {\n "title": "Yaw",\n "default": 0,\n "type": "number"\n },\n "position_tolerance": {\n "title": "Position Tolerance",\n "default": 0,\n "type": "number"\n },\n "yaw_tolerance": {\n "title": "Yaw Tolerance",\n "default": 0,\n "type": "number"\n }\n },\n "required": [\n "name",\n "x",\n "y",\n "yaw",\n "position_tolerance",\n "yaw_tolerance"\n ]\n },\n "Door": {\n "title": "Door",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "v1_x": {\n "title": "V1 X",\n "default": 0,\n "type": "number"\n },\n "v1_y": {\n "title": "V1 Y",\n "default": 0,\n "type": "number"\n },\n "v2_x": {\n "title": "V2 X",\n "default": 0,\n "type": "number"\n },\n "v2_y": {\n "title": "V2 Y",\n "default": 0,\n "type": "number"\n },\n "door_type": {\n "title": "Door Type",\n "default": 0,\n "minimum": 0,\n "maximum": 255,\n "type": "integer"\n },\n "motion_range": {\n "title": "Motion Range",\n "default": 0,\n "type": "number"\n },\n "motion_direction": {\n "title": "Motion Direction",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n }\n },\n "required": [\n "name",\n "v1_x",\n "v1_y",\n "v2_x",\n "v2_y",\n "door_type",\n "motion_range",\n "motion_direction"\n ]\n },\n "Param": {\n "title": "Param",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "type": {\n "title": "Type",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n },\n "value_int": {\n "title": "Value Int",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "value_float": {\n "title": "Value Float",\n "default": 0,\n "type": "number"\n },\n "value_string": {\n "title": "Value String",\n "default": "",\n "type": "string"\n },\n "value_bool": {\n "title": "Value Bool",\n "default": false,\n "type": "boolean"\n }\n },\n "required": [\n "name",\n "type",\n "value_int",\n "value_float",\n "value_string",\n "value_bool"\n ]\n },\n "GraphNode": {\n "title": "GraphNode",\n "type": "object",\n "properties": {\n "x": {\n "title": "X",\n "default": 0,\n "type": "number"\n },\n "y": {\n "title": "Y",\n "default": 0,\n "type": "number"\n },\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "params": {\n "title": "Params",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Param"\n }\n }\n },\n "required": [\n "x",\n "y",\n "name",\n "params"\n ]\n },\n "GraphEdge": {\n "title": "GraphEdge",\n "type": "object",\n "properties": {\n "v1_idx": {\n "title": "V1 Idx",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n },\n "v2_idx": {\n "title": "V2 Idx",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n },\n "params": {\n "title": "Params",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Param"\n }\n },\n "edge_type": {\n "title": "Edge Type",\n "default": 0,\n "minimum": 0,\n "maximum": 255,\n "type": "integer"\n }\n },\n "required": [\n "v1_idx",\n "v2_idx",\n "params",\n "edge_type"\n ]\n },\n "Graph": {\n "title": "Graph",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "vertices": {\n "title": "Vertices",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/GraphNode"\n }\n },\n "edges": {\n "title": "Edges",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/GraphEdge"\n }\n },\n "params": {\n "title": "Params",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Param"\n }\n }\n },\n "required": [\n "name",\n "vertices",\n "edges",\n "params"\n ]\n },\n "Level": {\n "title": "Level",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "elevation": {\n "title": "Elevation",\n "default": 0,\n "type": "number"\n },\n "images": {\n "title": "Images",\n "type": "array",\n "items": {\n "$ref": "#/definitions/AffineImage"\n }\n },\n "places": {\n "title": "Places",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Place"\n }\n },\n "doors": {\n "title": "Doors",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Door"\n }\n },\n "nav_graphs": {\n "title": "Nav Graphs",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Graph"\n }\n },\n "wall_graph": {\n "title": "Wall Graph",\n "default": {\n "name": "",\n "vertices": [],\n "edges": [],\n "params": []\n },\n "allOf": [\n {\n "$ref": "#/definitions/Graph"\n }\n ]\n }\n },\n "required": [\n "name",\n "elevation",\n "images",\n "places",\n "doors",\n "nav_graphs",\n "wall_graph"\n ]\n },\n "Lift": {\n "title": "Lift",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "default": "",\n "type": "string"\n },\n "levels": {\n "title": "Levels",\n "default": [],\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "doors": {\n "title": "Doors",\n "default": [],\n "type": "array",\n "items": {\n "$ref": "#/definitions/Door"\n }\n },\n "wall_graph": {\n "title": "Wall Graph",\n "default": {\n "name": "",\n "vertices": [],\n "edges": [],\n "params": []\n },\n "allOf": [\n {\n "$ref": "#/definitions/Graph"\n }\n ]\n },\n "ref_x": {\n "title": "Ref X",\n "default": 0,\n "type": "number"\n },\n "ref_y": {\n "title": "Ref Y",\n "default": 0,\n "type": "number"\n },\n "ref_yaw": {\n "title": "Ref Yaw",\n "default": 0,\n "type": "number"\n },\n "width": {\n "title": "Width",\n "default": 0,\n "type": "number"\n },\n "depth": {\n "title": "Depth",\n "default": 0,\n "type": "number"\n }\n },\n "required": [\n "name",\n "levels",\n "doors",\n "wall_graph",\n "ref_x",\n "ref_y",\n "ref_yaw",\n "width",\n "depth"\n ]\n }\n }\n}\n```\n\n\n### /building_map/fire_alarm_trigger\n\n\n```\n{\n "title": "FireAlarmTriggerState",\n "type": "object",\n "properties": {\n "unix_millis_time": {\n "title": "Unix Millis Time",\n "type": "integer"\n },\n "trigger": {\n "title": "Trigger",\n "type": "boolean"\n }\n },\n "required": [\n "unix_millis_time",\n "trigger"\n ]\n}\n```\n\n\n### /delivery_alerts\n\n\n```\n{\n "title": "DeliveryAlert",\n "type": "object",\n "properties": {\n "id": {\n "title": "Id",\n "type": "string"\n },\n "category": {\n "$ref": "#/definitions/Category"\n },\n "tier": {\n "$ref": "#/definitions/Tier"\n },\n "action": {\n "$ref": "#/definitions/Action"\n },\n "task_id": {\n "title": "Task Id",\n "type": "string"\n },\n "message": {\n "title": "Message",\n "type": "string"\n }\n },\n "required": [\n "id",\n "category",\n "tier",\n "action",\n "task_id",\n "message"\n ],\n "definitions": {\n "Category": {\n "title": "Category",\n "description": "An enumeration.",\n "enum": [\n "missing",\n "wrong",\n "obstructed",\n "cancelled"\n ],\n "type": "string"\n },\n "Tier": {\n "title": "Tier",\n "description": "An enumeration.",\n "enum": [\n "warning",\n "error"\n ],\n "type": "string"\n },\n "Action": {\n "title": "Action",\n "description": "An enumeration.",\n "enum": [\n "waiting",\n "cancelled",\n "override",\n "resume"\n ],\n "type": "string"\n }\n }\n}\n```\n\n\n### /doors/{door_name}/state\n\n\n```\n{\n "title": "DoorState",\n "type": "object",\n "properties": {\n "door_time": {\n "title": "Door Time",\n "default": {\n "sec": 0,\n "nanosec": 0\n },\n "allOf": [\n {\n "$ref": "#/definitions/Time"\n }\n ]\n },\n "door_name": {\n "title": "Door Name",\n "default": "",\n "type": "string"\n },\n "current_mode": {\n "title": "Current Mode",\n "default": {\n "value": 0\n },\n "allOf": [\n {\n "$ref": "#/definitions/DoorMode"\n }\n ]\n }\n },\n "required": [\n "door_time",\n "door_name",\n "current_mode"\n ],\n "definitions": {\n "Time": {\n "title": "Time",\n "type": "object",\n "properties": {\n "sec": {\n "title": "Sec",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "nanosec": {\n "title": "Nanosec",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n }\n },\n "required": [\n "sec",\n "nanosec"\n ]\n },\n "DoorMode": {\n "title": "DoorMode",\n "type": "object",\n "properties": {\n "value": {\n "title": "Value",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n }\n },\n "required": [\n "value"\n ]\n }\n }\n}\n```\n\n\n### /doors/{door_name}/health\n\n\n```\n{\n "title": "DoorHealth",\n "type": "object",\n "properties": {\n "health_status": {\n "title": "Health Status",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "health_message": {\n "title": "Health Message",\n "nullable": true,\n "type": "string"\n },\n "id_": {\n "title": "Id ",\n "maxLength": 255,\n "type": "string"\n }\n },\n "required": [\n "health_status",\n "id_"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /lifts/{lift_name}/state\n\n\n```\n{\n "title": "LiftState",\n "type": "object",\n "properties": {\n "lift_time": {\n "title": "Lift Time",\n "default": {\n "sec": 0,\n "nanosec": 0\n },\n "allOf": [\n {\n "$ref": "#/definitions/Time"\n }\n ]\n },\n "lift_name": {\n "title": "Lift Name",\n "default": "",\n "type": "string"\n },\n "available_floors": {\n "title": "Available Floors",\n "default": [],\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "current_floor": {\n "title": "Current Floor",\n "default": "",\n "type": "string"\n },\n "destination_floor": {\n "title": "Destination Floor",\n "default": "",\n "type": "string"\n },\n "door_state": {\n "title": "Door State",\n "default": 0,\n "minimum": 0,\n "maximum": 255,\n "type": "integer"\n },\n "motion_state": {\n "title": "Motion State",\n "default": 0,\n "minimum": 0,\n "maximum": 255,\n "type": "integer"\n },\n "available_modes": {\n "title": "Available Modes",\n "type": "array",\n "items": {\n "type": "integer"\n }\n },\n "current_mode": {\n "title": "Current Mode",\n "default": 0,\n "minimum": 0,\n "maximum": 255,\n "type": "integer"\n },\n "session_id": {\n "title": "Session Id",\n "default": "",\n "type": "string"\n }\n },\n "required": [\n "lift_time",\n "lift_name",\n "available_floors",\n "current_floor",\n "destination_floor",\n "door_state",\n "motion_state",\n "available_modes",\n "current_mode",\n "session_id"\n ],\n "definitions": {\n "Time": {\n "title": "Time",\n "type": "object",\n "properties": {\n "sec": {\n "title": "Sec",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "nanosec": {\n "title": "Nanosec",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n }\n },\n "required": [\n "sec",\n "nanosec"\n ]\n }\n }\n}\n```\n\n\n### /lifts/{lift_name}/health\n\n\n```\n{\n "title": "LiftHealth",\n "type": "object",\n "properties": {\n "health_status": {\n "title": "Health Status",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "health_message": {\n "title": "Health Message",\n "nullable": true,\n "type": "string"\n },\n "id_": {\n "title": "Id ",\n "maxLength": 255,\n "type": "string"\n }\n },\n "required": [\n "health_status",\n "id_"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /tasks/{task_id}/state\n\n\n```\n{\n "title": "TaskState",\n "type": "object",\n "properties": {\n "booking": {\n "$ref": "#/definitions/Booking"\n },\n "category": {\n "$ref": "#/definitions/Category"\n },\n "detail": {\n "$ref": "#/definitions/Detail"\n },\n "unix_millis_start_time": {\n "title": "Unix Millis Start Time",\n "type": "integer"\n },\n "unix_millis_finish_time": {\n "title": "Unix Millis Finish Time",\n "type": "integer"\n },\n "original_estimate_millis": {\n "$ref": "#/definitions/EstimateMillis"\n },\n "estimate_millis": {\n "$ref": "#/definitions/EstimateMillis"\n },\n "assigned_to": {\n "title": "Assigned To",\n "description": "Which agent (robot) is the task assigned to",\n "allOf": [\n {\n "$ref": "#/definitions/AssignedTo"\n }\n ]\n },\n "status": {\n "$ref": "#/definitions/Status"\n },\n "dispatch": {\n "$ref": "#/definitions/Dispatch"\n },\n "phases": {\n "title": "Phases",\n "description": "A dictionary of the states of the phases of the task. The keys (property names) are phase IDs, which are integers.",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/Phase"\n }\n },\n "completed": {\n "title": "Completed",\n "description": "An array of the IDs of completed phases of this task",\n "type": "array",\n "items": {\n "$ref": "#/definitions/Id"\n }\n },\n "active": {\n "title": "Active",\n "description": "The ID of the active phase for this task",\n "allOf": [\n {\n "$ref": "#/definitions/Id"\n }\n ]\n },\n "pending": {\n "title": "Pending",\n "description": "An array of the pending phases of this task",\n "type": "array",\n "items": {\n "$ref": "#/definitions/Id"\n }\n },\n "interruptions": {\n "title": "Interruptions",\n "description": "A dictionary of interruptions that have been applied to this task. The keys (property names) are the unique token of the interruption request.",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/Interruption"\n }\n },\n "cancellation": {\n "title": "Cancellation",\n "description": "If the task was cancelled, this will describe information about the request.",\n "allOf": [\n {\n "$ref": "#/definitions/Cancellation"\n }\n ]\n },\n "killed": {\n "title": "Killed",\n "description": "If the task was killed, this will describe information about the request.",\n "allOf": [\n {\n "$ref": "#/definitions/Killed"\n }\n ]\n }\n },\n "required": [\n "booking"\n ],\n "definitions": {\n "Booking": {\n "title": "Booking",\n "type": "object",\n "properties": {\n "id": {\n "title": "Id",\n "description": "The unique identifier for this task",\n "type": "string"\n },\n "unix_millis_earliest_start_time": {\n "title": "Unix Millis Earliest Start Time",\n "type": "integer"\n },\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "type": "integer"\n },\n "priority": {\n "title": "Priority",\n "description": "Priority information about this task",\n "anyOf": [\n {\n "type": "object"\n },\n {\n "type": "string"\n }\n ]\n },\n "labels": {\n "title": "Labels",\n "description": "Information about how and why this task was booked",\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "requester": {\n "title": "Requester",\n "description": "(Optional) An identifier for the entity that requested this task",\n "type": "string"\n }\n },\n "required": [\n "id"\n ]\n },\n "Category": {\n "title": "Category",\n "description": "The category of this task or phase",\n "type": "string"\n },\n "Detail": {\n "title": "Detail",\n "description": "Detailed information about a task, phase, or event",\n "anyOf": [\n {\n "type": "object"\n },\n {\n "type": "array",\n "items": {}\n },\n {\n "type": "string"\n }\n ]\n },\n "EstimateMillis": {\n "title": "EstimateMillis",\n "description": "An estimate, in milliseconds, of how long the subject will take to complete",\n "minimum": 0,\n "type": "integer"\n },\n "AssignedTo": {\n "title": "AssignedTo",\n "type": "object",\n "properties": {\n "group": {\n "title": "Group",\n "type": "string"\n },\n "name": {\n "title": "Name",\n "type": "string"\n }\n },\n "required": [\n "group",\n "name"\n ]\n },\n "Status": {\n "title": "Status",\n "description": "An enumeration.",\n "enum": [\n "uninitialized",\n "blocked",\n "error",\n "failed",\n "queued",\n "standby",\n "underway",\n "delayed",\n "skipped",\n "canceled",\n "killed",\n "completed"\n ]\n },\n "Status1": {\n "title": "Status1",\n "description": "An enumeration.",\n "enum": [\n "queued",\n "selected",\n "dispatched",\n "failed_to_assign",\n "canceled_in_flight"\n ]\n },\n "Assignment": {\n "title": "Assignment",\n "type": "object",\n "properties": {\n "fleet_name": {\n "title": "Fleet Name",\n "type": "string"\n },\n "expected_robot_name": {\n "title": "Expected Robot Name",\n "type": "string"\n }\n }\n },\n "Error": {\n "title": "Error",\n "type": "object",\n "properties": {\n "code": {\n "title": "Code",\n "description": "A standard code for the kind of error that has occurred",\n "minimum": 0,\n "type": "integer"\n },\n "category": {\n "title": "Category",\n "description": "The category of the error",\n "type": "string"\n },\n "detail": {\n "title": "Detail",\n "description": "Details about the error",\n "type": "string"\n }\n }\n },\n "Dispatch": {\n "title": "Dispatch",\n "type": "object",\n "properties": {\n "status": {\n "$ref": "#/definitions/Status1"\n },\n "assignment": {\n "$ref": "#/definitions/Assignment"\n },\n "errors": {\n "title": "Errors",\n "type": "array",\n "items": {\n "$ref": "#/definitions/Error"\n }\n }\n },\n "required": [\n "status"\n ]\n },\n "Id": {\n "title": "Id",\n "minimum": 0,\n "type": "integer"\n },\n "EventState": {\n "title": "EventState",\n "type": "object",\n "properties": {\n "id": {\n "$ref": "#/definitions/Id"\n },\n "status": {\n "$ref": "#/definitions/Status"\n },\n "name": {\n "title": "Name",\n "description": "The brief name of the event",\n "type": "string"\n },\n "detail": {\n "title": "Detail",\n "description": "Detailed information about the event",\n "allOf": [\n {\n "$ref": "#/definitions/Detail"\n }\n ]\n },\n "deps": {\n "title": "Deps",\n "description": "This event may depend on other events. This array contains the IDs of those other event dependencies.",\n "type": "array",\n "items": {\n "type": "integer",\n "minimum": 0\n }\n }\n },\n "required": [\n "id"\n ]\n },\n "Undo": {\n "title": "Undo",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the undo skip request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the undo skip request",\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n },\n "required": [\n "unix_millis_request_time",\n "labels"\n ]\n },\n "SkipPhaseRequest": {\n "title": "SkipPhaseRequest",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the skip request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the purpose of the skip request",\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "undo": {\n "title": "Undo",\n "description": "Information about an undo skip request that applied to this request",\n "allOf": [\n {\n "$ref": "#/definitions/Undo"\n }\n ]\n }\n },\n "required": [\n "unix_millis_request_time",\n "labels"\n ]\n },\n "Phase": {\n "title": "Phase",\n "type": "object",\n "properties": {\n "id": {\n "$ref": "#/definitions/Id"\n },\n "category": {\n "$ref": "#/definitions/Category"\n },\n "detail": {\n "$ref": "#/definitions/Detail"\n },\n "unix_millis_start_time": {\n "title": "Unix Millis Start Time",\n "type": "integer"\n },\n "unix_millis_finish_time": {\n "title": "Unix Millis Finish Time",\n "type": "integer"\n },\n "original_estimate_millis": {\n "$ref": "#/definitions/EstimateMillis"\n },\n "estimate_millis": {\n "$ref": "#/definitions/EstimateMillis"\n },\n "final_event_id": {\n "$ref": "#/definitions/Id"\n },\n "events": {\n "title": "Events",\n "description": "A dictionary of events for this phase. The keys (property names) are the event IDs, which are integers.",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/EventState"\n }\n },\n "skip_requests": {\n "title": "Skip Requests",\n "description": "Information about any skip requests that have been received",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/SkipPhaseRequest"\n }\n }\n },\n "required": [\n "id"\n ]\n },\n "ResumedBy": {\n "title": "ResumedBy",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the resume request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the resume request",\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n },\n "required": [\n "labels"\n ]\n },\n "Interruption": {\n "title": "Interruption",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the interruption request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the purpose of the interruption",\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "resumed_by": {\n "title": "Resumed By",\n "description": "Information about the resume request that ended this interruption. This field will be missing if the interruption is still active.",\n "allOf": [\n {\n "$ref": "#/definitions/ResumedBy"\n }\n ]\n }\n },\n "required": [\n "unix_millis_request_time",\n "labels"\n ]\n },\n "Cancellation": {\n "title": "Cancellation",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the cancellation request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the cancel request",\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n },\n "required": [\n "unix_millis_request_time",\n "labels"\n ]\n },\n "Killed": {\n "title": "Killed",\n "type": "object",\n "properties": {\n "unix_millis_request_time": {\n "title": "Unix Millis Request Time",\n "description": "The time that the cancellation request arrived",\n "type": "integer"\n },\n "labels": {\n "title": "Labels",\n "description": "Labels to describe the kill request",\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n },\n "required": [\n "unix_millis_request_time",\n "labels"\n ]\n }\n }\n}\n```\n\n\n### /tasks/{task_id}/log\n\n\n```\n{\n "title": "TaskEventLog",\n "type": "object",\n "properties": {\n "task_id": {\n "title": "Task Id",\n "type": "string"\n },\n "log": {\n "title": "Log",\n "description": "Log entries related to the overall task",\n "type": "array",\n "items": {\n "$ref": "#/definitions/LogEntry"\n }\n },\n "phases": {\n "title": "Phases",\n "description": "A dictionary whose keys (property names) are the indices of a phase",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/Phases"\n }\n }\n },\n "required": [\n "task_id"\n ],\n "additionalProperties": false,\n "definitions": {\n "Tier": {\n "title": "Tier",\n "description": "An enumeration.",\n "enum": [\n "uninitialized",\n "info",\n "warning",\n "error"\n ]\n },\n "LogEntry": {\n "title": "LogEntry",\n "type": "object",\n "properties": {\n "seq": {\n "title": "Seq",\n "description": "Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.",\n "exclusiveMaximum": 4294967296,\n "minimum": 0,\n "type": "integer"\n },\n "tier": {\n "description": "The importance level of the log entry",\n "allOf": [\n {\n "$ref": "#/definitions/Tier"\n }\n ]\n },\n "unix_millis_time": {\n "title": "Unix Millis Time",\n "type": "integer"\n },\n "text": {\n "title": "Text",\n "description": "The text of the log entry",\n "type": "string"\n }\n },\n "required": [\n "seq",\n "tier",\n "unix_millis_time",\n "text"\n ]\n },\n "Phases": {\n "title": "Phases",\n "type": "object",\n "properties": {\n "log": {\n "title": "Log",\n "description": "Log entries related to the overall phase",\n "type": "array",\n "items": {\n "$ref": "#/definitions/LogEntry"\n }\n },\n "events": {\n "title": "Events",\n "description": "A dictionary whose keys (property names) are the indices of an event in the phase",\n "type": "object",\n "additionalProperties": {\n "type": "array",\n "items": {\n "$ref": "#/definitions/LogEntry"\n }\n }\n }\n },\n "additionalProperties": false\n }\n }\n}\n```\n\n\n### /dispensers/{guid}/state\n\n\n```\n{\n "title": "DispenserState",\n "type": "object",\n "properties": {\n "time": {\n "title": "Time",\n "default": {\n "sec": 0,\n "nanosec": 0\n },\n "allOf": [\n {\n "$ref": "#/definitions/Time"\n }\n ]\n },\n "guid": {\n "title": "Guid",\n "default": "",\n "type": "string"\n },\n "mode": {\n "title": "Mode",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "request_guid_queue": {\n "title": "Request Guid Queue",\n "default": [],\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "seconds_remaining": {\n "title": "Seconds Remaining",\n "default": 0,\n "type": "number"\n }\n },\n "required": [\n "time",\n "guid",\n "mode",\n "request_guid_queue",\n "seconds_remaining"\n ],\n "definitions": {\n "Time": {\n "title": "Time",\n "type": "object",\n "properties": {\n "sec": {\n "title": "Sec",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "nanosec": {\n "title": "Nanosec",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n }\n },\n "required": [\n "sec",\n "nanosec"\n ]\n }\n }\n}\n```\n\n\n### /dispensers/{guid}/health\n\n\n```\n{\n "title": "DispenserHealth",\n "type": "object",\n "properties": {\n "health_status": {\n "title": "Health Status",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "health_message": {\n "title": "Health Message",\n "nullable": true,\n "type": "string"\n },\n "id_": {\n "title": "Id ",\n "maxLength": 255,\n "type": "string"\n }\n },\n "required": [\n "health_status",\n "id_"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /ingestors/{guid}/state\n\n\n```\n{\n "title": "IngestorState",\n "type": "object",\n "properties": {\n "time": {\n "title": "Time",\n "default": {\n "sec": 0,\n "nanosec": 0\n },\n "allOf": [\n {\n "$ref": "#/definitions/Time"\n }\n ]\n },\n "guid": {\n "title": "Guid",\n "default": "",\n "type": "string"\n },\n "mode": {\n "title": "Mode",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "request_guid_queue": {\n "title": "Request Guid Queue",\n "default": [],\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "seconds_remaining": {\n "title": "Seconds Remaining",\n "default": 0,\n "type": "number"\n }\n },\n "required": [\n "time",\n "guid",\n "mode",\n "request_guid_queue",\n "seconds_remaining"\n ],\n "definitions": {\n "Time": {\n "title": "Time",\n "type": "object",\n "properties": {\n "sec": {\n "title": "Sec",\n "default": 0,\n "minimum": -2147483648,\n "maximum": 2147483647,\n "type": "integer"\n },\n "nanosec": {\n "title": "Nanosec",\n "default": 0,\n "minimum": 0,\n "maximum": 4294967295,\n "type": "integer"\n }\n },\n "required": [\n "sec",\n "nanosec"\n ]\n }\n }\n}\n```\n\n\n### /ingestors/{guid}/health\n\n\n```\n{\n "title": "IngestorHealth",\n "type": "object",\n "properties": {\n "health_status": {\n "title": "Health Status",\n "maxLength": 255,\n "nullable": true,\n "type": "string"\n },\n "health_message": {\n "title": "Health Message",\n "nullable": true,\n "type": "string"\n },\n "id_": {\n "title": "Id ",\n "maxLength": 255,\n "type": "string"\n }\n },\n "required": [\n "health_status",\n "id_"\n ],\n "additionalProperties": false\n}\n```\n\n\n### /fleets/{name}/state\n\n\n```\n{\n "title": "FleetState",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "type": "string"\n },\n "robots": {\n "title": "Robots",\n "description": "A dictionary of the states of the robots that belong to this fleet",\n "type": "object",\n "additionalProperties": {\n "$ref": "#/definitions/RobotState"\n }\n }\n },\n "definitions": {\n "Status": {\n "title": "Status",\n "description": "An enumeration.",\n "enum": [\n "uninitialized",\n "offline",\n "shutdown",\n "idle",\n "charging",\n "working",\n "error"\n ]\n },\n "Location2D": {\n "title": "Location2D",\n "type": "object",\n "properties": {\n "map": {\n "title": "Map",\n "type": "string"\n },\n "x": {\n "title": "X",\n "type": "number"\n },\n "y": {\n "title": "Y",\n "type": "number"\n },\n "yaw": {\n "title": "Yaw",\n "type": "number"\n }\n },\n "required": [\n "map",\n "x",\n "y",\n "yaw"\n ]\n },\n "Issue": {\n "title": "Issue",\n "type": "object",\n "properties": {\n "category": {\n "title": "Category",\n "description": "Category of the robot\'s issue",\n "type": "string"\n },\n "detail": {\n "title": "Detail",\n "description": "Detailed information about the issue",\n "anyOf": [\n {\n "type": "object"\n },\n {\n "type": "array",\n "items": {}\n },\n {\n "type": "string"\n }\n ]\n }\n }\n },\n "Commission": {\n "title": "Commission",\n "type": "object",\n "properties": {\n "dispatch_tasks": {\n "title": "Dispatch Tasks",\n "description": "Should the robot accept dispatched tasks, true/false. When used in a request, leave this unset to not change the robot\'s current value.",\n "type": "boolean"\n },\n "direct_tasks": {\n "title": "Direct Tasks",\n "description": "Should the robot accept direct task requests, true/false. When used in a request, leave this unset to not change the robot\'s current value.",\n "type": "boolean"\n },\n "idle_behavior": {\n "title": "Idle Behavior",\n "description": "Should the robot perform its idle behavior, true/false. When used in a request, leave this unset to not change the robot\'s current value.",\n "type": "boolean"\n }\n }\n },\n "MutexGroups": {\n "title": "MutexGroups",\n "type": "object",\n "properties": {\n "locked": {\n "title": "Locked",\n "description": "A list of mutex groups that this robot has currently locked",\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "requesting": {\n "title": "Requesting",\n "description": "A list of the mutex groups that this robot is currently requesting but has not lockd yet",\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n }\n },\n "RobotState": {\n "title": "RobotState",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "type": "string"\n },\n "status": {\n "description": "A simple token representing the status of the robot",\n "allOf": [\n {\n "$ref": "#/definitions/Status"\n }\n ]\n },\n "task_id": {\n "title": "Task Id",\n "description": "The ID of the task this robot is currently working on. Empty string if the robot is not working on a task.",\n "type": "string"\n },\n "unix_millis_time": {\n "title": "Unix Millis Time",\n "type": "integer"\n },\n "location": {\n "$ref": "#/definitions/Location2D"\n },\n "battery": {\n "title": "Battery",\n "description": "State of charge of the battery. Values range from 0.0 (depleted) to 1.0 (fully charged)",\n "minimum": 0.0,\n "maximum": 1.0,\n "type": "number"\n },\n "issues": {\n "title": "Issues",\n "description": "A list of issues with the robot that operators need to address",\n "type": "array",\n "items": {\n "$ref": "#/definitions/Issue"\n }\n },\n "commission": {\n "$ref": "#/definitions/Commission"\n },\n "mutex_groups": {\n "title": "Mutex Groups",\n "description": "Information about the mutex groups that this robot is interacting with",\n "allOf": [\n {\n "$ref": "#/definitions/MutexGroups"\n }\n ]\n }\n }\n }\n }\n}\n```\n\n\n### /fleets/{name}/log\n\n\n```\n{\n "title": "FleetLog",\n "type": "object",\n "properties": {\n "name": {\n "title": "Name",\n "type": "string"\n },\n "log": {\n "title": "Log",\n "description": "Log for the overall fleet",\n "type": "array",\n "items": {\n "$ref": "#/definitions/LogEntry"\n }\n },\n "robots": {\n "title": "Robots",\n "description": "Dictionary of logs for the individual robots. The keys (property names) are the robot names.",\n "type": "object",\n "additionalProperties": {\n "type": "array",\n "items": {\n "$ref": "#/definitions/LogEntry"\n }\n }\n }\n },\n "definitions": {\n "Tier": {\n "title": "Tier",\n "description": "An enumeration.",\n "enum": [\n "uninitialized",\n "info",\n "warning",\n "error"\n ]\n },\n "LogEntry": {\n "title": "LogEntry",\n "type": "object",\n "properties": {\n "seq": {\n "title": "Seq",\n "description": "Sequence number for this entry. Each entry has a unique sequence number which monotonically increase, until integer overflow causes a wrap around.",\n "exclusiveMaximum": 4294967296,\n "minimum": 0,\n "type": "integer"\n },\n "tier": {\n "description": "The importance level of the log entry",\n "allOf": [\n {\n "$ref": "#/definitions/Tier"\n }\n ]\n },\n "unix_millis_time": {\n "title": "Unix Millis Time",\n "type": "integer"\n },\n "text": {\n "title": "Text",\n "description": "The text of the log entry",\n "type": "string"\n }\n },\n "required": [\n "seq",\n "tier",\n "unix_millis_time",\n "text"\n ]\n }\n }\n}\n```\n\n\n### /rios\n\n\n```\n{\n "title": "Rio",\n "type": "object",\n "properties": {\n "id": {\n "title": "Id",\n "type": "string"\n },\n "type": {\n "title": "Type",\n "type": "string"\n },\n "data": {\n "title": "Data",\n "type": "object"\n }\n },\n "required": [\n "id",\n "type",\n "data"\n ]\n}\n```\n\n', operationId: '_lambda__socket_io_get', responses: { '200': { @@ -67,43 +67,82 @@ export default { }, }, }, - '/alerts': { + '/alerts/request': { + post: { + tags: ['Alerts'], + summary: 'Create New Alert', + description: 'Creates a new alert.', + operationId: 'create_new_alert_alerts_request_post', + requestBody: { + content: { + 'application/json': { schema: { $ref: '#/components/schemas/AlertRequest' } }, + }, + required: true, + }, + responses: { + '201': { + description: 'Successful Response', + content: { + 'application/json': { schema: { $ref: '#/components/schemas/AlertRequest' } }, + }, + }, + '422': { + description: 'Validation Error', + content: { + 'application/json': { schema: { $ref: '#/components/schemas/HTTPValidationError' } }, + }, + }, + }, + }, + }, + '/alerts/request/{alert_id}': { get: { tags: ['Alerts'], - summary: 'Get Alerts', - operationId: 'get_alerts_alerts_get', + summary: 'Get Alert', + description: 'Gets an alert based on the alert ID.', + operationId: 'get_alert_alerts_request__alert_id__get', + parameters: [ + { + required: true, + schema: { title: 'Alert Id', type: 'string' }, + name: 'alert_id', + in: 'path', + }, + ], responses: { '200': { description: 'Successful Response', content: { - 'application/json': { - schema: { - title: 'Response Get Alerts Alerts Get', - type: 'array', - items: { - $ref: '#/components/schemas/api_server.models.tortoise_models.alerts.Alert.leaf', - }, - }, - }, + 'application/json': { schema: { $ref: '#/components/schemas/AlertRequest' } }, + }, + }, + '422': { + description: 'Validation Error', + content: { + 'application/json': { schema: { $ref: '#/components/schemas/HTTPValidationError' } }, }, }, }, }, + }, + '/alerts/request/{alert_id}/respond': { post: { tags: ['Alerts'], - summary: 'Create Alert', - operationId: 'create_alert_alerts_post', + summary: 'Respond To Alert', + description: + 'Responds to an existing alert. The response must be one of the available\nresponses listed in the alert.', + operationId: 'respond_to_alert_alerts_request__alert_id__respond_post', parameters: [ { required: true, schema: { title: 'Alert Id', type: 'string' }, name: 'alert_id', - in: 'query', + in: 'path', }, { required: true, - schema: { title: 'Category', type: 'string' }, - name: 'category', + schema: { title: 'Response', type: 'string' }, + name: 'response', in: 'query', }, ], @@ -111,11 +150,7 @@ export default { '201': { description: 'Successful Response', content: { - 'application/json': { - schema: { - $ref: '#/components/schemas/api_server.models.tortoise_models.alerts.Alert.leaf', - }, - }, + 'application/json': { schema: { $ref: '#/components/schemas/AlertResponse' } }, }, }, '422': { @@ -127,11 +162,12 @@ export default { }, }, }, - '/alerts/{alert_id}': { + '/alerts/request/{alert_id}/response': { get: { tags: ['Alerts'], - summary: 'Get Alert', - operationId: 'get_alert_alerts__alert_id__get', + summary: 'Get Alert Response', + description: 'Gets the response to the alert based on the alert ID.', + operationId: 'get_alert_response_alerts_request__alert_id__response_get', parameters: [ { required: true, @@ -144,11 +180,7 @@ export default { '200': { description: 'Successful Response', content: { - 'application/json': { - schema: { - $ref: '#/components/schemas/api_server.models.tortoise_models.alerts.Alert.leaf', - }, - }, + 'application/json': { schema: { $ref: '#/components/schemas/AlertResponse' } }, }, }, '422': { @@ -159,25 +191,69 @@ export default { }, }, }, - post: { + }, + '/alerts/requests/task/{task_id}': { + get: { tags: ['Alerts'], - summary: 'Acknowledge Alert', - operationId: 'acknowledge_alert_alerts__alert_id__post', + summary: 'Get Alerts Of Task', + description: + 'Returns all the alerts associated to a task ID. Provides the option to only\nreturn alerts that have not been responded to yet.', + operationId: 'get_alerts_of_task_alerts_requests_task__task_id__get', parameters: [ { required: true, - schema: { title: 'Alert Id', type: 'string' }, - name: 'alert_id', + schema: { title: 'Task Id', type: 'string' }, + name: 'task_id', in: 'path', }, + { + required: false, + schema: { title: 'Unresponded', type: 'boolean', default: true }, + name: 'unresponded', + in: 'query', + }, ], responses: { - '201': { + '200': { + description: 'Successful Response', + content: { + 'application/json': { + schema: { + title: 'Response Get Alerts Of Task Alerts Requests Task Task Id Get', + type: 'array', + items: { $ref: '#/components/schemas/AlertRequest' }, + }, + }, + }, + }, + '422': { + description: 'Validation Error', + content: { + 'application/json': { schema: { $ref: '#/components/schemas/HTTPValidationError' } }, + }, + }, + }, + }, + }, + '/alerts/unresponded_requests': { + get: { + tags: ['Alerts'], + summary: 'Get Unresponded Alerts', + description: + 'Returns the list of alert IDs that have yet to be responded to, while a\nresponse was required.', + operationId: 'get_unresponded_alerts_alerts_unresponded_requests_get', + requestBody: { + content: { 'application/json': { schema: { $ref: '#/components/schemas/Pagination' } } }, + }, + responses: { + '200': { description: 'Successful Response', content: { 'application/json': { schema: { - $ref: '#/components/schemas/api_server.models.tortoise_models.alerts.Alert.leaf', + title: 'Response Get Unresponded Alerts Alerts Unresponded Requests Get', + type: 'array', + items: { $ref: '#/components/schemas/AlertRequest' }, }, }, }, @@ -709,8 +785,6 @@ export default { get: { tags: ['Tasks'], summary: 'Query Task States', - description: - 'Note that sorting by `pickup` and `destination` is mutually exclusive and sorting\nby either of them will filter only tasks which has those labels.', operationId: 'query_task_states_tasks_get', parameters: [ { @@ -747,27 +821,25 @@ export default { in: 'query', }, { - description: 'comma separated list of pickup names. [deprecated] use `label` instead', + description: 'pickup name. [deprecated] use `label` instead', required: false, deprecated: true, schema: { title: 'Pickup', type: 'string', - description: 'comma separated list of pickup names. [deprecated] use `label` instead', + description: 'pickup name. [deprecated] use `label` instead', }, name: 'pickup', in: 'query', }, { - description: - 'comma separated list of destination names, [deprecated] use `label` instead', + description: 'destination name, [deprecated] use `label` instead', required: false, deprecated: true, schema: { title: 'Destination', type: 'string', - description: - 'comma separated list of destination names, [deprecated] use `label` instead', + description: 'destination name, [deprecated] use `label` instead', }, name: 'destination', in: 'query', @@ -2004,6 +2076,63 @@ export default { }, }, }, + '/rios': { + get: { + tags: ['RIOs'], + summary: 'Query Rios', + operationId: 'query_rios_rios_get', + parameters: [ + { required: false, schema: { title: 'Id ', type: 'string' }, name: 'id_', in: 'query' }, + { + required: false, + schema: { title: 'Type ', type: 'string' }, + name: 'type_', + in: 'query', + }, + ], + responses: { + '200': { + description: 'Successful Response', + content: { + 'application/json': { + schema: { + title: 'Response Query Rios Rios Get', + type: 'array', + items: { $ref: '#/components/schemas/Rio' }, + }, + }, + }, + }, + '422': { + description: 'Validation Error', + content: { + 'application/json': { schema: { $ref: '#/components/schemas/HTTPValidationError' } }, + }, + }, + }, + }, + put: { + tags: ['RIOs'], + summary: 'Put Rio', + operationId: 'put_rio_rios_put', + requestBody: { + content: { 'application/json': { schema: { $ref: '#/components/schemas/Rio' } } }, + required: true, + }, + responses: { + '200': { + description: 'Successful Response', + content: { 'application/json': { schema: {} } }, + }, + '422': { + description: 'Validation Error', + content: { + 'application/json': { schema: { $ref: '#/components/schemas/HTTPValidationError' } }, + }, + }, + }, + }, + }, '/admin/users': { get: { tags: ['Admin'], @@ -2515,6 +2644,60 @@ export default { data: { title: 'Data', type: 'string' }, }, }, + AlertParameter: { + title: 'AlertParameter', + required: ['name', 'value'], + type: 'object', + properties: { + name: { title: 'Name', type: 'string' }, + value: { title: 'Value', type: 'string' }, + }, + }, + AlertRequest: { + title: 'AlertRequest', + required: [ + 'id', + 'unix_millis_alert_time', + 'title', + 'subtitle', + 'message', + 'display', + 'tier', + 'responses_available', + 'alert_parameters', + ], + type: 'object', + properties: { + id: { title: 'Id', type: 'string' }, + unix_millis_alert_time: { title: 'Unix Millis Alert Time', type: 'integer' }, + title: { title: 'Title', type: 'string' }, + subtitle: { title: 'Subtitle', type: 'string' }, + message: { title: 'Message', type: 'string' }, + display: { title: 'Display', type: 'boolean' }, + tier: { $ref: '#/components/schemas/api_server__models__alerts__AlertRequest__Tier' }, + responses_available: { + title: 'Responses Available', + type: 'array', + items: { type: 'string' }, + }, + alert_parameters: { + title: 'Alert Parameters', + type: 'array', + items: { $ref: '#/components/schemas/AlertParameter' }, + }, + task_id: { title: 'Task Id', type: 'string' }, + }, + }, + AlertResponse: { + title: 'AlertResponse', + required: ['id', 'unix_millis_response_time', 'response'], + type: 'object', + properties: { + id: { title: 'Id', type: 'string' }, + unix_millis_response_time: { title: 'Unix Millis Response Time', type: 'integer' }, + response: { title: 'Response', type: 'string' }, + }, + }, AssignedTo: { title: 'AssignedTo', required: ['group', 'name'], @@ -3353,6 +3536,16 @@ export default { }, }, }, + Pagination: { + title: 'Pagination', + required: ['limit', 'offset', 'order_by'], + type: 'object', + properties: { + limit: { title: 'Limit', type: 'integer' }, + offset: { title: 'Offset', type: 'integer' }, + order_by: { title: 'Order By', type: 'array', items: { type: 'string' } }, + }, + }, Param: { title: 'Param', required: ['name', 'type', 'value_int', 'value_float', 'value_string', 'value_bool'], @@ -3528,6 +3721,16 @@ export default { }, }, }, + Rio: { + title: 'Rio', + required: ['id', 'type', 'data'], + type: 'object', + properties: { + id: { title: 'Id', type: 'string' }, + type: { title: 'Type', type: 'string' }, + data: { title: 'Data', type: 'object' }, + }, + }, RobotCommissionResponse: { title: 'RobotCommissionResponse', required: ['commission'], @@ -4216,42 +4419,6 @@ export default { type: { title: 'Error Type', type: 'string' }, }, }, - 'api_server.models.tortoise_models.alerts.Alert.leaf': { - title: 'Alert', - required: ['id', 'original_id', 'category', 'unix_millis_created_time'], - type: 'object', - properties: { - id: { title: 'Id', maxLength: 255, type: 'string' }, - original_id: { title: 'Original Id', maxLength: 255, type: 'string' }, - category: { - title: 'Category', - maxLength: 7, - type: 'string', - description: 'Default: default
Task: task
Fleet: fleet
Robot: robot', - }, - unix_millis_created_time: { - title: 'Unix Millis Created Time', - maximum: 9.223372036854776e18, - minimum: -9.223372036854776e18, - type: 'integer', - }, - acknowledged_by: { - title: 'Acknowledged By', - maxLength: 255, - type: 'string', - nullable: true, - }, - unix_millis_acknowledged_time: { - title: 'Unix Millis Acknowledged Time', - maximum: 9.223372036854776e18, - minimum: -9.223372036854776e18, - type: 'integer', - nullable: true, - }, - }, - additionalProperties: false, - description: 'General alert that can be triggered by events.', - }, 'api_server.models.tortoise_models.beacons.BeaconState.leaf': { title: 'BeaconState', required: ['id', 'online', 'activated'], @@ -4319,6 +4486,12 @@ export default { $ref: '#/components/schemas/api_server.models.tortoise_models.scheduled_task.ScheduledTask', }, }, + api_server__models__alerts__AlertRequest__Tier: { + title: 'Tier', + enum: ['info', 'warning', 'error'], + type: 'string', + description: 'An enumeration.', + }, api_server__models__delivery_alerts__DeliveryAlert__Category: { title: 'Category', enum: ['missing', 'wrong', 'obstructed', 'cancelled'], diff --git a/packages/api-server/api_server/app.py b/packages/api-server/api_server/app.py index 0a0637fc5..0928a0acf 100644 --- a/packages/api-server/api_server/app.py +++ b/packages/api-server/api_server/app.py @@ -33,7 +33,7 @@ ) from .models import tortoise_models as ttm from .repositories import TaskRepository -from .rmf_io import HealthWatchdog, RmfBookKeeper, rmf_events +from .rmf_io import HealthWatchdog, RmfBookKeeper, alert_events, rmf_events from .types import is_coroutine @@ -89,7 +89,7 @@ async def on_sio_connect( # will be called in reverse order on app shutdown shutdown_cbs: List[Union[Coroutine[Any, Any, Any], Callable[[], None]]] = [] -rmf_bookkeeper = RmfBookKeeper(rmf_events) +rmf_bookkeeper = RmfBookKeeper(rmf_events, alert_events) app.include_router(routes.main_router) app.include_router( diff --git a/packages/api-server/api_server/exceptions.py b/packages/api-server/api_server/exceptions.py new file mode 100644 index 000000000..215ae39c2 --- /dev/null +++ b/packages/api-server/api_server/exceptions.py @@ -0,0 +1,16 @@ +class AlreadyExistsError(Exception): + """ + Raised when an a resource already exists and there is a conflict. + """ + + +class NotFoundError(Exception): + """ + Raised when a resource is not found. + """ + + +class InvalidInputError(Exception): + """ + Raised when an input is invalid. + """ diff --git a/packages/api-server/api_server/gateway.py b/packages/api-server/api_server/gateway.py index 7070960f0..c13727a56 100644 --- a/packages/api-server/api_server/gateway.py +++ b/packages/api-server/api_server/gateway.py @@ -31,12 +31,17 @@ from rmf_ingestor_msgs.msg import IngestorState as RmfIngestorState from rmf_lift_msgs.msg import LiftRequest as RmfLiftRequest from rmf_lift_msgs.msg import LiftState as RmfLiftState +from rmf_task_msgs.msg import Alert as RmfAlert +from rmf_task_msgs.msg import AlertResponse as RmfAlertResponse from rmf_task_msgs.srv import CancelTask as RmfCancelTask from rmf_task_msgs.srv import SubmitTask as RmfSubmitTask from rosidl_runtime_py.convert import message_to_ordereddict from std_msgs.msg import Bool as BoolMsg from .models import ( + AlertParameter, + AlertRequest, + AlertResponse, BeaconState, BuildingMap, DeliveryAlert, @@ -48,7 +53,7 @@ ) from .models.delivery_alerts import action_from_msg, category_from_msg, tier_from_msg from .repositories import CachedFilesRepository, cached_files_repo -from .rmf_io import rmf_events +from .rmf_io import alert_events, rmf_events from .ros import ros_node @@ -107,6 +112,17 @@ def __init__(self, cached_files: CachedFilesRepository): ), ) + self._alert_response = ros_node().create_publisher( + RmfAlertResponse, + "alert_response", + rclpy.qos.QoSProfile( + history=rclpy.qos.HistoryPolicy.KEEP_LAST, + depth=10, + reliability=rclpy.qos.ReliabilityPolicy.RELIABLE, + durability=rclpy.qos.DurabilityPolicy.TRANSIENT_LOCAL, + ), + ) + self._mutex_group_release = ros_node().create_publisher( RmfMutexGroupManualRelease, "mutex_group_manual_release", @@ -248,6 +264,71 @@ def handle_delivery_alert(delivery_alert: DeliveryAlert): ) self._subscriptions.append(delivery_alert_request_sub) + def convert_alert(alert: RmfAlert): + tier = AlertRequest.Tier.Info + if alert.tier == RmfAlert.TIER_WARNING: + tier = AlertRequest.Tier.Warning + elif alert.tier == RmfAlert.TIER_ERROR: + tier = AlertRequest.Tier.Error + + parameters = [] + for p in alert.alert_parameters: + parameters.append(AlertParameter(name=p.name, value=p.value)) + + return AlertRequest( + id=alert.id, + unix_millis_alert_time=round(datetime.now().timestamp() * 1000), + title=alert.title, + subtitle=alert.subtitle, + message=alert.message, + display=alert.display, + tier=tier, + responses_available=alert.responses_available, + alert_parameters=parameters, + task_id=alert.task_id if len(alert.task_id) > 0 else None, + ) + + def handle_alert(alert: AlertRequest): + logging.info(f"Received alert: {alert}") + alert_events.alert_requests.on_next(alert) + + alert_sub = ros_node().create_subscription( + RmfAlert, + "alert", + lambda msg: handle_alert(convert_alert(msg)), + rclpy.qos.QoSProfile( + history=rclpy.qos.HistoryPolicy.KEEP_LAST, + depth=10, + reliability=rclpy.qos.ReliabilityPolicy.RELIABLE, + durability=rclpy.qos.DurabilityPolicy.TRANSIENT_LOCAL, + ), + ) + self._subscriptions.append(alert_sub) + + def convert_alert_response(alert_response: RmfAlertResponse): + return AlertResponse( + id=alert_response.id, + unix_millis_response_time=round(datetime.now().timestamp() * 1000), + response=alert_response.response, + ) + + def handle_alert_response(alert_response: AlertResponse): + logging.info(f"Received alert response: {alert_response}") + alert_events.alert_responses.on_next(alert_response) + + alert_response_sub = ros_node().create_subscription( + RmfAlertResponse, + "alert_response", + lambda msg: handle_alert_response(convert_alert_response(msg)), + rclpy.qos.QoSProfile( + history=rclpy.qos.HistoryPolicy.KEEP_LAST, + depth=10, + reliability=rclpy.qos.ReliabilityPolicy.RELIABLE, + durability=rclpy.qos.DurabilityPolicy.TRANSIENT_LOCAL, + ), + ) + self._subscriptions.append(alert_response_sub) + def handle_fire_alarm_trigger(fire_alarm_trigger_msg: BoolMsg): if fire_alarm_trigger_msg.data: logging.info("Fire alarm triggered") @@ -330,6 +411,12 @@ def respond_to_delivery_alert( msg.message = message self._delivery_alert_response.publish(msg) + def respond_to_alert(self, alert_id: str, response: str): + msg = RmfAlertResponse() + msg.id = alert_id + msg.response = response + self._alert_response.publish(msg) + def manual_release_mutex_groups( self, mutex_groups: List[str], diff --git a/packages/api-server/api_server/models/__init__.py b/packages/api-server/api_server/models/__init__.py index 8193e0c99..72016de82 100644 --- a/packages/api-server/api_server/models/__init__.py +++ b/packages/api-server/api_server/models/__init__.py @@ -1,3 +1,4 @@ +from .alerts import * from .authz import * from .beacons import * from .building_map import * @@ -48,7 +49,9 @@ from .rmf_api.task_log_response import TaskLogResponse from .rmf_api.task_log_update import TaskEventLogUpdate from .rmf_api.task_request import TaskRequest -from .rmf_api.task_state import Status, TaskState +from .rmf_api.task_state import Status +from .rmf_api.task_state import Status1 as DispatchStatus +from .rmf_api.task_state import TaskState from .rmf_api.task_state_update import TaskStateUpdate from .rmf_api.undo_skip_phase_request import UndoPhaseSkipRequest from .rmf_api.undo_skip_phase_response import UndoPhaseSkipResponse diff --git a/packages/api-server/api_server/models/alerts.py b/packages/api-server/api_server/models/alerts.py new file mode 100644 index 000000000..c31a17afb --- /dev/null +++ b/packages/api-server/api_server/models/alerts.py @@ -0,0 +1,69 @@ +from datetime import datetime +from enum import Enum +from typing import List, Optional + +from pydantic import BaseModel + +from . import tortoise_models as ttm + + +class AlertParameter(BaseModel): + name: str + value: str + + +class AlertResponse(BaseModel): + id: str + unix_millis_response_time: int + response: str + + @staticmethod + def from_tortoise(tortoise: ttm.AlertResponse) -> "AlertResponse": + return AlertResponse(**tortoise.data) + + async def save(self) -> None: + await ttm.AlertResponse.update_or_create( + { + "response_time": datetime.fromtimestamp( + self.unix_millis_response_time / 1000 + ), + "response": self.response, + "data": self.json(), + }, + id=self.id, + ) + + +class AlertRequest(BaseModel): + class Tier(str, Enum): + Info = "info" + Warning = "warning" + Error = "error" + + id: str + unix_millis_alert_time: int + title: str + subtitle: str + message: str + display: bool + tier: Tier + responses_available: List[str] + alert_parameters: List[AlertParameter] + task_id: Optional[str] + + @staticmethod + def from_tortoise(tortoise: ttm.AlertRequest) -> "AlertRequest": + return AlertRequest(**tortoise.data) + + async def save(self) -> None: + await ttm.AlertRequest.update_or_create( + { + "request_time": datetime.fromtimestamp( + self.unix_millis_alert_time / 1000 + ), + "response_expected": (len(self.responses_available) > 0), + "task_id": self.task_id, + "data": self.json(), + }, + id=self.id, + ) diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/ChargingAssignment.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/ChargingAssignment.py new file mode 100644 index 000000000..710bdd4fa --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/ChargingAssignment.py @@ -0,0 +1,29 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class ChargingAssignment(pydantic.BaseModel): + robot_name: str = "" # string + waypoint_name: str = "" # string + mode: pydantic.conint(ge=0, le=255) = 0 # uint8 + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "robot_name", + "waypoint_name", + "mode", + ], + } + + +# string robot_name +# string waypoint_name +# uint8 mode +# +# uint8 MODE_CHARGE = 0 +# uint8 MODE_WAIT = 1 diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/ChargingAssignments.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/ChargingAssignments.py new file mode 100644 index 000000000..8d738ff4e --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/ChargingAssignments.py @@ -0,0 +1,25 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..rmf_fleet_msgs.ChargingAssignment import ChargingAssignment + + +class ChargingAssignments(pydantic.BaseModel): + fleet_name: str = "" # string + assignments: List[ChargingAssignment] = [] # rmf_fleet_msgs/ChargingAssignment + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "fleet_name", + "assignments", + ], + } + + +# string fleet_name +# ChargingAssignment[] assignments diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/DeliveryAlertCategory.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/DeliveryAlertCategory.py index 3028860d1..6a6eb3b72 100644 --- a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/DeliveryAlertCategory.py +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/DeliveryAlertCategory.py @@ -20,3 +20,5 @@ class Config: # uint32 value # uint32 MISSING=0 # uint32 WRONG=1 +# uint32 OBSTRUCTED=2 +# uint32 CANCELLED=3 diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/InterruptRequest.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/InterruptRequest.py new file mode 100644 index 000000000..c5a04ff9c --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/InterruptRequest.py @@ -0,0 +1,35 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class InterruptRequest(pydantic.BaseModel): + fleet_name: str = "" # string + robot_name: str = "" # string + interrupt_id: str = "" # string + labels: List[str] = [] # string + type: pydantic.conint(ge=0, le=255) = 0 # uint8 + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "fleet_name", + "robot_name", + "interrupt_id", + "labels", + "type", + ], + } + + +# string fleet_name +# string robot_name +# string interrupt_id +# string[] labels +# uint8 type +# +# uint8 TYPE_INTERRUPT = 0 +# uint8 TYPE_RESUME = 1 diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/LaneStates.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/LaneStates.py new file mode 100644 index 000000000..651ad5ffb --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/LaneStates.py @@ -0,0 +1,33 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..rmf_fleet_msgs.SpeedLimitedLane import SpeedLimitedLane + + +class LaneStates(pydantic.BaseModel): + fleet_name: str = "" # string + closed_lanes: List[pydantic.conint(ge=0, le=18446744073709551615)] = [] # uint64 + speed_limits: List[SpeedLimitedLane] = [] # rmf_fleet_msgs/SpeedLimitedLane + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "fleet_name", + "closed_lanes", + "speed_limits", + ], + } + + +# # The name of the fleet with closed or speed limited lanes +# string fleet_name +# +# # The indices of the lanes that are currently closed +# uint64[] closed_lanes +# +# # Lanes that have speed limits +# SpeedLimitedLane[] speed_limits diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupAssignment.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupAssignment.py new file mode 100644 index 000000000..c6fc3c71e --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupAssignment.py @@ -0,0 +1,37 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..builtin_interfaces.Time import Time + + +class MutexGroupAssignment(pydantic.BaseModel): + group: str = "" # string + claimant: pydantic.conint(ge=0, le=18446744073709551615) = 0 # uint64 + claim_time: Time = Time() # builtin_interfaces/Time + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "group", + "claimant", + "claim_time", + ], + } + + +# # This message maps a mutex group name to the name of an agent that is currently +# # holding the claim to that group. +# +# # Name of the mutex group that is being described. +# string group +# +# # Traffic Participant ID of the agent that has currently claimed the group. +# # If the group is unclaimed, this will be the max uint64 value. +# uint64 claimant +# +# # Time stamp of when the claim request began. +# builtin_interfaces/Time claim_time diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupManualRelease.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupManualRelease.py new file mode 100644 index 000000000..4021aadc7 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupManualRelease.py @@ -0,0 +1,34 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class MutexGroupManualRelease(pydantic.BaseModel): + release_mutex_groups: List[str] = [] # string + fleet: str = "" # string + robot: str = "" # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "release_mutex_groups", + "fleet", + "robot", + ], + } + + +# # This message allows operators to manually request that a robot release one or +# # more mutex groups that it is currently holding. +# +# # Name of the mutex groups to release +# string[] release_mutex_groups +# +# # The name of the fleet that the robot belongs to +# string fleet +# +# # The name of the robot that needs to release the mutex groups +# string robot diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupRequest.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupRequest.py new file mode 100644 index 000000000..7abba9ea9 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupRequest.py @@ -0,0 +1,50 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..builtin_interfaces.Time import Time + + +class MutexGroupRequest(pydantic.BaseModel): + group: str = "" # string + claimant: pydantic.conint(ge=0, le=18446744073709551615) = 0 # uint64 + claim_time: Time = Time() # builtin_interfaces/Time + mode: pydantic.conint(ge=0, le=4294967295) = 0 # uint32 + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "group", + "claimant", + "claim_time", + "mode", + ], + } + + +# # This message is used to attempt to claim a mutex group. It should be sent +# # periodically for the entire duration that the claimer needs the mutex because +# # mutex groups have a limited-time leasing period that will timeout if a request +# # heartbeat is not received in some amount of time. +# +# # Name of the mutex group that is being claimed +# string group +# +# # Name of the agent that is trying to claim the mutex group. +# uint64 claimant +# +# # Time stamp of when the claim request began. The same time stamp should be used +# # for all subsequent heartbeat messages related to this claim. If the claim time +# # changes then this claim will be treated a new claim and may be deprioritized. +# # Earlier claims have priority over later claims. +# builtin_interfaces/Time claim_time +# +# # What kind of request is this? +# uint32 mode +# # Request to release the mutex group from this claimer +# uint32 MODE_RELEASE=0 +# # Request to lock the mutex group for this claimer +# uint32 MODE_LOCK=1 diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupStates.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupStates.py new file mode 100644 index 000000000..ab4fe1e1f --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/MutexGroupStates.py @@ -0,0 +1,23 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..rmf_fleet_msgs.MutexGroupAssignment import MutexGroupAssignment + + +class MutexGroupStates(pydantic.BaseModel): + assignments: List[MutexGroupAssignment] = [] # rmf_fleet_msgs/MutexGroupAssignment + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "assignments", + ], + } + + +# # A map of all the current mutex group assignments +# MutexGroupAssignment[] assignments diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/RobotMode.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/RobotMode.py index 20e13587c..99048ff00 100644 --- a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/RobotMode.py +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/RobotMode.py @@ -8,6 +8,7 @@ class RobotMode(pydantic.BaseModel): mode: pydantic.conint(ge=0, le=4294967295) = 0 # uint32 mode_request_id: pydantic.conint(ge=0, le=18446744073709551615) = 0 # uint64 + performing_action: str = "" # string class Config: orm_mode = True @@ -15,6 +16,7 @@ class Config: "required": [ "mode", "mode_request_id", + "performing_action", ], } @@ -35,4 +37,14 @@ class Config: # # uint32 MODE_CLEANING=9 # +# # These modes are used to indicate that the robot has started or completed +# # performing an action in simulation, it is not encouraged to be used for +# # fleet adapters +# uint32 MODE_PERFORMING_ACTION=10 +# uint32 MODE_ACTION_COMPLETED=11 +# # uint64 mode_request_id +# +# # Specify the action that the robot is performing when its current mode +# # is MODE_PERFORMING_ACTION +# string performing_action diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/SpeedLimitRequest.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/SpeedLimitRequest.py new file mode 100644 index 000000000..1a37c1c97 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/SpeedLimitRequest.py @@ -0,0 +1,33 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..rmf_fleet_msgs.SpeedLimitedLane import SpeedLimitedLane + + +class SpeedLimitRequest(pydantic.BaseModel): + fleet_name: str = "" # string + speed_limits: List[SpeedLimitedLane] = [] # rmf_fleet_msgs/SpeedLimitedLane + remove_limits: List[pydantic.conint(ge=0, le=18446744073709551615)] = [] # uint64 + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "fleet_name", + "speed_limits", + "remove_limits", + ], + } + + +# # The name of the fleet +# string fleet_name +# +# # The lanes to impose speed limits upon. +# SpeedLimitedLane[] speed_limits +# +# # The indices of lanes to remove speed limits +# uint64[] remove_limits diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/SpeedLimitedLane.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/SpeedLimitedLane.py new file mode 100644 index 000000000..8d86ed88a --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/SpeedLimitedLane.py @@ -0,0 +1,26 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class SpeedLimitedLane(pydantic.BaseModel): + lane_index: pydantic.conint(ge=0, le=18446744073709551615) = 0 # uint64 + speed_limit: float = 0 # float64 + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "lane_index", + "speed_limit", + ], + } + + +# # The index of the lane with a speed limit +# uint64 lane_index +# +# # The imposed speed limit for the lane +# float64 speed_limit diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/__init__.py b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/__init__.py index aa71579ca..b854b8e85 100644 --- a/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/__init__.py +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_fleet_msgs/__init__.py @@ -1,4 +1,6 @@ from .BeaconState import BeaconState +from .ChargingAssignment import ChargingAssignment +from .ChargingAssignments import ChargingAssignments from .ClosedLanes import ClosedLanes from .DeliveryAlert import DeliveryAlert from .DeliveryAlertAction import DeliveryAlertAction @@ -9,13 +11,21 @@ from .DockParameter import DockParameter from .DockSummary import DockSummary from .FleetState import FleetState +from .InterruptRequest import InterruptRequest from .LaneRequest import LaneRequest +from .LaneStates import LaneStates from .LiftClearance_Request import LiftClearance_Request from .LiftClearance_Response import LiftClearance_Response from .Location import Location from .ModeParameter import ModeParameter from .ModeRequest import ModeRequest +from .MutexGroupAssignment import MutexGroupAssignment +from .MutexGroupManualRelease import MutexGroupManualRelease +from .MutexGroupRequest import MutexGroupRequest +from .MutexGroupStates import MutexGroupStates from .PathRequest import PathRequest from .PauseRequest import PauseRequest from .RobotMode import RobotMode from .RobotState import RobotState +from .SpeedLimitedLane import SpeedLimitedLane +from .SpeedLimitRequest import SpeedLimitRequest diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/Alert.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/Alert.py new file mode 100644 index 000000000..8f51889a1 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/Alert.py @@ -0,0 +1,65 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..rmf_task_msgs.AlertParameter import AlertParameter + + +class Alert(pydantic.BaseModel): + id: str = "" # string + title: str = "" # string + subtitle: str = "" # string + message: str = "" # string + display: bool = False # bool + tier: pydantic.conint(ge=0, le=255) = 0 # uint8 + responses_available: List[str] = [] # string + alert_parameters: List[AlertParameter] = [] # rmf_task_msgs/AlertParameter + task_id: str = "" # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "id", + "title", + "subtitle", + "message", + "display", + "tier", + "responses_available", + "alert_parameters", + "task_id", + ], + } + + +# # The unique ID which responses can reply to +# string id +# +# # Title, subtitle and message to be displayed on any frontend +# string title +# string subtitle +# string message +# +# # Whether this alert should be displayed on any frontend, default +# # as true +# bool display true +# +# # The severity tier of this alert +# uint8 tier +# uint8 TIER_INFO=0 +# uint8 TIER_WARNING=1 +# uint8 TIER_ERROR=2 +# +# # Responses available for this alert. If no responses are expected +# # this field can be left empty +# string[] responses_available +# +# # Parameters that may be useful for custom interactions +# AlertParameter[] alert_parameters +# +# # The task ID that is involved in this alert. If no task is involved +# # this string can be left empty +# string task_id diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/AlertParameter.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/AlertParameter.py new file mode 100644 index 000000000..f90309658 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/AlertParameter.py @@ -0,0 +1,24 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class AlertParameter(pydantic.BaseModel): + name: str = "" # string + value: str = "" # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "name", + "value", + ], + } + + +# # Generic key-value pair to be used in Alert +# string name +# string value diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/AlertResponse.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/AlertResponse.py new file mode 100644 index 000000000..585aa0395 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/AlertResponse.py @@ -0,0 +1,27 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class AlertResponse(pydantic.BaseModel): + id: str = "" # string + response: str = "" # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "id", + "response", + ], + } + + +# # The unique ID of the Alert this response is for +# string id +# +# # This response must be one of the available options +# # in the Alert. +# string response diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiRequest.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiRequest.py new file mode 100644 index 000000000..b43562b97 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiRequest.py @@ -0,0 +1,27 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class ApiRequest(pydantic.BaseModel): + json_msg: str = "" # string + request_id: str = "" # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "json_msg", + "request_id", + ], + } + + +# +# # The JSON message that represents the request +# string json_msg +# +# # The unique ID assigned to this request +# string request_id diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiResponse.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiResponse.py new file mode 100644 index 000000000..ca557ba95 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiResponse.py @@ -0,0 +1,47 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class ApiResponse(pydantic.BaseModel): + type: pydantic.conint(ge=0, le=255) = 0 # uint8 + json_msg: str = "" # string + request_id: str = "" # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "type", + "json_msg", + "request_id", + ], + } + + +# +# # This response type means the message was not initialized correctly and will +# # result in an error +# uint8 TYPE_UNINITIALIZED = 0 +# +# # This response type means the request is being acknowledged which will grant it +# # some extra time before the API Node has its response timeout. This can be used +# # to extend the lifetime of a request which may take a long time to complete. +# # Each time an acknowledgment is sent the lifetime will be extended. +# uint8 TYPE_ACKNOWLEDGE = 1 +# +# # This response type means this message is responding to the request and +# # therefore fulfilling the request. +# uint8 TYPE_RESPONDING = 2 +# +# # The type of response this is: Acknowledging or Responding +# # (Uninitialized will result in the API Node issuing an error response) +# uint8 type +# +# # The JSON message that represents the response +# string json_msg +# +# # The unique ID of the request that this response is targeted at +# string request_id diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiService_Request.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiService_Request.py new file mode 100644 index 000000000..d471c84c1 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiService_Request.py @@ -0,0 +1,23 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class ApiService_Request(pydantic.BaseModel): + json_msg: str = "" # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "json_msg", + ], + } + + +# +# # The JSON message that represents the request +# string json_msg +# diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiService_Response.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiService_Response.py new file mode 100644 index 000000000..941f0f98f --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/ApiService_Response.py @@ -0,0 +1,23 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class ApiService_Response(pydantic.BaseModel): + json_msg: str = "" # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "json_msg", + ], + } + + +# +# +# # The JSON message that represents the response +# string json_msg diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/Assignment.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/Assignment.py new file mode 100644 index 000000000..38d05197d --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/Assignment.py @@ -0,0 +1,26 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + + +class Assignment(pydantic.BaseModel): + is_assigned: bool = False # bool + fleet_name: str = "" # string + expected_robot_name: str = "" # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "is_assigned", + "fleet_name", + "expected_robot_name", + ], + } + + +# bool is_assigned +# string fleet_name +# string expected_robot_name diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidNotice.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidNotice.py index d6e2eb08c..9a9921a87 100644 --- a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidNotice.py +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidNotice.py @@ -5,18 +5,19 @@ import pydantic from ..builtin_interfaces.Duration import Duration -from ..rmf_task_msgs.TaskProfile import TaskProfile class BidNotice(pydantic.BaseModel): - task_profile: TaskProfile = TaskProfile() # rmf_task_msgs/TaskProfile + request: str = "" # string + task_id: str = "" # string time_window: Duration = Duration() # builtin_interfaces/Duration class Config: orm_mode = True schema_extra = { "required": [ - "task_profile", + "request", + "task_id", "time_window", ], } @@ -27,8 +28,11 @@ class Config: # # Fleet Adapters may then submit a BidProposal message with their best proposal # # to accommodate the new task. # -# # Details of the new task -# TaskProfile task_profile +# # Details of the task request +# string request +# +# # The ID for this request +# string task_id # # # Duration for which the bidding is open # builtin_interfaces/Duration time_window diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidProposal.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidProposal.py index da0a392a7..e24ddbfb2 100644 --- a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidProposal.py +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidProposal.py @@ -5,27 +5,24 @@ import pydantic from ..builtin_interfaces.Time import Time -from ..rmf_task_msgs.TaskProfile import TaskProfile class BidProposal(pydantic.BaseModel): fleet_name: str = "" # string - task_profile: TaskProfile = TaskProfile() # rmf_task_msgs/TaskProfile + expected_robot_name: str = "" # string prev_cost: float = 0 # float64 new_cost: float = 0 # float64 finish_time: Time = Time() # builtin_interfaces/Time - robot_name: str = "" # string class Config: orm_mode = True schema_extra = { "required": [ "fleet_name", - "task_profile", + "expected_robot_name", "prev_cost", "new_cost", "finish_time", - "robot_name", ], } @@ -36,9 +33,8 @@ class Config: # # The name of the Fleet Adapter publishing this message # string fleet_name # -# # Details of the task to accommodate. This should math the TaskProfile in the -# # BidNotice -# TaskProfile task_profile +# # The name of the robot in the fleet which will potentially execute the task +# string expected_robot_name # # # The overall cost of task assignments prior to accommodating the new task # float64 prev_cost @@ -48,6 +44,3 @@ class Config: # # # The estimated finish time of the new task # builtin_interfaces/Time finish_time -# -# # The name of the robot in the fleet which will potentially execute the task -# string robot_name diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidResponse.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidResponse.py new file mode 100644 index 000000000..4fe0309e8 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/BidResponse.py @@ -0,0 +1,38 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..rmf_task_msgs.BidProposal import BidProposal + + +class BidResponse(pydantic.BaseModel): + task_id: str = "" # string + has_proposal: bool = False # bool + proposal: BidProposal = BidProposal() # rmf_task_msgs/BidProposal + errors: List[str] = [] # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "task_id", + "has_proposal", + "proposal", + "errors", + ], + } + + +# # ID of the task that is being bid on +# string task_id +# +# # True if this response contains a proposal +# bool has_proposal +# +# # The proposal of this response, if has_proposal is true +# BidProposal proposal +# +# # Any errors related to this bid +# string[] errors diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchAck.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchAck.py index 4482ef002..ad8dec587 100644 --- a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchAck.py +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchAck.py @@ -4,21 +4,19 @@ import pydantic -from ..rmf_task_msgs.DispatchRequest import DispatchRequest - class DispatchAck(pydantic.BaseModel): - dispatch_request: DispatchRequest = ( - DispatchRequest() - ) # rmf_task_msgs/DispatchRequest + dispatch_id: pydantic.conint(ge=0, le=18446744073709551615) = 0 # uint64 success: bool = False # bool + errors: List[str] = [] # string class Config: orm_mode = True schema_extra = { "required": [ - "dispatch_request", + "dispatch_id", "success", + "errors", ], } @@ -27,8 +25,10 @@ class Config: # # DispatchRequest message. It indicates whether the requested task addition or # # cancellation was successful. # -# # The DispatchRequest message received by the Fleet Adapter -# DispatchRequest dispatch_request +# # The ID of the DispatchRequest that is being responded to +# uint64 dispatch_id # # # True if the addition or cancellation operation was successful # bool success +# +# string[] errors diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchCommand.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchCommand.py new file mode 100644 index 000000000..c4051ef20 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchCommand.py @@ -0,0 +1,49 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..builtin_interfaces.Time import Time + + +class DispatchCommand(pydantic.BaseModel): + fleet_name: str = "" # string + task_id: str = "" # string + dispatch_id: pydantic.conint(ge=0, le=18446744073709551615) = 0 # uint64 + timestamp: Time = Time() # builtin_interfaces/Time + type: pydantic.conint(ge=0, le=255) = 0 # uint8 + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "fleet_name", + "task_id", + "dispatch_id", + "timestamp", + "type", + ], + } + + +# # This message is published by Task Dispatcher Node to either award or cancel a +# # task for a Fleet Adapter +# +# # The selected Fleet Adapter to award/cancel the task +# string fleet_name +# +# # The task_id of the task that +# string task_id +# +# # Unique ID of this request message +# uint64 dispatch_id +# +# # The time that this dispatch request was originally made. Dispatch requests may +# # expire with an error if they get no response after an extended period of time. +# builtin_interfaces/Time timestamp +# +# # Add or Cancel a task +# uint8 type +# uint8 TYPE_AWARD=1 # to award a task to a fleet +# uint8 TYPE_REMOVE=2 # to remove a task from a fleet diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchRequest.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchRequest.py deleted file mode 100644 index 0a5db1096..000000000 --- a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchRequest.py +++ /dev/null @@ -1,39 +0,0 @@ -# This is a generated file, do not edit - -from typing import List - -import pydantic - -from ..rmf_task_msgs.TaskProfile import TaskProfile - - -class DispatchRequest(pydantic.BaseModel): - fleet_name: str = "" # string - task_profile: TaskProfile = TaskProfile() # rmf_task_msgs/TaskProfile - method: pydantic.conint(ge=0, le=255) = 0 # uint8 - - class Config: - orm_mode = True - schema_extra = { - "required": [ - "fleet_name", - "task_profile", - "method", - ], - } - - -# # This message is published by Task Dispatcher Node to either award or cancel a -# # task for a Fleet Adapter -# -# # The selected Fleet Adapter to award/cancel the task -# string fleet_name -# -# # The details of the task to be awarded or cancelled. This should match the -# # TaskProfile in the corresponding BidNotice message -# TaskProfile task_profile -# -# # Add or Cancel a task -# uint8 method -# uint8 ADD=1 # to add a task -# uint8 CANCEL=2 # to cancel and remove a task diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchState.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchState.py new file mode 100644 index 000000000..3e790501e --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchState.py @@ -0,0 +1,39 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..rmf_task_msgs.Assignment import Assignment + + +class DispatchState(pydantic.BaseModel): + task_id: str = "" # string + status: pydantic.conint(ge=-128, le=127) = 0 # int8 + assignment: Assignment = Assignment() # rmf_task_msgs/Assignment + errors: List[str] = [] # string + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "task_id", + "status", + "assignment", + "errors", + ], + } + + +# +# uint8 STATUS_UNINITIALIZED = 0 +# uint8 STATUS_QUEUED = 1 +# uint8 STATUS_SELECTED = 2 +# uint8 STATUS_DISPATCHED = 3 +# uint8 STATUS_FAILED_TO_ASSIGN = 4 +# uint8 STATUS_CANCELED_IN_FLIGHT = 5 +# +# string task_id +# int8 status +# Assignment assignment +# string[] errors diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchStates.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchStates.py new file mode 100644 index 000000000..443ce69a7 --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/DispatchStates.py @@ -0,0 +1,30 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..rmf_task_msgs.DispatchState import DispatchState + + +class DispatchStates(pydantic.BaseModel): + active: List[DispatchState] = [] # rmf_task_msgs/DispatchState + finished: List[DispatchState] = [] # rmf_task_msgs/DispatchState + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "active", + "finished", + ], + } + + +# # States of tasks that are currently in the process of being dispatched +# DispatchState[] active +# +# # States of tasks that have recently finished being dispatched. This may mean +# # the task was assigned or it may mean it failed to be dispatched or was +# # canceled before the dispatch took place. +# DispatchState[] finished diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetTaskList_Request.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetDispatchStates_Request.py similarity index 57% rename from packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetTaskList_Request.py rename to packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetDispatchStates_Request.py index 492fb294f..272858792 100644 --- a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetTaskList_Request.py +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetDispatchStates_Request.py @@ -5,26 +5,21 @@ import pydantic -class GetTaskList_Request(pydantic.BaseModel): - requester: str = "" # string - task_id: List[str] = [] # string +class GetDispatchStates_Request(pydantic.BaseModel): + task_ids: List[str] = [] # string class Config: orm_mode = True schema_extra = { "required": [ - "requester", - "task_id", + "task_ids", ], } # # Query list of submitted tasks | Get service call # -# # Identifier for who is requesting the service -# string requester -# # # Input the generated task ID during submission # # if empty, provide all Submitted Tasks -# string[] task_id +# string[] task_ids # diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetDispatchStates_Response.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetDispatchStates_Response.py new file mode 100644 index 000000000..aa9d0026d --- /dev/null +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetDispatchStates_Response.py @@ -0,0 +1,28 @@ +# This is a generated file, do not edit + +from typing import List + +import pydantic + +from ..rmf_task_msgs.DispatchStates import DispatchStates + + +class GetDispatchStates_Response(pydantic.BaseModel): + success: bool = False # bool + states: DispatchStates = DispatchStates() # rmf_task_msgs/DispatchStates + + class Config: + orm_mode = True + schema_extra = { + "required": [ + "success", + "states", + ], + } + + +# +# +# bool success +# +# DispatchStates states diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetTaskList_Response.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetTaskList_Response.py deleted file mode 100644 index b5e796167..000000000 --- a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/GetTaskList_Response.py +++ /dev/null @@ -1,31 +0,0 @@ -# This is a generated file, do not edit - -from typing import List - -import pydantic - -from ..rmf_task_msgs.TaskSummary import TaskSummary - - -class GetTaskList_Response(pydantic.BaseModel): - success: bool = False # bool - active_tasks: List[TaskSummary] = [] # rmf_task_msgs/TaskSummary - terminated_tasks: List[TaskSummary] = [] # rmf_task_msgs/TaskSummary - - class Config: - orm_mode = True - schema_extra = { - "required": [ - "success", - "active_tasks", - "terminated_tasks", - ], - } - - -# -# -# bool success -# -# TaskSummary[] active_tasks -# TaskSummary[] terminated_tasks diff --git a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/__init__.py b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/__init__.py index e8786c2d9..aa3e2af03 100644 --- a/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/__init__.py +++ b/packages/api-server/api_server/models/ros_pydantic/rmf_task_msgs/__init__.py @@ -1,15 +1,26 @@ +from .Alert import Alert +from .AlertParameter import AlertParameter +from .AlertResponse import AlertResponse +from .ApiRequest import ApiRequest +from .ApiResponse import ApiResponse +from .ApiService_Request import ApiService_Request +from .ApiService_Response import ApiService_Response +from .Assignment import Assignment from .Behavior import Behavior from .BehaviorParameter import BehaviorParameter from .BidNotice import BidNotice from .BidProposal import BidProposal +from .BidResponse import BidResponse from .CancelTask_Request import CancelTask_Request from .CancelTask_Response import CancelTask_Response from .Clean import Clean from .Delivery import Delivery from .DispatchAck import DispatchAck -from .DispatchRequest import DispatchRequest -from .GetTaskList_Request import GetTaskList_Request -from .GetTaskList_Response import GetTaskList_Response +from .DispatchCommand import DispatchCommand +from .DispatchState import DispatchState +from .DispatchStates import DispatchStates +from .GetDispatchStates_Request import GetDispatchStates_Request +from .GetDispatchStates_Response import GetDispatchStates_Response from .Loop import Loop from .Priority import Priority from .ReviveTask_Request import ReviveTask_Request diff --git a/packages/api-server/api_server/models/ros_pydantic/version.py b/packages/api-server/api_server/models/ros_pydantic/version.py index a1ae792bd..16f07f254 100644 --- a/packages/api-server/api_server/models/ros_pydantic/version.py +++ b/packages/api-server/api_server/models/ros_pydantic/version.py @@ -1,5 +1,5 @@ # THIS FILE IS GENERATED version = { - "rmf_internal_msgs": "0c237e1758872917661879975d7dc0acf5fa518c", + "rmf_internal_msgs": "e3f2dc688dcba79d2def064bae542fa0cadfd4dc", "rmf_building_map_msgs": "c5e0352e2dfd3d11e4d292a1c2901cad867c1441", } diff --git a/packages/api-server/api_server/models/tortoise_models/alerts.py b/packages/api-server/api_server/models/tortoise_models/alerts.py index 0b04917d3..0ef129559 100644 --- a/packages/api-server/api_server/models/tortoise_models/alerts.py +++ b/packages/api-server/api_server/models/tortoise_models/alerts.py @@ -1,27 +1,28 @@ -from enum import Enum - -from tortoise.contrib.pydantic.creator import pydantic_model_creator -from tortoise.fields import BigIntField, CharEnumField, CharField +from tortoise.fields import ( + BooleanField, + CharField, + DatetimeField, + JSONField, + OneToOneField, + ReverseRelation, +) from tortoise.models import Model -class Alert(Model): - """ - General alert that can be triggered by events. - """ - - class Category(str, Enum): - Default = "default" - Task = "task" - Fleet = "fleet" - Robot = "robot" - +class AlertResponse(Model): id = CharField(255, pk=True) - original_id = CharField(255, index=True) - category = CharEnumField(Category, index=True) - unix_millis_created_time = BigIntField(null=False, index=True) - acknowledged_by = CharField(255, null=True, index=True) - unix_millis_acknowledged_time = BigIntField(null=True, index=True) + response_time = DatetimeField(null=False, index=True) + response = CharField(255, null=False, index=True) + data = JSONField() + alert_request = OneToOneField( + "models.AlertRequest", null=False, related_name="alert_response" + ) -AlertPydantic = pydantic_model_creator(Alert) +class AlertRequest(Model): + id = CharField(255, pk=True) + request_time = DatetimeField(null=False, index=True) + response_expected = BooleanField(null=False, index=True) + task_id = CharField(255, null=True, index=True) + data = JSONField() + alert_response = ReverseRelation["AlertResponse"] diff --git a/packages/api-server/api_server/repositories/alerts.py b/packages/api-server/api_server/repositories/alerts.py index 782a0586a..427e2582e 100644 --- a/packages/api-server/api_server/repositories/alerts.py +++ b/packages/api-server/api_server/repositories/alerts.py @@ -1,94 +1,89 @@ -import logging from datetime import datetime -from typing import List, Optional +from typing import List -from fastapi import Depends - -from api_server.authenticator import user_dep -from api_server.models import User +from api_server.exceptions import AlreadyExistsError, InvalidInputError, NotFoundError +from api_server.models import AlertRequest, AlertResponse, Pagination from api_server.models import tortoise_models as ttm -from api_server.repositories.tasks import TaskRepository class AlertRepository: - def __init__( - self, - user: User = Depends(user_dep), - task_repo: TaskRepository = Depends(TaskRepository), - ): - self.user = user - self.task_repo = task_repo + async def create_new_alert(self, alert: AlertRequest) -> AlertRequest: + exists = await ttm.AlertRequest.exists(id=alert.id) + if exists: + raise AlreadyExistsError(f"Alert with ID {alert.id} already exists") - async def get_all_alerts(self) -> List[ttm.AlertPydantic]: - alerts = await ttm.Alert.all() - return [await ttm.AlertPydantic.from_tortoise_orm(a) for a in alerts] + await ttm.AlertRequest.create( + id=alert.id, + request_time=datetime.fromtimestamp(alert.unix_millis_alert_time / 1000), + response_expected=(len(alert.responses_available) > 0), + task_id=alert.task_id, + data=alert.json(), + ) + return alert - async def alert_exists(self, alert_id: str) -> bool: - result = await ttm.Alert.exists(id=alert_id) - return result + async def get_alert(self, alert_id: str) -> AlertRequest: + alert = await ttm.AlertRequest.get_or_none(id=alert_id) + if alert is None: + raise NotFoundError(f"Alert with ID {alert_id} does not exists") - async def alert_original_id_exists(self, original_id: str) -> bool: - result = await ttm.Alert.exists(original_id=original_id) - return result + alert_model = AlertRequest.from_tortoise(alert) + return alert_model - async def get_alert(self, alert_id: str) -> Optional[ttm.AlertPydantic]: - alert = await ttm.Alert.get_or_none(id=alert_id) + async def create_response(self, alert_id: str, response: str) -> AlertResponse: + alert = await ttm.AlertRequest.get_or_none(id=alert_id) if alert is None: - logging.error(f"Alert with ID {alert_id} not found") - return None - alert_pydantic = await ttm.AlertPydantic.from_tortoise_orm(alert) - return alert_pydantic + raise NotFoundError(f"Alert with ID {alert_id} does not exists") - async def create_alert( - self, alert_id: str, category: str - ) -> Optional[ttm.AlertPydantic]: - alert, _ = await ttm.Alert.update_or_create( - { - "original_id": alert_id, - "category": category, - "unix_millis_created_time": round(datetime.now().timestamp() * 1e3), - "acknowledged_by": None, - "unix_millis_acknowledged_time": None, - }, + alert_model = AlertRequest.from_tortoise(alert) + if response not in alert_model.responses_available: + raise InvalidInputError( + f"Response [{response}] is not a response option of alert with ID {alert_model.id}" + ) + + alert_response_model = AlertResponse( id=alert_id, + unix_millis_response_time=round(datetime.now().timestamp() * 1000), + response=response, ) - if alert is None: - logging.error(f"Failed to create Alert with ID {alert_id}") - return None - alert_pydantic = await ttm.AlertPydantic.from_tortoise_orm(alert) - return alert_pydantic + await ttm.AlertResponse.create( + id=alert_id, + response_time=datetime.fromtimestamp( + alert_response_model.unix_millis_response_time / 1000 + ), + response=response, + data=alert_response_model.json(), + alert_request=alert, + ) + return alert_response_model - async def acknowledge_alert(self, alert_id: str) -> Optional[ttm.AlertPydantic]: - alert = await ttm.Alert.get_or_none(id=alert_id) - if alert is None: - acknowledged_alert = await ttm.Alert.filter(original_id=alert_id).first() - if acknowledged_alert is None: - logging.error(f"No existing or past alert with ID {alert_id} found.") - return None - acknowledged_alert_pydantic = await ttm.AlertPydantic.from_tortoise_orm( - acknowledged_alert + async def get_alert_response(self, alert_id: str) -> AlertResponse: + response = await ttm.AlertResponse.get_or_none(id=alert_id) + if response is None: + raise NotFoundError(f"Response to alert with ID {alert_id} does not exists") + + response_model = AlertResponse.from_tortoise(response) + return response_model + + async def get_alerts_of_task( + self, task_id: str, unresponded: bool = True + ) -> List[AlertRequest]: + if unresponded: + task_id_alerts = await ttm.AlertRequest.filter( + response_expected=True, + task_id=task_id, + alert_response=None, ) - return acknowledged_alert_pydantic + else: + task_id_alerts = await ttm.AlertRequest.filter(task_id=task_id) - ack_time = datetime.now() - epoch = datetime.utcfromtimestamp(0) - ack_unix_millis = round((ack_time - epoch).total_seconds() * 1000) - new_id = f"{alert_id}__{ack_unix_millis}" + alert_models = [AlertRequest.from_tortoise(alert) for alert in task_id_alerts] + return alert_models - ack_alert = alert.clone(pk=new_id) - # TODO(aaronchongth): remove the following line once we bump - # tortoise-orm to include - # https://github.com/tortoise/tortoise-orm/pull/1131. This is a - # temporary workaround. - ack_alert._custom_generated_pk = True # pylint: disable=W0212 - unix_millis_acknowledged_time = round(ack_time.timestamp() * 1e3) - ack_alert.update_from_dict( - { - "acknowledged_by": self.user.username, - "unix_millis_acknowledged_time": unix_millis_acknowledged_time, - } - ) - await ack_alert.save() - await alert.delete() - ack_alert_pydantic = await ttm.AlertPydantic.from_tortoise_orm(ack_alert) - return ack_alert_pydantic + async def get_unresponded_alerts( + self, pagination: Pagination | None + ) -> List[AlertRequest]: + query = ttm.AlertRequest.filter(alert_response=None, response_expected=True) + if pagination: + query = query.limit(pagination.limit).offset(pagination.offset) + unresponded_alerts = await query.all() + return [AlertRequest.from_tortoise(alert) for alert in unresponded_alerts] diff --git a/packages/api-server/api_server/repositories/tasks.py b/packages/api-server/api_server/repositories/tasks.py index f47b33453..5539652dd 100644 --- a/packages/api-server/api_server/repositories/tasks.py +++ b/packages/api-server/api_server/repositories/tasks.py @@ -1,4 +1,3 @@ -import sys from datetime import datetime from typing import Dict, List, Optional, Sequence, Tuple, cast @@ -21,11 +20,8 @@ User, ) from api_server.models import tortoise_models as ttm -from api_server.models.rmf_api.log_entry import Tier -from api_server.models.rmf_api.task_state import Category, Id, Phase from api_server.models.tortoise_models import TaskRequest as DbTaskRequest from api_server.models.tortoise_models import TaskState as DbTaskState -from api_server.rmf_io import task_events class TaskRepository: @@ -327,61 +323,6 @@ async def _saveTaskLogs( text=log.text, ) - async def save_log_acknowledged_task_completion( - self, - task_id: str, - acknowledged_by: str, - unix_millis_acknowledged_time: int, - action: str = "Task completion", - ) -> None: - async with in_transaction(): - task_logs = await self.get_task_log(task_id, (0, sys.maxsize)) - task_state = await self.get_task_state(task_id=task_id) - # A try could be used here to avoid using so many "ands" - # but the configured lint suggests comparing that no value is None - if task_logs and task_state and task_logs.phases and task_state.phases: - # The next phase key value matches in both `task_logs` and `task_state`. - # It is the same whether it is obtained from `task_logs` or from `task_state`. - # In this case, it is obtained from `task_logs` and is also used to assign the next - # phase in `task_state`. - next_phase_key = str(int(list(task_logs.phases)[-1]) + 1) - else: - raise ValueError("Phases can't be null") - - event = LogEntry( - seq=0, - tier=Tier.warning, - unix_millis_time=unix_millis_acknowledged_time, - text=f"{action} acknowledged by {acknowledged_by}", - ) - task_logs.phases = { - **task_logs.phases, - next_phase_key: Phases(log=[], events={"0": [event]}), - } - - await self.save_task_log(task_logs) - - task_state.phases = { - **task_state.phases, - next_phase_key: Phase( - id=Id(__root__=next_phase_key), - category=Category(__root__="Task completed"), - detail=None, - unix_millis_start_time=None, - unix_millis_finish_time=None, - original_estimate_millis=None, - estimate_millis=None, - final_event_id=None, - events=None, - skip_requests=None, - ), - } - - await self.save_task_state(task_state) - # Notifies observers of the next task_state value to correctly display the title of the - # logs when acknowledged by a user without reloading the page. - task_events.task_states.on_next(task_state) - async def save_task_log(self, task_log: TaskEventLog) -> None: async with in_transaction(): db_task_log = ( diff --git a/packages/api-server/api_server/rmf_io/book_keeper.py b/packages/api-server/api_server/rmf_io/book_keeper.py index ff98e0987..bc9da35d4 100644 --- a/packages/api-server/api_server/rmf_io/book_keeper.py +++ b/packages/api-server/api_server/rmf_io/book_keeper.py @@ -7,6 +7,8 @@ from rx.subject.subject import Subject from api_server.models import ( + AlertRequest, + AlertResponse, BeaconState, BuildingMap, DispenserHealth, @@ -21,7 +23,7 @@ ) from api_server.models.health import BaseBasicHealth -from .events import RmfEvents +from .events import AlertEvents, RmfEvents class RmfBookKeeperEvents: @@ -33,8 +35,10 @@ class RmfBookKeeper: def __init__( self, rmf_events: RmfEvents, + alert_events: AlertEvents, ): - self.rmf = rmf_events + self.rmf_events = rmf_events + self.alert_events = alert_events self.bookkeeper_events = RmfBookKeeperEvents() self._loop: asyncio.AbstractEventLoop self._pending_tasks = set() @@ -52,6 +56,8 @@ async def start(self): self._record_dispenser_health() self._record_ingestor_state() self._record_ingestor_health() + self._record_alert_request() + self._record_alert_response() async def stop(self): for sub in self._subscriptions: @@ -81,7 +87,7 @@ async def update(beacon_state: BeaconState): logging.debug(json.dumps(beacon_state.dict())) self._subscriptions.append( - self.rmf.beacons.subscribe(lambda x: self._create_task(update(x))) + self.rmf_events.beacons.subscribe(lambda x: self._create_task(update(x))) ) def _record_building_map(self): @@ -92,7 +98,9 @@ async def update(building_map: BuildingMap): logging.debug(json.dumps(building_map.dict())) self._subscriptions.append( - self.rmf.building_map.subscribe(lambda x: self._create_task(update(x))) + self.rmf_events.building_map.subscribe( + lambda x: self._create_task(update(x)) + ) ) def _record_door_state(self): @@ -101,7 +109,9 @@ async def update(door_state: DoorState): logging.debug(json.dumps(door_state.dict())) self._subscriptions.append( - self.rmf.door_states.subscribe(lambda x: self._create_task(update(x))) + self.rmf_events.door_states.subscribe( + lambda x: self._create_task(update(x)) + ) ) def _record_door_health(self): @@ -110,7 +120,9 @@ async def update(health: DoorHealth): self._report_health(health) self._subscriptions.append( - self.rmf.door_health.subscribe(lambda x: self._create_task(update(x))) + self.rmf_events.door_health.subscribe( + lambda x: self._create_task(update(x)) + ) ) def _record_lift_state(self): @@ -119,7 +131,9 @@ async def update(lift_state: LiftState): logging.debug(lift_state.json()) self._subscriptions.append( - self.rmf.lift_states.subscribe(lambda x: self._create_task(update(x))) + self.rmf_events.lift_states.subscribe( + lambda x: self._create_task(update(x)) + ) ) def _record_lift_health(self): @@ -128,7 +142,9 @@ async def update(health: LiftHealth): self._report_health(health) self._subscriptions.append( - self.rmf.lift_health.subscribe(lambda x: self._create_task(update(x))) + self.rmf_events.lift_health.subscribe( + lambda x: self._create_task(update(x)) + ) ) def _record_dispenser_state(self): @@ -137,7 +153,9 @@ async def update(dispenser_state: DispenserState): logging.debug(dispenser_state.json()) self._subscriptions.append( - self.rmf.dispenser_states.subscribe(lambda x: self._create_task(update(x))) + self.rmf_events.dispenser_states.subscribe( + lambda x: self._create_task(update(x)) + ) ) def _record_dispenser_health(self): @@ -146,7 +164,9 @@ async def update(health: DispenserHealth): self._report_health(health) self._subscriptions.append( - self.rmf.dispenser_health.subscribe(lambda x: self._create_task(update(x))) + self.rmf_events.dispenser_health.subscribe( + lambda x: self._create_task(update(x)) + ) ) def _record_ingestor_state(self): @@ -155,7 +175,9 @@ async def update(ingestor_state: IngestorState): logging.debug(ingestor_state.json()) self._subscriptions.append( - self.rmf.ingestor_states.subscribe(lambda x: self._create_task(update(x))) + self.rmf_events.ingestor_states.subscribe( + lambda x: self._create_task(update(x)) + ) ) def _record_ingestor_health(self): @@ -164,5 +186,29 @@ async def update(health: IngestorHealth): self._report_health(health) self._subscriptions.append( - self.rmf.ingestor_health.subscribe(lambda x: self._create_task(update(x))) + self.rmf_events.ingestor_health.subscribe( + lambda x: self._create_task(update(x)) + ) + ) + + def _record_alert_request(self): + async def update(alert_request: AlertRequest): + await alert_request.save() + logging.debug(json.dumps(alert_request.dict())) + + self._subscriptions.append( + self.alert_events.alert_requests.subscribe( + lambda x: self._create_task(update(x)) + ) + ) + + def _record_alert_response(self): + async def update(alert_response: AlertResponse): + await alert_response.save() + logging.debug(json.dumps(alert_response.dict())) + + self._subscriptions.append( + self.alert_events.alert_responses.subscribe( + lambda x: self._create_task(update(x)) + ) ) diff --git a/packages/api-server/api_server/rmf_io/events.py b/packages/api-server/api_server/rmf_io/events.py index 97128188b..44b3d394a 100644 --- a/packages/api-server/api_server/rmf_io/events.py +++ b/packages/api-server/api_server/rmf_io/events.py @@ -46,7 +46,8 @@ def __init__(self): class AlertEvents: def __init__(self): - self.alerts = Subject() # Alert + self.alert_requests = Subject() # AlertRequest + self.alert_responses = Subject() # AlertResponse alert_events = AlertEvents() diff --git a/packages/api-server/api_server/routes/alerts.py b/packages/api-server/api_server/routes/alerts.py index 22a90a335..0bc990682 100644 --- a/packages/api-server/api_server/routes/alerts.py +++ b/packages/api-server/api_server/routes/alerts.py @@ -1,50 +1,118 @@ -from typing import List +from typing import List, Optional from fastapi import Depends, HTTPException -from rx import operators as rxops +from tortoise.exceptions import IntegrityError +from api_server.exceptions import AlreadyExistsError, InvalidInputError, NotFoundError from api_server.fast_io import FastIORouter, SubscriptionRequest -from api_server.models import tortoise_models as ttm +from api_server.gateway import rmf_gateway +from api_server.models import AlertRequest, AlertResponse, Pagination from api_server.repositories import AlertRepository from api_server.rmf_io import alert_events router = FastIORouter(tags=["Alerts"]) -@router.sub("", response_model=ttm.AlertPydantic) +@router.sub("/requests", response_model=AlertRequest) async def sub_alerts(_req: SubscriptionRequest): - return alert_events.alerts.pipe(rxops.filter(lambda x: x is not None)) + return alert_events.alert_requests -@router.get("", response_model=List[ttm.AlertPydantic]) -async def get_alerts(repo: AlertRepository = Depends(AlertRepository)): - return await repo.get_all_alerts() +@router.post("/request", status_code=201, response_model=AlertRequest) +async def create_new_alert( + alert: AlertRequest, repo: AlertRepository = Depends(AlertRepository) +): + """ + Creates a new alert. + """ + try: + created_alert = await repo.create_new_alert(alert) + except IntegrityError as e: + raise HTTPException(400, e) from e + except AlreadyExistsError as e: + raise HTTPException(409, str(e)) from e + + alert_events.alert_requests.on_next(created_alert) + return created_alert -@router.get("/{alert_id}", response_model=ttm.AlertPydantic) +@router.get("/request/{alert_id}", response_model=AlertRequest) async def get_alert(alert_id: str, repo: AlertRepository = Depends(AlertRepository)): - alert = await repo.get_alert(alert_id) - if alert is None: - raise HTTPException(404, f"Alert with ID {alert_id} not found") - return alert + """ + Gets an alert based on the alert ID. + """ + try: + alert_model = await repo.get_alert(alert_id) + except NotFoundError as e: + raise HTTPException(404, str(e)) from e + + return alert_model + +@router.sub("/responses", response_model=AlertResponse) +async def sub_alert_responses(_req: SubscriptionRequest): + return alert_events.alert_responses -@router.post("", status_code=201, response_model=ttm.AlertPydantic) -async def create_alert( - alert_id: str, category: str, repo: AlertRepository = Depends(AlertRepository) + +@router.post( + "/request/{alert_id}/respond", status_code=201, response_model=AlertResponse +) +async def respond_to_alert( + alert_id: str, response: str, repo: AlertRepository = Depends(AlertRepository) ): - alert = await repo.create_alert(alert_id, category) - if alert is None: - raise HTTPException(404, f"Could not create alert with ID {alert_id}") - return alert + """ + Responds to an existing alert. The response must be one of the available + responses listed in the alert. + """ + try: + alert_response_model = await repo.create_response(alert_id, response) + except IntegrityError as e: + raise HTTPException(400, e) from e + except NotFoundError as e: + raise HTTPException(404, str(e)) from e + except InvalidInputError as e: + raise HTTPException(400, str(e)) from e + + alert_events.alert_responses.on_next(alert_response_model) + rmf_gateway().respond_to_alert(alert_id, response) + return alert_response_model -@router.post("/{alert_id}", status_code=201, response_model=ttm.AlertPydantic) -async def acknowledge_alert( +@router.get("/request/{alert_id}/response", response_model=AlertResponse) +async def get_alert_response( alert_id: str, repo: AlertRepository = Depends(AlertRepository) ): - alert = await repo.acknowledge_alert(alert_id) - if alert is None: - raise HTTPException(404, f"Could acknowledge alert with ID {alert_id}") - alert_events.alerts.on_next(alert) - return alert + """ + Gets the response to the alert based on the alert ID. + """ + try: + response_model = await repo.get_alert_response(alert_id) + except NotFoundError as e: + raise HTTPException(404, str(e)) from e + + return response_model + + +@router.get("/requests/task/{task_id}", response_model=List[AlertRequest]) +async def get_alerts_of_task( + task_id: str, + unresponded: bool = True, + repo: AlertRepository = Depends(AlertRepository), +): + """ + Returns all the alerts associated to a task ID. Provides the option to only + return alerts that have not been responded to yet. + """ + return await repo.get_alerts_of_task(task_id, unresponded) + + +@router.get("/unresponded_requests", response_model=List[AlertRequest]) +async def get_unresponded_alerts( + repo: AlertRepository = Depends(AlertRepository), + pagination: Optional[Pagination] = None, +): + """ + Returns the list of alert IDs that have yet to be responded to, while a + response was required. + """ + return await repo.get_unresponded_alerts(pagination) diff --git a/packages/api-server/api_server/routes/internal.py b/packages/api-server/api_server/routes/internal.py index cca37fbc7..a6c098147 100644 --- a/packages/api-server/api_server/routes/internal.py +++ b/packages/api-server/api_server/routes/internal.py @@ -1,13 +1,16 @@ # NOTE: This will eventually replace `gateway.py`` import logging import os +from datetime import datetime from typing import Any, Dict +from uuid import uuid4 from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect from websockets.exceptions import ConnectionClosed from api_server import models as mdl from api_server.app_config import app_config +from api_server.exceptions import AlreadyExistsError from api_server.logging import LoggerAdapter, get_logger from api_server.repositories import AlertRepository, FleetRepository, TaskRepository from api_server.rmf_io import alert_events, fleet_events, task_events @@ -49,37 +52,11 @@ def disconnect(self, websocket: WebSocket): connection_manager = ConnectionManager() -def log_phase_has_error(phase: mdl.Phases) -> bool: - if phase.log: - for log in phase.log: - if log.tier == mdl.Tier.error: - return True - if phase.events: - for _, event_logs in phase.events.items(): - for event_log in event_logs: - if event_log.tier == mdl.Tier.error: - return True - return False - - -def task_log_has_error(task_log: mdl.TaskEventLog) -> bool: - if task_log.log: - for log in task_log.log: - if log.tier == mdl.Tier.error: - return True - - if task_log.phases: - for _, phase in task_log.phases.items(): - if log_phase_has_error(phase): - return True - return False - - async def process_msg( msg: Dict[str, Any], + alert_repo: AlertRepository, fleet_repo: FleetRepository, task_repo: TaskRepository, - alert_repo: AlertRepository, logger: LoggerAdapter, ) -> None: if "type" not in msg: @@ -97,24 +74,60 @@ async def process_msg( await task_repo.save_task_state(task_state) task_events.task_states.on_next(task_state) - if ( - task_state.status == mdl.Status.completed - or task_state.status == mdl.Status.failed - ): - alert = await alert_repo.create_alert(task_state.booking.id, "task") - if alert is not None: - alert_events.alerts.on_next(alert) + if task_state.status == mdl.Status.completed: + alert_request = mdl.AlertRequest( + id=str(uuid4()), + unix_millis_alert_time=round(datetime.now().timestamp() * 1000), + title="Task completed", + subtitle=f"ID: {task_state.booking.id}", + message="", + display=True, + tier=mdl.AlertRequest.Tier.Info, + responses_available=["Acknowledge"], + alert_parameters=[], + task_id=task_state.booking.id, + ) + try: + created_alert = await alert_repo.create_new_alert(alert_request) + except AlreadyExistsError as e: + logger.error(e) + return + alert_events.alert_requests.on_next(created_alert) + elif task_state.status == mdl.Status.failed: + errorMessage = "" + if ( + task_state.dispatch is not None + and task_state.dispatch.status == mdl.DispatchStatus.failed_to_assign + ): + errorMessage += "Failed to assign\n" + if task_state.dispatch.errors is not None: + for error in task_state.dispatch.errors: + errorMessage += error.json() + "\n" + + alert_request = mdl.AlertRequest( + id=str(uuid4()), + unix_millis_alert_time=round(datetime.now().timestamp() * 1000), + title="Task failed", + subtitle=f"ID: {task_state.booking.id}", + message=errorMessage, + display=True, + tier=mdl.AlertRequest.Tier.Error, + responses_available=["Acknowledge"], + alert_parameters=[], + task_id=task_state.booking.id, + ) + try: + created_alert = await alert_repo.create_new_alert(alert_request) + except AlreadyExistsError as e: + logger.error(e) + return + alert_events.alert_requests.on_next(created_alert) elif payload_type == "task_log_update": task_log = mdl.TaskEventLog(**msg["data"]) await task_repo.save_task_log(task_log) task_events.task_event_logs.on_next(task_log) - if task_log_has_error(task_log): - alert = await alert_repo.create_alert(task_log.task_id, "task") - if alert is not None: - alert_events.alerts.on_next(alert) - elif payload_type == "fleet_state_update": fleet_state = mdl.FleetState(**msg["data"]) await fleet_repo.save_fleet_state(fleet_state) @@ -132,13 +145,13 @@ async def rmf_gateway( logger: LoggerAdapter = Depends(get_logger), ): await connection_manager.connect(websocket) + alert_repo = AlertRepository() fleet_repo = FleetRepository(user, logger) task_repo = TaskRepository(user, logger) - alert_repo = AlertRepository(user, task_repo) try: while True: msg: Dict[str, Any] = await websocket.receive_json() - await process_msg(msg, fleet_repo, task_repo, alert_repo, logger) + await process_msg(msg, alert_repo, fleet_repo, task_repo, logger) except (WebSocketDisconnect, ConnectionClosed): connection_manager.disconnect(websocket) logger.warning("Client websocket disconnected") diff --git a/packages/api-server/api_server/routes/test_alerts.py b/packages/api-server/api_server/routes/test_alerts.py new file mode 100644 index 000000000..af855ef82 --- /dev/null +++ b/packages/api-server/api_server/routes/test_alerts.py @@ -0,0 +1,226 @@ +from urllib.parse import urlencode +from uuid import uuid4 + +from api_server import models as mdl +from api_server.test import AppFixture, make_alert_request + + +class TestAlertsRoute(AppFixture): + @classmethod + def setUpClass(cls): + super().setUpClass() + + def test_create_new_alert(self): + alert_id = str(uuid4()) + alert = make_alert_request(alert_id=alert_id, responses=["resume", "cancel"]) + resp = self.client.post("/alerts/request", data=alert.json(exclude_none=True)) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(alert, resp.json(), resp.content) + + # repeated creation with same ID will fail + alert = make_alert_request(alert_id=alert_id, responses=["resume", "cancel"]) + resp = self.client.post("/alerts/request", data=alert.json(exclude_none=True)) + self.assertEqual(409, resp.status_code, resp.content) + + def respond_to_alert(self): + alert_id = str(uuid4()) + alert = make_alert_request(alert_id=alert_id, responses=["resume", "cancel"]) + resp = self.client.post("/alerts/request", data=alert.json(exclude_none=True)) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(alert, resp.json(), resp.content) + + # respond to alert that does not exist + params = {"response": "resume"} + resp = self.client.post( + f"/alerts/request/wrong_alert/respond?{urlencode(params)}" + ) + self.assertEqual(422, resp.status_code, resp.content) + + # response that is unavailable + params = {"response": "wrong"} + resp = self.client.post(f"/alerts/{alert_id}/respond?{urlencode(params)}") + self.assertEqual(422, resp.status_code, resp.content) + + # respond correctly + response = "resume" + params = {"response": response} + resp = self.client.post( + f"/alerts/request/{alert_id}/respond?{urlencode(params)}" + ) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(id, resp.json()["id"], resp.content) + self.assertEqual(response, resp.json()["response"], resp.content) + + def test_get_alert(self): + alert_id = str(uuid4()) + + # alert does not exist + resp = self.client.get(f"/alerts/request/{alert_id}") + self.assertEqual(404, resp.status_code, resp.content) + + # create alert + alert = make_alert_request(alert_id=alert_id, responses=["resume", "cancel"]) + resp = self.client.post("/alerts/request", data=alert.json(exclude_none=True)) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(alert, resp.json(), resp.content) + + # alert exists now + resp = self.client.get(f"/alerts/request/{alert_id}") + self.assertEqual(200, resp.status_code, resp.content) + self.assertEqual(alert, resp.json(), resp.content) + + def test_get_alert_response(self): + alert_id = str(uuid4()) + alert = make_alert_request(alert_id=alert_id, responses=["resume", "cancel"]) + resp = self.client.post("/alerts/request", data=alert.json(exclude_none=True)) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(alert, resp.json(), resp.content) + + # respond + response = "resume" + params = {"response": response} + resp = self.client.post( + f"/alerts/request/{alert_id}/respond?{urlencode(params)}" + ) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(alert_id, resp.json()["id"], resp.content) + self.assertEqual(response, resp.json()["response"], resp.content) + + # response exists + resp = self.client.get(f"/alerts/request/{alert_id}/response") + self.assertEqual(200, resp.status_code, resp.content) + self.assertEqual(alert_id, resp.json()["id"], resp.content) + self.assertEqual(response, resp.json()["response"], resp.content) + + def test_sub_alert(self): + alert_id = str(uuid4()) + alert = make_alert_request(alert_id=alert_id, responses=["resume", "cancel"]) + + # check subscribed alert + with self.subscribe_sio("/alerts/requests") as sub: + resp = self.client.post( + "/alerts/request", data=alert.json(exclude_none=True) + ) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(alert, resp.json(), resp.content) + + subbed_alert = mdl.AlertRequest(**next(sub)) + self.assertEqual(subbed_alert, alert, subbed_alert) + + def test_sub_alert_response(self): + alert_id = str(uuid4()) + alert = make_alert_request(alert_id=alert_id, responses=["resume", "cancel"]) + resp = self.client.post("/alerts/request", data=alert.json(exclude_none=True)) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(alert, resp.json(), resp.content) + + # respond + response = "resume" + params = {"response": response} + with self.subscribe_sio("/alerts/responses") as sub: + resp = self.client.post( + f"/alerts/request/{alert_id}/respond?{urlencode(params)}" + ) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(alert_id, resp.json()["id"], resp.content) + self.assertEqual(response, resp.json()["response"], resp.content) + + # check subscribed alert response + subbed_alert_response = mdl.AlertResponse(**next(sub)) + self.assertEqual(subbed_alert_response, resp.json(), subbed_alert_response) + + def test_get_alerts_of_task(self): + alert_id = str(uuid4()) + alert = make_alert_request(alert_id=alert_id, responses=["resume", "cancel"]) + alert.task_id = "test_task_id" + resp = self.client.post("/alerts/request", data=alert.json(exclude_none=True)) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(alert, resp.json(), resp.content) + + # check for non-existent alert for a wrong task ID + resp = self.client.get("/alerts/requests/task/wrong_task_id") + self.assertEqual(200, resp.status_code, resp.content) + self.assertEqual(0, len(resp.json()), resp.content) + + # check for correct task ID + resp = self.client.get(f"/alerts/requests/task/{alert.task_id}") + self.assertEqual(200, resp.status_code, resp.content) + self.assertEqual(1, len(resp.json()), resp.content) + self.assertEqual(resp.json()[0], alert, resp.content) + + # respond to alert + response = "resume" + params = {"response": response} + resp = self.client.post( + f"/alerts/request/{alert_id}/respond?{urlencode(params)}" + ) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(alert_id, resp.json()["id"], resp.content) + self.assertEqual(response, resp.json()["response"], resp.content) + + # check for alert of correct task ID again (will only return + # unresponded by default) + resp = self.client.get(f"/alerts/requests/task/{alert.task_id}") + self.assertEqual(200, resp.status_code, resp.content) + self.assertEqual(0, len(resp.json()), resp.content) + + # check for alert of correct task ID again with unresponded False + params = {"unresponded": False} + resp = self.client.get( + f"/alerts/requests/task/{alert.task_id}?{urlencode(params)}" + ) + self.assertEqual(200, resp.status_code, resp.content) + self.assertEqual(1, len(resp.json()), resp.content) + self.assertEqual(resp.json()[0], alert, resp.content) + + def test_get_unresponded_alert_ids(self): + first_id = str(uuid4()) + first_alert = make_alert_request( + alert_id=first_id, responses=["resume", "cancel"] + ) + resp = self.client.post( + "/alerts/request", data=first_alert.json(exclude_none=True) + ) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(first_alert, resp.json(), resp.content) + + second_id = str(uuid4()) + second_alert = make_alert_request( + alert_id=second_id, responses=["resume", "cancel"] + ) + resp = self.client.post( + "/alerts/request", data=second_alert.json(exclude_none=True) + ) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(second_alert, resp.json(), resp.content) + + # both alerts unresponded + resp = self.client.get("/alerts/unresponded_requests") + self.assertEqual(200, resp.status_code, resp.content) + unresponded_num = len(resp.json()) + self.assertTrue(unresponded_num > 0, resp.content) + returned_alerts = resp.json() + returned_alert_ids = [a["id"] for a in returned_alerts] + self.assertTrue(first_id in returned_alert_ids) + self.assertTrue(second_id in returned_alert_ids) + + # respond to first + response = "resume" + params = {"response": response} + resp = self.client.post( + f"/alerts/request/{first_id}/respond?{urlencode(params)}" + ) + self.assertEqual(201, resp.status_code, resp.content) + self.assertEqual(first_id, resp.json()["id"], resp.content) + self.assertEqual(response, resp.json()["response"], resp.content) + + # first is no longer returned + resp = self.client.get("/alerts/unresponded_requests") + self.assertEqual(200, resp.status_code, resp.content) + new_unresponded_num = len(resp.json()) + self.assertTrue(new_unresponded_num > 0, resp.content) + self.assertTrue(unresponded_num - new_unresponded_num == 1, resp.content) + returned_alerts = resp.json() + returned_alert_ids = [a["id"] for a in returned_alerts] + self.assertTrue(first_id not in returned_alert_ids) + self.assertTrue(second_id in returned_alert_ids) diff --git a/packages/api-server/api_server/test/test_data.py b/packages/api-server/api_server/test/test_data.py index 3a1970c5c..f3690af0b 100644 --- a/packages/api-server/api_server/test/test_data.py +++ b/packages/api-server/api_server/test/test_data.py @@ -1,5 +1,5 @@ import json -from typing import Optional +from typing import List, Optional from uuid import uuid4 from rmf_building_map_msgs.msg import Door as RmfDoor @@ -10,6 +10,7 @@ from api_server.models import ( AffineImage, + AlertRequest, BuildingMap, DispenserState, Door, @@ -743,3 +744,18 @@ def make_task_log(task_id: str) -> TaskEventLog: ) sample.task_id = task_id return sample + + +def make_alert_request(alert_id: str, responses: List[str]) -> AlertRequest: + return AlertRequest( + id=alert_id, + unix_millis_alert_time=0, + title="test_title", + subtitle="test_subtitle", + message="test_message", + display=True, + tier=AlertRequest.Tier.Info, + responses_available=responses, + alert_parameters=[], + task_id=None, + ) diff --git a/packages/api-server/generate-models.sh b/packages/api-server/generate-models.sh index 81305ed57..0e1edc6f7 100755 --- a/packages/api-server/generate-models.sh +++ b/packages/api-server/generate-models.sh @@ -3,7 +3,7 @@ set -e shopt -s globstar RMF_BUILDING_MAP_MSGS_VER=c5e0352e2dfd3d11e4d292a1c2901cad867c1441 -RMF_INTERNAL_MSGS_VER=3690a47055ef45466cf970587d8b8e09df1a8825 +RMF_INTERNAL_MSGS_VER=e3f2dc688dcba79d2def064bae542fa0cadfd4dc RMF_API_MSGS_VER=255c22de9b920540dcac6ce67c3c902403de8092 RMF_ROS2_VER=bf038461b5b0fb7d4594461a724bc9e5e7cb97c6 CODEGEN_VER=$(pipenv run datamodel-codegen --version) diff --git a/packages/dashboard/src/components/alert-manager.tsx b/packages/dashboard/src/components/alert-manager.tsx new file mode 100644 index 000000000..b63a4ce30 --- /dev/null +++ b/packages/dashboard/src/components/alert-manager.tsx @@ -0,0 +1,361 @@ +import { + AlertRequest, + ApiServerModelsAlertsAlertRequestTier, + LogEntry, + TaskEventLog, + ApiServerModelsRmfApiLogEntryTier as LogEntryTier, +} from 'api-client'; +import { AppEvents } from './app-events'; +import { + Button, + Dialog, + DialogActions, + DialogTitle, + TextField, + Theme, + Divider, + useMediaQuery, + DialogContent, +} from '@mui/material'; +import { makeStyles, createStyles } from '@mui/styles'; +import React from 'react'; +import { base } from 'react-components'; +import { AppControllerContext } from './app-contexts'; +import { RmfAppContext } from './rmf-app'; +import { Subscription } from 'rxjs'; +import { TaskCancelButton } from './tasks/task-cancellation'; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + textField: { + background: theme.palette.background.default, + '&:hover': { + backgroundColor: theme.palette.background.default, + }, + }, + }), +); + +interface AlertDialogProps { + alertRequest: AlertRequest; + onDismiss: () => void; +} + +const AlertDialog = React.memo((props: AlertDialogProps) => { + const { alertRequest, onDismiss } = props; + const classes = useStyles(); + const [isOpen, setIsOpen] = React.useState(true); + const { showAlert } = React.useContext(AppControllerContext); + const rmf = React.useContext(RmfAppContext); + const isScreenHeightLessThan800 = useMediaQuery('(max-height:800px)'); + const [additionalAlertMessage, setAdditionalAlertMessage] = React.useState(null); + + const respondToAlert = async (alert_id: string, response: string) => { + if (!rmf) { + return; + } + + try { + const resp = ( + await rmf.alertsApi.respondToAlertAlertsRequestAlertIdRespondPost(alert_id, response) + ).data; + console.log( + `Alert [${alertRequest.id}]: responded with [${resp.response}] at ${resp.unix_millis_response_time}`, + ); + } catch (e) { + const errorMessage = `Failed to respond [${response}] to alert ID [${alertRequest.id}], ${ + (e as Error).message + }`; + console.error(errorMessage); + showAlert('error', errorMessage); + return; + } + + const successMessage = `Responded [${response}] to alert ID [${alertRequest.id}]`; + console.log(successMessage); + showAlert('success', successMessage); + }; + + const getErrorLogEntries = (logs: TaskEventLog) => { + let errorLogs: LogEntry[] = []; + if (logs.log) { + errorLogs.concat(logs.log.filter((entry) => entry.tier === LogEntryTier.Error)); + } + + if (logs.phases) { + for (let phase of Object.values(logs.phases)) { + if (phase.log) { + errorLogs.concat(phase.log.filter((entry) => entry.tier === LogEntryTier.Error)); + } + if (phase.events) { + for (let eventLogs of Object.values(phase.events)) { + errorLogs.concat(eventLogs.filter((entry) => entry.tier === LogEntryTier.Error)); + } + } + } + } + return errorLogs; + }; + + React.useEffect(() => { + if (alertRequest.tier === ApiServerModelsAlertsAlertRequestTier.Info || !alertRequest.task_id) { + return; + } + if (!rmf) { + return; + } + + (async () => { + if (!alertRequest.task_id) { + return; + } + + let logs: TaskEventLog | null = null; + try { + logs = ( + await rmf.tasksApi.getTaskLogTasksTaskIdLogGet( + alertRequest.task_id, + `0,${Number.MAX_SAFE_INTEGER}`, + ) + ).data; + } catch { + console.log( + `Failed to fetch task [${alertRequest.task_id}] logs for alert [${alertRequest.id}]`, + ); + } + const errorLogEntries = logs ? getErrorLogEntries(logs) : []; + + let consolidatedErrorMessages = ''; + for (const entry of errorLogEntries) { + consolidatedErrorMessages += `${new Date(entry.unix_millis_time).toLocaleString()} - ${ + entry.text + }\n`; + } + if (consolidatedErrorMessages.length > 0) { + setAdditionalAlertMessage(consolidatedErrorMessages); + } + })(); + }, [rmf, alertRequest.id, alertRequest.task_id, alertRequest.tier]); + + return ( + + + {alertRequest.title.length > 0 ? alertRequest.title : 'n/a'} + + + + 0 ? alertRequest.subtitle : 'n/a'} + /> + {(alertRequest.message.length > 0 || additionalAlertMessage !== null) && ( + 0 ? alertRequest.message : 'n/a') + + '\n' + + (additionalAlertMessage ?? '') + } + /> + )} + + + {alertRequest.responses_available.map((response) => { + return ( + + ); + })} + {alertRequest.task_id ? ( + + ) : null} + + + + ); +}); + +export const AlertManager = React.memo(() => { + const rmf = React.useContext(RmfAppContext); + const [openAlerts, setOpenAlerts] = React.useState>({}); + + React.useEffect(() => { + if (!rmf) { + return; + } + + const pushAlertsToBeDisplayed = async (alertRequest: AlertRequest) => { + if (!rmf) { + console.error('Alerts API not available'); + return; + } + if (!alertRequest.display) { + setOpenAlerts((prev) => { + const filteredAlerts = Object.fromEntries( + Object.entries(prev).filter(([key]) => key !== alertRequest.id), + ); + return filteredAlerts; + }); + return; + } + + try { + const resp = ( + await rmf.alertsApi.getAlertResponseAlertsRequestAlertIdResponseGet(alertRequest.id) + ).data; + console.log( + `Alert [${alertRequest.id}]: was responded with [${resp.response}] at ${resp.unix_millis_response_time}`, + ); + } catch (e) { + console.log( + `Error retrieving alert response of ID ${alertRequest.id}, ${(e as Error).message}`, + ); + setOpenAlerts((prev) => { + return { + ...prev, + [alertRequest.id]: alertRequest, + }; + }); + return; + } + }; + + const subs: Subscription[] = []; + + subs.push( + rmf.alertRequestsObsStore.subscribe((alertRequest) => { + if (!alertRequest.display) { + setOpenAlerts((prev) => { + const filteredAlerts = Object.fromEntries( + Object.entries(prev).filter(([key]) => key !== alertRequest.id), + ); + return filteredAlerts; + }); + return; + } + AppEvents.pushAlert.next(alertRequest); + }), + ); + + subs.push( + rmf.alertResponsesObsStore.subscribe((alertResponse) => { + setOpenAlerts((prev) => { + return Object.fromEntries( + Object.entries(prev).filter(([key]) => key !== alertResponse.id), + ); + }); + }), + ); + + subs.push( + AppEvents.pushAlert.subscribe(async (alertRequest) => { + if (!alertRequest) { + return; + } + await pushAlertsToBeDisplayed(alertRequest); + }), + ); + + return () => { + for (const sub of subs) { + sub.unsubscribe(); + } + }; + }, [rmf]); + + const removeOpenAlert = (id: string) => { + const filteredAlerts = Object.fromEntries( + Object.entries(openAlerts).filter(([key]) => key !== id), + ); + setOpenAlerts(filteredAlerts); + }; + + return ( + <> + {Object.values(openAlerts).map((alert) => { + const removeThisAlert = () => removeOpenAlert(alert.id); + return ; + })} + + ); +}); diff --git a/packages/dashboard/src/components/alert-store.tsx b/packages/dashboard/src/components/alert-store.tsx deleted file mode 100644 index 8af882d40..000000000 --- a/packages/dashboard/src/components/alert-store.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { ApiServerModelsTortoiseModelsAlertsAlertLeaf as Alert } from 'api-client'; -import { AppEvents } from './app-events'; -import React from 'react'; -import { RmfAppContext } from './rmf-app'; -import { Subscription } from 'rxjs'; -import { TaskAlertDialog } from './tasks/task-alert'; - -// This needs to match the enums provided for the Alert model, as it is not -// provided via the api-client since tortoise's pydantic_model_creator is used. -enum AlertCategory { - Default = 'default', - Task = 'task', - Fleet = 'fleet', - Robot = 'robot', -} - -export const AlertStore = React.memo(() => { - const rmf = React.useContext(RmfAppContext); - const [taskAlerts, setTaskAlerts] = React.useState>({}); - - const categorizeAndPushAlerts = (alert: Alert) => { - // We check if an existing alert has been acknowledged, and remove it from - // display. - if (alert.category === AlertCategory.Task) { - setTaskAlerts((prev) => { - const filteredTaskAlerts = Object.fromEntries( - Object.entries(prev).filter(([key]) => key !== alert.original_id), - ); - - if (!alert.acknowledged_by) { - filteredTaskAlerts[alert.id] = alert; - } - return filteredTaskAlerts; - }); - } - }; - - React.useEffect(() => { - const subs: Subscription[] = []; - subs.push( - AppEvents.alertListOpenedAlert.subscribe((alert) => { - if (alert) { - categorizeAndPushAlerts(alert); - } - }), - ); - return () => subs.forEach((s) => s.unsubscribe()); - }, []); - - React.useEffect(() => { - if (!rmf) { - return; - } - const sub = rmf.alertObsStore.subscribe((alert) => { - categorizeAndPushAlerts(alert); - AppEvents.refreshAlert.next(); - }); - return () => sub.unsubscribe(); - }, [rmf]); - - const removeTaskAlert = (id: string) => { - const filteredTaskAlerts = Object.fromEntries( - Object.entries(taskAlerts).filter(([key]) => key !== id), - ); - setTaskAlerts(filteredTaskAlerts); - }; - - return ( - <> - {Object.values(taskAlerts).map((alert) => { - const removeThisAlert = () => { - removeTaskAlert(alert.id); - }; - return ; - })} - - ); -}); diff --git a/packages/dashboard/src/components/app-base.tsx b/packages/dashboard/src/components/app-base.tsx index 0e76dc200..6c3efbfcc 100644 --- a/packages/dashboard/src/components/app-base.tsx +++ b/packages/dashboard/src/components/app-base.tsx @@ -15,7 +15,7 @@ import { rmfDark, rmfDarkLeaflet, rmfLight } from 'react-components'; import { loadSettings, saveSettings, Settings, ThemeMode } from '../settings'; import { AppController, AppControllerContext, SettingsContext } from './app-contexts'; import AppBar from './appbar'; -import { AlertStore } from './alert-store'; +import { AlertManager } from './alert-manager'; import { AppEvents } from './app-events'; import { DeliveryAlertStore } from './delivery-alert-store'; @@ -95,7 +95,7 @@ export function AppBase({ children }: React.PropsWithChildren<{}>): JSX.Element )} - + (), refreshFavoriteTasks: new Subject(), refreshTaskSchedule: new Subject(), - refreshAlert: new Subject(), - alertListOpenedAlert: new Subject(), + pushAlert: new Subject(), disabledLayers: new ReplaySubject>(), zoom: new BehaviorSubject(null), cameraPosition: new BehaviorSubject(null), diff --git a/packages/dashboard/src/components/appbar.tsx b/packages/dashboard/src/components/appbar.tsx index 5ef0e56ad..ec2f4bb87 100644 --- a/packages/dashboard/src/components/appbar.tsx +++ b/packages/dashboard/src/components/appbar.tsx @@ -35,12 +35,7 @@ import { Typography, useMediaQuery, } from '@mui/material'; -import { - ApiServerModelsTortoiseModelsAlertsAlertLeaf as Alert, - FireAlarmTriggerState, - TaskFavorite, - TaskRequest, -} from 'api-client'; +import { AlertRequest, FireAlarmTriggerState, TaskFavorite, TaskRequest } from 'api-client'; import React from 'react'; import { AppBarTab, @@ -174,8 +169,7 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea const [openCreateTaskForm, setOpenCreateTaskForm] = React.useState(false); const [favoritesTasks, setFavoritesTasks] = React.useState([]); const [alertListAnchor, setAlertListAnchor] = React.useState(null); - const [unacknowledgedAlertsNum, setUnacknowledgedAlertsNum] = React.useState(0); - const [unacknowledgedAlertList, setUnacknowledgedAlertList] = React.useState([]); + const [unacknowledgedAlertList, setUnacknowledgedAlertList] = React.useState([]); const [openAdminActionsDialog, setOpenAdminActionsDialog] = React.useState(false); const [openFireAlarmTriggerResetDialog, setOpenFireAlarmTriggerResetDialog] = React.useState(false); @@ -208,32 +202,21 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea return; } + const updateUnrespondedAlerts = async () => { + const { data: alerts } = + await rmf.alertsApi.getUnrespondedAlertsAlertsUnrespondedRequestsGet(); + // alert.display is checked to verify that the dashboard should display it + // in the first place + const alertsToBeDisplayed = alerts.filter((alert) => alert.display); + setUnacknowledgedAlertList(alertsToBeDisplayed.reverse()); + }; + const subs: Subscription[] = []; - subs.push( - AppEvents.refreshAlert.subscribe({ - next: () => { - (async () => { - const resp = await rmf.alertsApi.getAlertsAlertsGet(); - const alerts = resp.data as Alert[]; - setUnacknowledgedAlertsNum( - alerts.filter( - (alert) => !(alert.acknowledged_by && alert.unix_millis_acknowledged_time), - ).length, - ); - })(); - }, - }), - ); + subs.push(rmf.alertRequestsObsStore.subscribe(updateUnrespondedAlerts)); + subs.push(rmf.alertResponsesObsStore.subscribe(updateUnrespondedAlerts)); // Get the initial number of unacknowledged alerts - (async () => { - const resp = await rmf.alertsApi.getAlertsAlertsGet(); - const alerts = resp.data as Alert[]; - setUnacknowledgedAlertsNum( - alerts.filter((alert) => !(alert.acknowledged_by && alert.unix_millis_acknowledged_time)) - .length, - ); - })(); + updateUnrespondedAlerts(); return () => subs.forEach((s) => s.unsubscribe()); }, [rmf]); @@ -348,18 +331,11 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea if (!rmf) { return; } - (async () => { - const { data: alerts } = await rmf.alertsApi.getAlertsAlertsGet(); - const unackList = alerts.filter( - (alert) => !alert.acknowledged_by && !alert.unix_millis_acknowledged_time, - ); - setUnacknowledgedAlertList(unackList.reverse()); - })(); setAlertListAnchor(event.currentTarget); }; - const openAlertDialog = (alert: Alert) => { - AppEvents.alertListOpenedAlert.next(alert); + const openAlertDialog = (alert: AlertRequest) => { + AppEvents.pushAlert.next(alert); }; const timeDistance = (time: number) => { @@ -445,7 +421,7 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea color="inherit" onClick={handleOpenAlertList} > - + @@ -475,17 +451,11 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea key={alert.id} title={ - - Alert - - - ID: {alert.original_id} - - - Type: {alert.category.toUpperCase()} - - - Created: {new Date(alert.unix_millis_created_time).toLocaleString()} + Alert + ID: {alert.id} + Title: {alert.title} + + Created: {new Date(alert.unix_millis_alert_time).toLocaleString()} } @@ -501,8 +471,8 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea > - Task {alert.original_id} had an alert{' '} - {timeDistance(alert.unix_millis_created_time)} ago + {alert.task_id ? `Task ${alert.task_id} had an alert ` : 'Alert occured '} + {timeDistance(alert.unix_millis_alert_time)} ago diff --git a/packages/dashboard/src/components/rmf-app/rmf-ingress.ts b/packages/dashboard/src/components/rmf-app/rmf-ingress.ts index 06f07a878..e733c2e74 100644 --- a/packages/dashboard/src/components/rmf-app/rmf-ingress.ts +++ b/packages/dashboard/src/components/rmf-app/rmf-ingress.ts @@ -1,7 +1,8 @@ import { AdminApi, AlertsApi, - ApiServerModelsTortoiseModelsAlertsAlertLeaf, + AlertRequest, + AlertResponse, ApiServerModelsTortoiseModelsBeaconsBeaconStateLeaf as BeaconState, BeaconsApi, BuildingApi, @@ -39,8 +40,6 @@ import { RobotTrajectoryManager, } from '../../managers/robot-trajectory-manager'; -type Alert = ApiServerModelsTortoiseModelsAlertsAlertLeaf; - export class RmfIngress { // This should be private because socketio does not support "replaying" subscription. If // subscription is made before the one made by the observables, the replays will not work @@ -245,8 +244,12 @@ export class RmfIngress { return this._taskStateObsStore[taskId]; } - alertObsStore: Observable = this._convertSioToRxObs((handler) => - this._sioClient.subscribeAlerts(handler), + alertRequestsObsStore: Observable = this._convertSioToRxObs((handler) => + this._sioClient.subscribeAlertRequests(handler), + ); + + alertResponsesObsStore: Observable = this._convertSioToRxObs((handler) => + this._sioClient.subscribeAlertResponses(handler), ); deliveryAlertObsStore: Observable = this._convertSioToRxObs((handler) => diff --git a/packages/dashboard/src/components/tasks/task-alert.tsx b/packages/dashboard/src/components/tasks/task-alert.tsx deleted file mode 100644 index 3319abf0b..000000000 --- a/packages/dashboard/src/components/tasks/task-alert.tsx +++ /dev/null @@ -1,303 +0,0 @@ -import React from 'react'; -import { - ApiServerModelsRmfApiLogEntryTier as Tier, - ApiServerModelsTortoiseModelsAlertsAlertLeaf, - LogEntry, - ApiServerModelsRmfApiTaskStateStatus as Status, - Status1, - TaskEventLog, - TaskState, -} from 'api-client'; -import { AppControllerContext } from '../app-contexts'; -import { RmfAppContext } from '../rmf-app'; -import { AlertContent, AlertDialog } from 'react-components'; -import { base } from 'react-components'; -import { TaskInspector } from './task-inspector'; - -type Alert = ApiServerModelsTortoiseModelsAlertsAlertLeaf; - -interface TaskAlert extends TaskEventLog { - title: string; - progress?: number; - content: AlertContent[]; - color: string; - acknowledgedBy?: string; - late: boolean; -} - -export interface TaskAlertDialogProps { - alert: Alert; - removeAlert: () => void; -} - -export function TaskAlertDialog({ alert, removeAlert }: TaskAlertDialogProps): JSX.Element { - const getErrorLogEntries = (logs: TaskEventLog) => { - let errorLogs: LogEntry[] = []; - if (logs.log) { - errorLogs.concat(logs.log.filter((entry) => entry.tier === Tier.Error)); - } - - if (logs.phases) { - for (let phase of Object.values(logs.phases)) { - if (phase.log) { - errorLogs.concat(phase.log.filter((entry) => entry.tier === Tier.Error)); - } - if (phase.events) { - for (let eventLogs of Object.values(phase.events)) { - errorLogs.concat(eventLogs.filter((entry) => entry.tier === Tier.Error)); - } - } - } - } - return errorLogs; - }; - - const getAlertTitle = (state: TaskState, errorLogEntries: LogEntry[]) => { - if (state.status && state.status === Status.Completed) { - return 'Task completed'; - } - if (state.status && state.status === Status.Failed) { - return 'Task failed'; - } - if (errorLogEntries.length !== 0) { - return 'Task error'; - } - return 'Task alert'; - }; - - const getTaskProgress = (state: TaskState) => { - if (state.status && state.status === Status.Completed) { - return 1; - } - - if (!state.estimate_millis || !state.unix_millis_start_time || !state.unix_millis_finish_time) { - return undefined; - } - return Math.min( - 1.0 - state.estimate_millis / (state.unix_millis_finish_time - state.unix_millis_start_time), - 1, - ); - }; - - const getAlertContent = (state: TaskState, errorLogEntries: LogEntry[]) => { - // First field to be the taks ID - let content: AlertContent[] = [ - { - title: 'ID', - value: state.booking.id, - }, - ]; - - // Second field would be any dispatch errors - if (state.dispatch && state.dispatch.status === Status1.FailedToAssign) { - let errors = ''; - if (state.dispatch.errors) { - for (const error of state.dispatch.errors) { - errors += `${JSON.stringify(error)}\n`; - } - } - content = [ - ...content, - { - title: 'Dispatch failure', - value: errors.length !== 0 ? errors : 'n/a', - }, - ]; - } - - // Third field would be any errors found - if (errorLogEntries.length !== 0) { - let consolidatedErrorMessages = ''; - for (let entry of errorLogEntries) { - consolidatedErrorMessages += `${new Date(entry.unix_millis_time).toLocaleString()} - ${ - entry.text - } - \n`; - } - - content = [ - ...content, - { - title: 'Error logs', - value: consolidatedErrorMessages, - }, - ]; - } - - // If the task happen to complete anyway, we mention that it has completed - // in a separate log - if (state.status && state.status === Status.Completed) { - const completionTimeString = state.unix_millis_finish_time - ? `${new Date(state.unix_millis_finish_time).toLocaleString()} - ` - : ''; - - content = [ - ...content, - { - title: 'Logs', - value: `${completionTimeString}Task completed!`, - }, - ]; - } - - return content; - }; - - const getAlertColor = (state: TaskState, errorLogs: LogEntry[]) => { - if (state.status) { - switch (state.status) { - case Status.Completed: - return base.palette.success.dark; - - case Status.Error: - case Status.Failed: - return base.palette.error.dark; - - default: - break; - } - } - - if (errorLogs.length !== 0) { - return base.palette.error.dark; - } - - return base.palette.background.default; - }; - - const rmf = React.useContext(RmfAppContext); - const { showAlert } = React.useContext(AppControllerContext); - const [taskAlert, setTaskAlert] = React.useState(null); - const [openTaskInspector, setOpenTaskInspector] = React.useState(false); - const [taskState, setTaskState] = React.useState(null); - React.useEffect(() => { - if (!rmf) { - return; - } - - (async () => { - // TODO(AC): Move away from using substrings, perhaps delayed tasks will - // be its own category. - const late_substr = '__late'; - const task_late = alert.original_id.includes(late_substr); - const task_id = task_late - ? alert.original_id.substring(0, alert.original_id.length - late_substr.length) - : alert.original_id; - - let logs: TaskEventLog | null = null; - try { - logs = ( - await rmf.tasksApi.getTaskLogTasksTaskIdLogGet(task_id, `0,${Number.MAX_SAFE_INTEGER}`) - ).data; - } catch { - console.log(`Failed to fetch task logs for ${alert.original_id}`); - } - const errorLogEntries = logs ? getErrorLogEntries(logs) : []; - - let state: TaskState | null = null; - try { - state = (await rmf.tasksApi.getTaskStateTasksTaskIdStateGet(task_id)).data; - } catch { - console.log(`Failed to fetch task state for ${alert.original_id}`); - } - setTaskState(state); - - let acknowledgedBy: string | undefined = undefined; - if (alert.acknowledged_by) { - acknowledgedBy = alert.acknowledged_by; - } else if (alert.unix_millis_acknowledged_time) { - acknowledgedBy = '-'; - } - - if (task_late && state) { - setTaskAlert({ - title: getAlertTitle(state, []), - progress: getTaskProgress(state), - content: getAlertContent(state, []), - color: getAlertColor(state, []), - acknowledgedBy: acknowledgedBy, - late: task_late, - task_id: task_id, - }); - } else if (!task_late && logs && state) { - setTaskAlert({ - title: getAlertTitle(state, errorLogEntries), - progress: getTaskProgress(state), - content: getAlertContent(state, errorLogEntries), - color: getAlertColor(state, errorLogEntries), - acknowledgedBy: acknowledgedBy, - late: task_late, - ...logs, - }); - } else if (state) { - setTaskAlert({ - title: getAlertTitle(state, []), - progress: getTaskProgress(state), - content: getAlertContent(state, []), - color: getAlertColor(state, []), - acknowledgedBy: acknowledgedBy, - late: task_late, - task_id: state.booking.id, - }); - } - })(); - }, [rmf, alert.original_id, alert.acknowledged_by, alert.unix_millis_acknowledged_time]); - - const acknowledgeAlert = () => { - if (!rmf) { - throw new Error('alerts api not available'); - } - if (!taskAlert) { - return; - } - - (async () => { - const idToAcknowledge = taskAlert.late ? `${taskAlert.task_id}__late` : taskAlert.task_id; - try { - const ackResponse = ( - await rmf?.alertsApi.acknowledgeAlertAlertsAlertIdPost(idToAcknowledge) - ).data; - if (ackResponse.id !== ackResponse.original_id) { - let showAlertMessage = `Alert ${ackResponse.original_id} acknowledged`; - if (ackResponse.acknowledged_by) { - showAlertMessage += ` by User ${ackResponse.acknowledged_by}`; - } - if (ackResponse.unix_millis_acknowledged_time) { - const ackSecondsAgo = - (new Date().getTime() - ackResponse.unix_millis_acknowledged_time) / 1000; - showAlertMessage += ` ${Math.round(ackSecondsAgo)}s ago`; - } - showAlert('success', showAlertMessage); - removeAlert(); - } else { - throw new Error(`Failed to acknowledge alert ID ${idToAcknowledge}`); - } - } catch (error) { - showAlert('error', `Failed to acknowledge alert ID ${idToAcknowledge}`); - console.log(error); - } - })(); - }; - - if (!taskAlert) { - return <>; - } - - return ( - <> - - {openTaskInspector && ( - setOpenTaskInspector(false)} /> - )} - - ); -} diff --git a/packages/dashboard/src/components/tasks/task-cancellation.tsx b/packages/dashboard/src/components/tasks/task-cancellation.tsx index baf1d082f..09738025b 100644 --- a/packages/dashboard/src/components/tasks/task-cancellation.tsx +++ b/packages/dashboard/src/components/tasks/task-cancellation.tsx @@ -41,14 +41,18 @@ export function TaskCancelButton({ if (!rmf || !taskId) { return; } - const sub = rmf.getTaskStateObs(taskId).subscribe(setTaskState); + const sub = rmf.getTaskStateObs(taskId).subscribe((state) => { + setTaskState(state); + }); return () => sub.unsubscribe(); }, [rmf, taskId]); - const taskCancellable = - taskState && - taskState.status && - !['canceled', 'killed', 'completed', 'failed'].includes(taskState.status); + const isTaskCancellable = (state: TaskState | null) => { + return ( + state && state.status && !['canceled', 'killed', 'completed', 'failed'].includes(state.status) + ); + }; + const userCanCancelTask = profile && Enforcer.canCancelTask(profile); function capitalizeFirstLetter(status: string): string { @@ -79,11 +83,11 @@ export function TaskCancelButton({ return ( <> - {taskCancellable && userCanCancelTask ? ( + {isTaskCancellable(taskState) && userCanCancelTask ? ( - ) : taskCancellable && !userCanCancelTask ? ( + ) : isTaskCancellable(taskState) && !userCanCancelTask ? (