UNPKG

@wandelbots/nova-js

Version:

Official JS client for the Wandelbots API

127 lines (114 loc) 3.93 kB
import type { MotionGroupState } from "@wandelbots/nova-api/v2" import type { AxiosResponse, InternalAxiosRequestConfig } from "axios" import { AxiosError } from "axios" import * as pathToRegexp from "path-to-regexp" import type { AutoReconnectingWebsocket } from "../AutoReconnectingWebsocket.ts" import { getCurrentRobotControllerState } from "./getCurrentRobotControllerState.ts" import { getMotionGroupDescription } from "./getMotionGroupDescription.ts" import { getMotionGroupKinematicModel } from "./getMotionGroupKinematicModel.ts" import { getRobotController } from "./getRobotController.ts" import { listCoordinateSystems } from "./listCoordinateSystems.ts" import { listRobotControllers } from "./listRobotControllers.ts" /** * Ultra-simplified mock Nova server for testing stuff */ export class MockNovaInstance { readonly connections: AutoReconnectingWebsocket[] = [] async handleAPIRequest( config: InternalAxiosRequestConfig, ): Promise<AxiosResponse> { const apiHandlers = [ listRobotControllers, getRobotController, getMotionGroupDescription, getCurrentRobotControllerState, listCoordinateSystems, getMotionGroupKinematicModel, ] const method = config.method?.toUpperCase() || "GET" if (!config.url) { throw new Error("No url sent with request") } const path = config.url.split("?")[0] ?? config.url for (const handler of apiHandlers) { const match = pathToRegexp.match(handler.path)(path) if (method === handler.method && match) { const json = handler.handle() return { status: 200, statusText: "Success", data: JSON.stringify(json), headers: {}, config, request: { responseURL: config.url, }, } } } throw new AxiosError( `No mock handler matched this request: ${method} ${path}`, "404", config, ) } // Please note: Only very basic websocket mocking is done here, needs to be extended as needed handleWebsocketConnection(socket: AutoReconnectingWebsocket) { this.connections.push(socket) setTimeout(() => { socket.dispatchEvent(new Event("open")) console.log("Websocket connection opened from", socket.url) if (socket.url.includes("/state-stream")) { socket.dispatchEvent( new MessageEvent("message", { data: JSON.stringify(defaultMotionState), }), ) } if (socket.url.includes("/execution/jogging")) { socket.dispatchEvent( new MessageEvent("message", { data: JSON.stringify({ result: { message: "string", kind: "INITIALIZE_RECEIVED", }, }), }), ) } }, 10) } handleWebsocketMessage(socket: AutoReconnectingWebsocket, message: string) { console.log(`Received message on ${socket.url}`, message) } } const defaultMotionState = { result: { motion_group: "0@universalrobots-ur5e", controller: "universalrobots-ur5e", timestamp: new Date().toISOString(), sequence_number: 1, joint_position: [ 1.1699999570846558, -1.5700000524520874, 1.3600000143051147, 1.0299999713897705, 1.2899999618530273, 1.2799999713897705, ], joint_limit_reached: { limit_reached: [false, false, false, false, false, false], }, standstill: false, flange_pose: { position: [1.3300010259703043, -409.2680714682808, 531.0203477065281], orientation: [ 1.7564919306270736, -1.7542521568325058, 0.7326972590614671, ], }, tcp_pose: { position: [1.3300010259703043, -409.2680714682808, 531.0203477065281], orientation: [ 1.7564919306270736, -1.7542521568325058, 0.7326972590614671, ], }, description_revision: 0, } satisfies MotionGroupState, }