abb-rws-client 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +199 -137
- package/dist/ResourceMapper.d.ts +219 -2
- package/dist/ResourceMapper.d.ts.map +1 -1
- package/dist/ResourceMapper.js +278 -3
- package/dist/ResourceMapper.js.map +1 -1
- package/dist/ResponseParser.d.ts +81 -2
- package/dist/ResponseParser.d.ts.map +1 -1
- package/dist/ResponseParser.js +309 -3
- package/dist/ResponseParser.js.map +1 -1
- package/dist/RwsClient.d.ts +247 -1
- package/dist/RwsClient.d.ts.map +1 -1
- package/dist/RwsClient.js +626 -2
- package/dist/RwsClient.js.map +1 -1
- package/dist/WsSubscriber.d.ts.map +1 -1
- package/dist/WsSubscriber.js +18 -11
- package/dist/WsSubscriber.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/types.d.ts +188 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
package/dist/RwsClient.js
CHANGED
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
import { HttpSession } from './HttpSession.js';
|
|
18
18
|
import { WsSubscriber } from './WsSubscriber.js';
|
|
19
19
|
import { RwsError } from './types.js';
|
|
20
|
-
import { controllerState as pathControllerState, operationMode as pathOperationMode, rapidTasks as pathRapidTasks, rapidExecutionState as pathRapidExecutionState, startRapid as mapStartRapid, stopRapid as mapStopRapid, resetRapid as mapResetRapid, jointTarget as pathJointTarget, robTarget as pathRobTarget, loadModule as mapLoadModule, listModules as pathListModules, uploadFile as pathUploadFile, signal as pathSignal, setSignal as mapSetSignal, } from './ResourceMapper.js';
|
|
21
|
-
import { parseControllerState, parseOperationMode, parseExecutionState, parseJointTarget, parseRobTarget, parseSignal, parseRapidTasks, } from './ResponseParser.js';
|
|
20
|
+
import { controllerState as pathControllerState, setControllerState as mapSetControllerState, operationMode as pathOperationMode, speedRatio as pathSpeedRatio, setSpeedRatio as mapSetSpeedRatio, collisionDetectionState as pathCollisionDetectionState, restartController as mapRestartController, lockOperationMode as mapLockOperationMode, unlockOperationMode as mapUnlockOperationMode, rapidTasks as pathRapidTasks, rapidExecutionState as pathRapidExecutionState, startRapid as mapStartRapid, stopRapid as mapStopRapid, resetRapid as mapResetRapid, setExecutionCycle as mapSetExecutionCycle, rapidSymbol as pathRapidSymbol, rapidSymbolProperties as pathRapidSymbolProperties, setRapidSymbol as mapSetRapidSymbol, activeUiInstruction as pathActiveUiInstruction, setUiInstructionParam as mapSetUiInstructionParam, activateRapidTask as mapActivateRapidTask, deactivateRapidTask as mapDeactivateRapidTask, activateAllRapidTasks as mapActivateAllRapidTasks, deactivateAllRapidTasks as mapDeactivateAllRapidTasks, searchRapidSymbols as mapSearchRapidSymbols, validateRapidValue as mapValidateRapidValue, jointTarget as pathJointTarget, robTarget as pathRobTarget, cartesianFull as pathCartesianFull, loadModule as mapLoadModule, listModules as pathListModules, uploadFile as pathUploadFile, allSignals as pathAllSignals, networks as pathNetworks, devices as pathDevices, signal as pathSignal, setSignal as mapSetSignal, systemInfo as pathSystemInfo, controllerIdentity as pathControllerIdentity, clockInfo as pathClockInfo, setControllerClock as mapSetControllerClock, elogMessages as pathElogMessages, clearElogDomain as mapClearElogDomain, clearAllElogs as mapClearAllElogs, fileServicePath, deleteFile as pathDeleteFile, copyFile as mapCopyFile, requestMastership as mapRequestMastership, releaseMastership as mapReleaseMastership, } from './ResourceMapper.js';
|
|
21
|
+
import { parseControllerState, parseOperationMode, parseSpeedRatio, parseExecutionState, parseExecutionInfo, parseJointTarget, parseRobTarget, parseCartesianFull, parseRapidSymbolValue, parseRapidSymbolProperties, parseSignal, parseSignalList, parseNetworks, parseDevices, parseRapidTasks, parseSystemInfo, parseControllerIdentity, parseControllerClock, parseActiveUiInstruction, parseRapidSymbolSearch, parseElogMessages, parseDirectory, parseCollisionDetectionState, } from './ResponseParser.js';
|
|
22
22
|
export class RwsClient {
|
|
23
23
|
session;
|
|
24
24
|
subscriber;
|
|
@@ -89,6 +89,24 @@ export class RwsClient {
|
|
|
89
89
|
throw new RwsError(`getControllerState failed: ${String(e)}`, 'UNKNOWN');
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Set the controller motor state.
|
|
94
|
+
* Requires AUTO mode and mastership (request with requestMastership('motion') first).
|
|
95
|
+
*
|
|
96
|
+
* @param state - 'motoron' | 'motoroff'
|
|
97
|
+
* @throws {RwsError} code='AUTH_FAILED' if mastership is not held
|
|
98
|
+
*/
|
|
99
|
+
async setControllerState(state) {
|
|
100
|
+
try {
|
|
101
|
+
const { path, body } = mapSetControllerState(state);
|
|
102
|
+
await this.session.post(path, body);
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
if (e instanceof RwsError)
|
|
106
|
+
throw e;
|
|
107
|
+
throw new RwsError(`setControllerState failed: ${String(e)}`, 'UNKNOWN');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
92
110
|
/**
|
|
93
111
|
* Read the current operation mode.
|
|
94
112
|
*
|
|
@@ -106,6 +124,103 @@ export class RwsClient {
|
|
|
106
124
|
throw new RwsError(`getOperationMode failed: ${String(e)}`, 'UNKNOWN');
|
|
107
125
|
}
|
|
108
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Read the collision detection state.
|
|
129
|
+
* Returns INIT (no collision), TRIGGERED, CONFIRMED, or TRIGGERED_ACK.
|
|
130
|
+
* Requires the Collision Detection option on the controller.
|
|
131
|
+
*/
|
|
132
|
+
async getCollisionDetectionState() {
|
|
133
|
+
try {
|
|
134
|
+
const { body } = await this.session.get(pathCollisionDetectionState());
|
|
135
|
+
return parseCollisionDetectionState(body);
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
if (e instanceof RwsError)
|
|
139
|
+
throw e;
|
|
140
|
+
throw new RwsError(`getCollisionDetectionState failed: ${String(e)}`, 'UNKNOWN');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Restart (or warm-start) the controller.
|
|
145
|
+
*
|
|
146
|
+
* **Modes:**
|
|
147
|
+
* - `restart` — Normal restart; saves state and activates changed system parameters
|
|
148
|
+
* - `istart` — Restart with original installation settings; discards all programs
|
|
149
|
+
* - `pstart` — Restart preserving system parameters; removes programs
|
|
150
|
+
* - `bstart` — Boot with last auto-saved state (crash recovery)
|
|
151
|
+
*
|
|
152
|
+
* @param mode - Restart mode; default 'restart'
|
|
153
|
+
*/
|
|
154
|
+
async restartController(mode = 'restart') {
|
|
155
|
+
try {
|
|
156
|
+
const { path, body } = mapRestartController(mode);
|
|
157
|
+
await this.session.post(path, body);
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
if (e instanceof RwsError)
|
|
161
|
+
throw e;
|
|
162
|
+
throw new RwsError(`restartController failed: ${String(e)}`, 'UNKNOWN');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Lock the operation mode selector on the FlexPendant.
|
|
167
|
+
* @param pin - 4-digit PIN code
|
|
168
|
+
* @param permanent - true = permanent lock; false = temporary
|
|
169
|
+
*/
|
|
170
|
+
async lockOperationMode(pin, permanent = false) {
|
|
171
|
+
try {
|
|
172
|
+
const { path, body } = mapLockOperationMode(pin, permanent);
|
|
173
|
+
await this.session.post(path, body);
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
if (e instanceof RwsError)
|
|
177
|
+
throw e;
|
|
178
|
+
throw new RwsError(`lockOperationMode failed: ${String(e)}`, 'UNKNOWN');
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** Unlock the operation mode selector. */
|
|
182
|
+
async unlockOperationMode() {
|
|
183
|
+
try {
|
|
184
|
+
const { path, body } = mapUnlockOperationMode();
|
|
185
|
+
await this.session.post(path, body);
|
|
186
|
+
}
|
|
187
|
+
catch (e) {
|
|
188
|
+
if (e instanceof RwsError)
|
|
189
|
+
throw e;
|
|
190
|
+
throw new RwsError(`unlockOperationMode failed: ${String(e)}`, 'UNKNOWN');
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// ─── Speed ratio ────────────────────────────────────────────────────────────
|
|
194
|
+
/**
|
|
195
|
+
* Read the current speed ratio (0–100).
|
|
196
|
+
* Represents override percentage applied to all robot speeds.
|
|
197
|
+
*/
|
|
198
|
+
async getSpeedRatio() {
|
|
199
|
+
try {
|
|
200
|
+
const { body } = await this.session.get(pathSpeedRatio());
|
|
201
|
+
return parseSpeedRatio(body);
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
if (e instanceof RwsError)
|
|
205
|
+
throw e;
|
|
206
|
+
throw new RwsError(`getSpeedRatio failed: ${String(e)}`, 'UNKNOWN');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Set the speed ratio override (0–100). Only valid in AUTO mode.
|
|
211
|
+
* @param ratio - Integer 0–100 (clamped automatically)
|
|
212
|
+
*/
|
|
213
|
+
async setSpeedRatio(ratio) {
|
|
214
|
+
try {
|
|
215
|
+
const { path, body } = mapSetSpeedRatio(ratio);
|
|
216
|
+
await this.session.post(path, body);
|
|
217
|
+
}
|
|
218
|
+
catch (e) {
|
|
219
|
+
if (e instanceof RwsError)
|
|
220
|
+
throw e;
|
|
221
|
+
throw new RwsError(`setSpeedRatio failed: ${String(e)}`, 'UNKNOWN');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
109
224
|
// ─── RAPID execution ────────────────────────────────────────────────────────
|
|
110
225
|
/**
|
|
111
226
|
* Read the current RAPID execution state.
|
|
@@ -123,6 +238,22 @@ export class RwsClient {
|
|
|
123
238
|
throw new RwsError(`getRapidExecutionState failed: ${String(e)}`, 'UNKNOWN');
|
|
124
239
|
}
|
|
125
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Read the full RAPID execution info including state and current cycle mode.
|
|
243
|
+
*
|
|
244
|
+
* @returns ExecutionInfo with state ('running'|'stopped') and cycle ('once'|'forever'|'asis'|'oncedone')
|
|
245
|
+
*/
|
|
246
|
+
async getRapidExecutionInfo() {
|
|
247
|
+
try {
|
|
248
|
+
const { body } = await this.session.get(pathRapidExecutionState());
|
|
249
|
+
return parseExecutionInfo(body);
|
|
250
|
+
}
|
|
251
|
+
catch (e) {
|
|
252
|
+
if (e instanceof RwsError)
|
|
253
|
+
throw e;
|
|
254
|
+
throw new RwsError(`getRapidExecutionInfo failed: ${String(e)}`, 'UNKNOWN');
|
|
255
|
+
}
|
|
256
|
+
}
|
|
126
257
|
/**
|
|
127
258
|
* Retrieve all RAPID tasks and their current states.
|
|
128
259
|
*
|
|
@@ -191,6 +322,222 @@ export class RwsClient {
|
|
|
191
322
|
throw new RwsError(`resetRapid failed: ${String(e)}`, 'UNKNOWN');
|
|
192
323
|
}
|
|
193
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Set the RAPID execution cycle mode.
|
|
327
|
+
* @param cycle - 'once' (run once then stop) | 'forever' (loop) | 'asis' (keep current)
|
|
328
|
+
*/
|
|
329
|
+
async setExecutionCycle(cycle) {
|
|
330
|
+
try {
|
|
331
|
+
const { path, body } = mapSetExecutionCycle(cycle);
|
|
332
|
+
await this.session.post(path, body);
|
|
333
|
+
}
|
|
334
|
+
catch (e) {
|
|
335
|
+
if (e instanceof RwsError)
|
|
336
|
+
throw e;
|
|
337
|
+
throw new RwsError(`setExecutionCycle failed: ${String(e)}`, 'UNKNOWN');
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// ─── RAPID variables ────────────────────────────────────────────────────────
|
|
341
|
+
/**
|
|
342
|
+
* Read the value of a RAPID symbol (variable, persistent, or constant).
|
|
343
|
+
* Returns the raw string as the controller formats it (e.g. '42', '"hello"', '[1,2,3]').
|
|
344
|
+
*
|
|
345
|
+
* @param taskName - RAPID task name, e.g. 'T_ROB1'
|
|
346
|
+
* @param moduleName - Module name, e.g. 'user'
|
|
347
|
+
* @param symbolName - Symbol name, e.g. 'reg1'
|
|
348
|
+
*/
|
|
349
|
+
async getRapidVariable(taskName, moduleName, symbolName) {
|
|
350
|
+
try {
|
|
351
|
+
const { body } = await this.session.get(pathRapidSymbol(taskName, moduleName, symbolName));
|
|
352
|
+
return parseRapidSymbolValue(body);
|
|
353
|
+
}
|
|
354
|
+
catch (e) {
|
|
355
|
+
if (e instanceof RwsError)
|
|
356
|
+
throw e;
|
|
357
|
+
throw new RwsError(`getRapidVariable failed: ${String(e)}`, 'UNKNOWN');
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Write a value to a RAPID variable or persistent.
|
|
362
|
+
* Value must be a RAPID-formatted string: e.g. '42', '3.14', '"hello"', '[1,0,0,0]'.
|
|
363
|
+
*
|
|
364
|
+
* @param taskName - RAPID task name
|
|
365
|
+
* @param moduleName - Module name
|
|
366
|
+
* @param symbolName - Symbol name
|
|
367
|
+
* @param value - New value in RAPID syntax
|
|
368
|
+
*/
|
|
369
|
+
async setRapidVariable(taskName, moduleName, symbolName, value) {
|
|
370
|
+
try {
|
|
371
|
+
const { path, body } = mapSetRapidSymbol(taskName, moduleName, symbolName, value);
|
|
372
|
+
await this.session.post(path, body);
|
|
373
|
+
}
|
|
374
|
+
catch (e) {
|
|
375
|
+
if (e instanceof RwsError)
|
|
376
|
+
throw e;
|
|
377
|
+
throw new RwsError(`setRapidVariable failed: ${String(e)}`, 'UNKNOWN');
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Activate a RAPID task (for multitasking systems).
|
|
382
|
+
* Mastership is taken internally by the controller.
|
|
383
|
+
* @param task - Task name, e.g. 'T_ROB2'
|
|
384
|
+
*/
|
|
385
|
+
async activateRapidTask(task) {
|
|
386
|
+
try {
|
|
387
|
+
const { path, body } = mapActivateRapidTask(task);
|
|
388
|
+
await this.session.post(path, body);
|
|
389
|
+
}
|
|
390
|
+
catch (e) {
|
|
391
|
+
if (e instanceof RwsError)
|
|
392
|
+
throw e;
|
|
393
|
+
throw new RwsError(`activateRapidTask failed: ${String(e)}`, 'UNKNOWN');
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Deactivate a RAPID task (for multitasking systems).
|
|
398
|
+
* @param task - Task name
|
|
399
|
+
*/
|
|
400
|
+
async deactivateRapidTask(task) {
|
|
401
|
+
try {
|
|
402
|
+
const { path, body } = mapDeactivateRapidTask(task);
|
|
403
|
+
await this.session.post(path, body);
|
|
404
|
+
}
|
|
405
|
+
catch (e) {
|
|
406
|
+
if (e instanceof RwsError)
|
|
407
|
+
throw e;
|
|
408
|
+
throw new RwsError(`deactivateRapidTask failed: ${String(e)}`, 'UNKNOWN');
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/** Activate ALL RAPID tasks. */
|
|
412
|
+
async activateAllRapidTasks() {
|
|
413
|
+
try {
|
|
414
|
+
const { path, body } = mapActivateAllRapidTasks();
|
|
415
|
+
await this.session.post(path, body);
|
|
416
|
+
}
|
|
417
|
+
catch (e) {
|
|
418
|
+
if (e instanceof RwsError)
|
|
419
|
+
throw e;
|
|
420
|
+
throw new RwsError(`activateAllRapidTasks failed: ${String(e)}`, 'UNKNOWN');
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
/** Deactivate ALL RAPID tasks. */
|
|
424
|
+
async deactivateAllRapidTasks() {
|
|
425
|
+
try {
|
|
426
|
+
const { path, body } = mapDeactivateAllRapidTasks();
|
|
427
|
+
await this.session.post(path, body);
|
|
428
|
+
}
|
|
429
|
+
catch (e) {
|
|
430
|
+
if (e instanceof RwsError)
|
|
431
|
+
throw e;
|
|
432
|
+
throw new RwsError(`deactivateAllRapidTasks failed: ${String(e)}`, 'UNKNOWN');
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Get the currently active RAPID UI instruction.
|
|
437
|
+
* Returns null if no UI instruction is waiting for input.
|
|
438
|
+
* Used to detect when RAPID is waiting for operator input (TPReadNum, TPReadFK, etc.).
|
|
439
|
+
*/
|
|
440
|
+
async getActiveUiInstruction() {
|
|
441
|
+
try {
|
|
442
|
+
const { body } = await this.session.get(pathActiveUiInstruction());
|
|
443
|
+
return parseActiveUiInstruction(body);
|
|
444
|
+
}
|
|
445
|
+
catch (e) {
|
|
446
|
+
if (e instanceof RwsError)
|
|
447
|
+
throw e;
|
|
448
|
+
throw new RwsError(`getActiveUiInstruction failed: ${String(e)}`, 'UNKNOWN');
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Respond to an active RAPID UI instruction (e.g. send the answer to a TPReadNum).
|
|
453
|
+
* Get the stackurl from getActiveUiInstruction().stack.
|
|
454
|
+
*
|
|
455
|
+
* Common parameter names:
|
|
456
|
+
* - 'Result' — the answer value for TPReadNum, TPReadFK
|
|
457
|
+
* - 'TPFK1' … 'TPFK5' — individual function key states (0/1)
|
|
458
|
+
* - 'TPCompleted' — set to 'TRUE' when done
|
|
459
|
+
*
|
|
460
|
+
* @param stackurl - Stack URL from UiInstruction.stack (e.g. 'RAPID/T_ROB1/%$104')
|
|
461
|
+
* @param uiparam - Parameter name, e.g. 'Result'
|
|
462
|
+
* @param value - Value to set, e.g. '42' or 'TRUE'
|
|
463
|
+
*/
|
|
464
|
+
async setUiInstructionParam(stackurl, uiparam, value) {
|
|
465
|
+
try {
|
|
466
|
+
const { path, body } = mapSetUiInstructionParam(stackurl, uiparam, value);
|
|
467
|
+
await this.session.post(path, body);
|
|
468
|
+
}
|
|
469
|
+
catch (e) {
|
|
470
|
+
if (e instanceof RwsError)
|
|
471
|
+
throw e;
|
|
472
|
+
throw new RwsError(`setUiInstructionParam failed: ${String(e)}`, 'UNKNOWN');
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Search for RAPID symbols matching filter criteria.
|
|
477
|
+
*
|
|
478
|
+
* @param params - Search parameters (task is required; all others are optional filters)
|
|
479
|
+
* @returns Array of matching symbols with abbreviated properties
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* ```ts
|
|
483
|
+
* // Find all persistent variables in T_ROB1
|
|
484
|
+
* const persistents = await client.searchRapidSymbols({ task: 'T_ROB1', symtyp: 'per' });
|
|
485
|
+
* ```
|
|
486
|
+
*/
|
|
487
|
+
async searchRapidSymbols(params) {
|
|
488
|
+
try {
|
|
489
|
+
const { path, body } = mapSearchRapidSymbols(params);
|
|
490
|
+
const { body: responseBody } = await this.session.post(path, body);
|
|
491
|
+
return parseRapidSymbolSearch(responseBody);
|
|
492
|
+
}
|
|
493
|
+
catch (e) {
|
|
494
|
+
if (e instanceof RwsError)
|
|
495
|
+
throw e;
|
|
496
|
+
throw new RwsError(`searchRapidSymbols failed: ${String(e)}`, 'UNKNOWN');
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Validate a value against a RAPID data type without writing it.
|
|
501
|
+
* Useful for validating user input before calling setRapidVariable.
|
|
502
|
+
*
|
|
503
|
+
* @param task - RAPID task name, e.g. 'T_ROB1'
|
|
504
|
+
* @param value - Value in RAPID syntax, e.g. '[1,0,0,0]'
|
|
505
|
+
* @param datatype - RAPID data type name, e.g. 'tooldata', 'robtarget', 'num'
|
|
506
|
+
* @returns true if valid, false if invalid (no exception thrown for invalid values)
|
|
507
|
+
*/
|
|
508
|
+
async validateRapidValue(task, value, datatype) {
|
|
509
|
+
try {
|
|
510
|
+
const { path, body } = mapValidateRapidValue(task, value, datatype);
|
|
511
|
+
const { status } = await this.session.post(path, body);
|
|
512
|
+
return status === 204;
|
|
513
|
+
}
|
|
514
|
+
catch (e) {
|
|
515
|
+
if (e instanceof RwsError && e.httpStatus === 400)
|
|
516
|
+
return false;
|
|
517
|
+
if (e instanceof RwsError)
|
|
518
|
+
throw e;
|
|
519
|
+
throw new RwsError(`validateRapidValue failed: ${String(e)}`, 'UNKNOWN');
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Read RAPID symbol properties (type, dimensions, storage class, etc.).
|
|
524
|
+
* Useful for introspecting variables, persistents, constants, and records.
|
|
525
|
+
*
|
|
526
|
+
* @param taskName - RAPID task name, e.g. 'T_ROB1'
|
|
527
|
+
* @param moduleName - Module name, e.g. 'user'
|
|
528
|
+
* @param symbolName - Symbol name, e.g. 'reg1'
|
|
529
|
+
*/
|
|
530
|
+
async getRapidSymbolProperties(taskName, moduleName, symbolName) {
|
|
531
|
+
try {
|
|
532
|
+
const { body } = await this.session.get(pathRapidSymbolProperties(taskName, moduleName, symbolName));
|
|
533
|
+
return parseRapidSymbolProperties(body);
|
|
534
|
+
}
|
|
535
|
+
catch (e) {
|
|
536
|
+
if (e instanceof RwsError)
|
|
537
|
+
throw e;
|
|
538
|
+
throw new RwsError(`getRapidSymbolProperties failed: ${String(e)}`, 'UNKNOWN');
|
|
539
|
+
}
|
|
540
|
+
}
|
|
194
541
|
// ─── Motion ─────────────────────────────────────────────────────────────────
|
|
195
542
|
/**
|
|
196
543
|
* Read the current joint-space positions for a mechanical unit.
|
|
@@ -228,6 +575,24 @@ export class RwsClient {
|
|
|
228
575
|
throw new RwsError(`getCartesianPosition failed: ${String(e)}`, 'UNKNOWN');
|
|
229
576
|
}
|
|
230
577
|
}
|
|
578
|
+
/**
|
|
579
|
+
* Read the current Cartesian position including robot configuration flags.
|
|
580
|
+
* Uses /cartesian endpoint (no tool/wobj override — uses active tool/wobj).
|
|
581
|
+
* Returns j1/j4/j6/jx configuration integers in addition to pose.
|
|
582
|
+
*
|
|
583
|
+
* @param mechunit - Default 'ROB_1'
|
|
584
|
+
*/
|
|
585
|
+
async getCartesianFull(mechunit) {
|
|
586
|
+
try {
|
|
587
|
+
const { body } = await this.session.get(pathCartesianFull(mechunit));
|
|
588
|
+
return parseCartesianFull(body);
|
|
589
|
+
}
|
|
590
|
+
catch (e) {
|
|
591
|
+
if (e instanceof RwsError)
|
|
592
|
+
throw e;
|
|
593
|
+
throw new RwsError(`getCartesianFull failed: ${String(e)}`, 'UNKNOWN');
|
|
594
|
+
}
|
|
595
|
+
}
|
|
231
596
|
// ─── Modules ────────────────────────────────────────────────────────────────
|
|
232
597
|
/**
|
|
233
598
|
* Download a file from the controller filesystem as a UTF-8 string.
|
|
@@ -324,6 +689,69 @@ export class RwsClient {
|
|
|
324
689
|
throw new RwsError(`listModules failed: ${String(e)}`, 'UNKNOWN');
|
|
325
690
|
}
|
|
326
691
|
}
|
|
692
|
+
/**
|
|
693
|
+
* Download a directory listing from the controller filesystem.
|
|
694
|
+
* Returns entries sorted: directories first, then files.
|
|
695
|
+
*
|
|
696
|
+
* @param remotePath - Controller path, e.g. '$HOME' or '$HOME/Dispense'
|
|
697
|
+
*/
|
|
698
|
+
async listDirectory(remotePath) {
|
|
699
|
+
try {
|
|
700
|
+
const { body } = await this.session.get(fileServicePath(remotePath));
|
|
701
|
+
return parseDirectory(body);
|
|
702
|
+
}
|
|
703
|
+
catch (e) {
|
|
704
|
+
if (e instanceof RwsError)
|
|
705
|
+
throw e;
|
|
706
|
+
throw new RwsError(`listDirectory failed: ${String(e)}`, 'UNKNOWN');
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Delete a file from the controller filesystem.
|
|
711
|
+
* @param remotePath - Controller path, e.g. '$HOME/OldMod.mod'
|
|
712
|
+
*/
|
|
713
|
+
async deleteFile(remotePath) {
|
|
714
|
+
try {
|
|
715
|
+
await this.session.delete(pathDeleteFile(remotePath));
|
|
716
|
+
}
|
|
717
|
+
catch (e) {
|
|
718
|
+
if (e instanceof RwsError)
|
|
719
|
+
throw e;
|
|
720
|
+
throw new RwsError(`deleteFile failed: ${String(e)}`, 'UNKNOWN');
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Create a directory on the controller filesystem.
|
|
725
|
+
* @param parentPath - Parent directory path, e.g. '$HOME'
|
|
726
|
+
* @param dirName - New directory name, e.g. 'Backup'
|
|
727
|
+
*/
|
|
728
|
+
async createDirectory(parentPath, dirName) {
|
|
729
|
+
try {
|
|
730
|
+
const { path } = { path: fileServicePath(parentPath) };
|
|
731
|
+
await this.session.post(`${path}?fs-action=create&fs-newname=${encodeURIComponent(dirName)}`, '');
|
|
732
|
+
}
|
|
733
|
+
catch (e) {
|
|
734
|
+
if (e instanceof RwsError)
|
|
735
|
+
throw e;
|
|
736
|
+
throw new RwsError(`createDirectory failed: ${String(e)}`, 'UNKNOWN');
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* Copy a file on the controller filesystem.
|
|
741
|
+
* @param sourcePath - Source file path, e.g. '$HOME/MyMod.mod'
|
|
742
|
+
* @param destPath - Destination path (full path including filename), e.g. '$HOME/Backup/MyMod.mod'
|
|
743
|
+
*/
|
|
744
|
+
async copyFile(sourcePath, destPath) {
|
|
745
|
+
try {
|
|
746
|
+
const { path, body } = mapCopyFile(sourcePath, destPath);
|
|
747
|
+
await this.session.post(path, body);
|
|
748
|
+
}
|
|
749
|
+
catch (e) {
|
|
750
|
+
if (e instanceof RwsError)
|
|
751
|
+
throw e;
|
|
752
|
+
throw new RwsError(`copyFile failed: ${String(e)}`, 'UNKNOWN');
|
|
753
|
+
}
|
|
754
|
+
}
|
|
327
755
|
// ─── I/O signals ────────────────────────────────────────────────────────────
|
|
328
756
|
/**
|
|
329
757
|
* Read an I/O signal value.
|
|
@@ -363,6 +791,202 @@ export class RwsClient {
|
|
|
363
791
|
throw new RwsError(`writeSignal failed: ${String(e)}`, 'UNKNOWN');
|
|
364
792
|
}
|
|
365
793
|
}
|
|
794
|
+
/**
|
|
795
|
+
* List all configured I/O signals (paginated).
|
|
796
|
+
* The controller returns up to `limit` signals per call; use `start` to page through.
|
|
797
|
+
*
|
|
798
|
+
* @param start - Starting index (default 0)
|
|
799
|
+
* @param limit - Results per page (default 100)
|
|
800
|
+
*/
|
|
801
|
+
async listAllSignals(start = 0, limit = 100) {
|
|
802
|
+
try {
|
|
803
|
+
const { body } = await this.session.get(pathAllSignals(start, limit));
|
|
804
|
+
return parseSignalList(body);
|
|
805
|
+
}
|
|
806
|
+
catch (e) {
|
|
807
|
+
if (e instanceof RwsError)
|
|
808
|
+
throw e;
|
|
809
|
+
throw new RwsError(`listAllSignals failed: ${String(e)}`, 'UNKNOWN');
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* List all configured I/O networks.
|
|
814
|
+
*/
|
|
815
|
+
async listNetworks() {
|
|
816
|
+
try {
|
|
817
|
+
const { body } = await this.session.get(pathNetworks());
|
|
818
|
+
return parseNetworks(body);
|
|
819
|
+
}
|
|
820
|
+
catch (e) {
|
|
821
|
+
if (e instanceof RwsError)
|
|
822
|
+
throw e;
|
|
823
|
+
throw new RwsError(`listNetworks failed: ${String(e)}`, 'UNKNOWN');
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* List all I/O devices on a network.
|
|
828
|
+
* @param network - Network name, e.g. 'Local'
|
|
829
|
+
*/
|
|
830
|
+
async listDevices(network) {
|
|
831
|
+
try {
|
|
832
|
+
const { body } = await this.session.get(pathDevices(network));
|
|
833
|
+
return parseDevices(body);
|
|
834
|
+
}
|
|
835
|
+
catch (e) {
|
|
836
|
+
if (e instanceof RwsError)
|
|
837
|
+
throw e;
|
|
838
|
+
throw new RwsError(`listDevices failed: ${String(e)}`, 'UNKNOWN');
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
// ─── Controller info ────────────────────────────────────────────────────────
|
|
842
|
+
/**
|
|
843
|
+
* Read RobotWare system information (version, options, system ID).
|
|
844
|
+
*/
|
|
845
|
+
async getSystemInfo() {
|
|
846
|
+
try {
|
|
847
|
+
const { body } = await this.session.get(pathSystemInfo());
|
|
848
|
+
return parseSystemInfo(body);
|
|
849
|
+
}
|
|
850
|
+
catch (e) {
|
|
851
|
+
if (e instanceof RwsError)
|
|
852
|
+
throw e;
|
|
853
|
+
throw new RwsError(`getSystemInfo failed: ${String(e)}`, 'UNKNOWN');
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Read controller hardware identity (name, ID, type, MAC address).
|
|
858
|
+
*/
|
|
859
|
+
async getControllerIdentity() {
|
|
860
|
+
try {
|
|
861
|
+
const { body } = await this.session.get(pathControllerIdentity());
|
|
862
|
+
return parseControllerIdentity(body);
|
|
863
|
+
}
|
|
864
|
+
catch (e) {
|
|
865
|
+
if (e instanceof RwsError)
|
|
866
|
+
throw e;
|
|
867
|
+
throw new RwsError(`getControllerIdentity failed: ${String(e)}`, 'UNKNOWN');
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Read the controller date and time.
|
|
872
|
+
* Returns a ControllerClock with the datetime string in 'YYYY-MM-DD T HH:MM:SS' format (UTC).
|
|
873
|
+
*/
|
|
874
|
+
async getControllerClock() {
|
|
875
|
+
try {
|
|
876
|
+
const { body } = await this.session.get(pathClockInfo());
|
|
877
|
+
return parseControllerClock(body);
|
|
878
|
+
}
|
|
879
|
+
catch (e) {
|
|
880
|
+
if (e instanceof RwsError)
|
|
881
|
+
throw e;
|
|
882
|
+
throw new RwsError(`getControllerClock failed: ${String(e)}`, 'UNKNOWN');
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Set the controller date and time (UTC).
|
|
887
|
+
* @param year - Full year, e.g. 2024
|
|
888
|
+
* @param month - Month 1–12
|
|
889
|
+
* @param day - Day 1–31
|
|
890
|
+
* @param hour - Hour 0–23
|
|
891
|
+
* @param min - Minute 0–59
|
|
892
|
+
* @param sec - Second 0–59
|
|
893
|
+
*/
|
|
894
|
+
async setControllerClock(year, month, day, hour, min, sec) {
|
|
895
|
+
try {
|
|
896
|
+
const { path, body } = mapSetControllerClock(year, month, day, hour, min, sec);
|
|
897
|
+
await this.session.put(path, new TextEncoder().encode(body));
|
|
898
|
+
}
|
|
899
|
+
catch (e) {
|
|
900
|
+
if (e instanceof RwsError)
|
|
901
|
+
throw e;
|
|
902
|
+
throw new RwsError(`setControllerClock failed: ${String(e)}`, 'UNKNOWN');
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
// ─── Event log ──────────────────────────────────────────────────────────────
|
|
906
|
+
/**
|
|
907
|
+
* Retrieve event log messages from the controller.
|
|
908
|
+
* Domain 0 is the main system log (up to 1000 entries).
|
|
909
|
+
* Messages are returned newest-first (LIFO order).
|
|
910
|
+
*
|
|
911
|
+
* @param domain - Log domain number; default 0 (main system log)
|
|
912
|
+
* @param lang - Language for message text; default 'en'
|
|
913
|
+
*/
|
|
914
|
+
async getEventLog(domain = 0, lang = 'en') {
|
|
915
|
+
try {
|
|
916
|
+
const { body } = await this.session.get(pathElogMessages(domain, lang));
|
|
917
|
+
return parseElogMessages(body);
|
|
918
|
+
}
|
|
919
|
+
catch (e) {
|
|
920
|
+
if (e instanceof RwsError)
|
|
921
|
+
throw e;
|
|
922
|
+
throw new RwsError(`getEventLog failed: ${String(e)}`, 'UNKNOWN');
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Clear event log messages in a specific domain.
|
|
927
|
+
* @param domain - Log domain number; default 0 (main system log)
|
|
928
|
+
*/
|
|
929
|
+
async clearEventLog(domain = 0) {
|
|
930
|
+
try {
|
|
931
|
+
const { path, body } = mapClearElogDomain(domain);
|
|
932
|
+
await this.session.post(path, body);
|
|
933
|
+
}
|
|
934
|
+
catch (e) {
|
|
935
|
+
if (e instanceof RwsError)
|
|
936
|
+
throw e;
|
|
937
|
+
throw new RwsError(`clearEventLog failed: ${String(e)}`, 'UNKNOWN');
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Clear ALL event log messages across all domains.
|
|
942
|
+
*/
|
|
943
|
+
async clearAllEventLogs() {
|
|
944
|
+
try {
|
|
945
|
+
const { path, body } = mapClearAllElogs();
|
|
946
|
+
await this.session.post(path, body);
|
|
947
|
+
}
|
|
948
|
+
catch (e) {
|
|
949
|
+
if (e instanceof RwsError)
|
|
950
|
+
throw e;
|
|
951
|
+
throw new RwsError(`clearAllEventLogs failed: ${String(e)}`, 'UNKNOWN');
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
// ─── Mastership ──────────────────────────────────────────────────────────────
|
|
955
|
+
/**
|
|
956
|
+
* Request mastership on a domain.
|
|
957
|
+
* Must call releaseMastership when done. Operations that modify controller state
|
|
958
|
+
* (motor on/off, speed ratio, etc.) require mastership on the appropriate domain.
|
|
959
|
+
*
|
|
960
|
+
* @param domain - 'cfg' | 'motion' | 'rapid'
|
|
961
|
+
*/
|
|
962
|
+
async requestMastership(domain) {
|
|
963
|
+
try {
|
|
964
|
+
const { path, body } = mapRequestMastership(domain);
|
|
965
|
+
await this.session.post(path, body);
|
|
966
|
+
}
|
|
967
|
+
catch (e) {
|
|
968
|
+
if (e instanceof RwsError)
|
|
969
|
+
throw e;
|
|
970
|
+
throw new RwsError(`requestMastership failed: ${String(e)}`, 'UNKNOWN');
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Release mastership on a domain.
|
|
975
|
+
* Always call this after requestMastership, even if the operation failed.
|
|
976
|
+
*
|
|
977
|
+
* @param domain - 'cfg' | 'motion' | 'rapid'
|
|
978
|
+
*/
|
|
979
|
+
async releaseMastership(domain) {
|
|
980
|
+
try {
|
|
981
|
+
const { path, body } = mapReleaseMastership(domain);
|
|
982
|
+
await this.session.post(path, body);
|
|
983
|
+
}
|
|
984
|
+
catch (e) {
|
|
985
|
+
if (e instanceof RwsError)
|
|
986
|
+
throw e;
|
|
987
|
+
throw new RwsError(`releaseMastership failed: ${String(e)}`, 'UNKNOWN');
|
|
988
|
+
}
|
|
989
|
+
}
|
|
366
990
|
// ─── Subscriptions ──────────────────────────────────────────────────────────
|
|
367
991
|
/**
|
|
368
992
|
* Subscribe to one or more RWS resource events via WebSocket.
|