abb-rws-client 0.1.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/LICENSE +21 -0
- package/README.md +261 -0
- package/dist/HttpSession.d.ts +92 -0
- package/dist/HttpSession.d.ts.map +1 -0
- package/dist/HttpSession.js +321 -0
- package/dist/HttpSession.js.map +1 -0
- package/dist/ResourceMapper.d.ts +95 -0
- package/dist/ResourceMapper.d.ts.map +1 -0
- package/dist/ResourceMapper.js +146 -0
- package/dist/ResourceMapper.js.map +1 -0
- package/dist/ResponseParser.d.ts +73 -0
- package/dist/ResponseParser.d.ts.map +1 -0
- package/dist/ResponseParser.js +294 -0
- package/dist/ResponseParser.js.map +1 -0
- package/dist/RwsClient.d.ts +156 -0
- package/dist/RwsClient.d.ts.map +1 -0
- package/dist/RwsClient.js +353 -0
- package/dist/RwsClient.js.map +1 -0
- package/dist/WsSubscriber.d.ts +33 -0
- package/dist/WsSubscriber.d.ts.map +1 -0
- package/dist/WsSubscriber.js +234 -0
- package/dist/WsSubscriber.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +90 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HttpSession — HTTP communication layer for ABB IRC5 controllers.
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - HTTP Digest Authentication (RFC 2617) implemented from scratch using node:crypto
|
|
6
|
+
* - ABBCX + -http-session- cookie management
|
|
7
|
+
* - Request queue enforcing minimum interval between requests (<20 req/sec RWS limit)
|
|
8
|
+
* - Automatic re-authentication on session expiry (5-minute inactivity)
|
|
9
|
+
* - 401 retry with fresh digest handshake; 503 retry with 200ms backoff
|
|
10
|
+
* - AbortController-based timeout
|
|
11
|
+
*
|
|
12
|
+
* Uses Node 18+ built-in fetch and node:crypto. Zero external dependencies.
|
|
13
|
+
*/
|
|
14
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
15
|
+
import { RwsError } from './types.js';
|
|
16
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
17
|
+
function md5(s) {
|
|
18
|
+
return createHash('md5').update(s).digest('hex');
|
|
19
|
+
}
|
|
20
|
+
function sleep(ms) {
|
|
21
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
22
|
+
}
|
|
23
|
+
// ─── HttpSession ─────────────────────────────────────────────────────────────
|
|
24
|
+
export class HttpSession {
|
|
25
|
+
baseUrl;
|
|
26
|
+
username;
|
|
27
|
+
password;
|
|
28
|
+
requestIntervalMs;
|
|
29
|
+
timeoutMs;
|
|
30
|
+
/** Stored session cookies: '-http-session-' and 'ABBCX' */
|
|
31
|
+
cookies = new Map();
|
|
32
|
+
/** Last parsed digest challenge from WWW-Authenticate */
|
|
33
|
+
digestChallenge = null;
|
|
34
|
+
/** Nonce use counter — reset to 0 whenever a new nonce is received */
|
|
35
|
+
nonceCount = 0;
|
|
36
|
+
/** Timestamp of the most recent request sent */
|
|
37
|
+
lastRequestTime = 0;
|
|
38
|
+
/** Timestamp of the most recent successful response — used for session expiry */
|
|
39
|
+
lastActivityTime = 0;
|
|
40
|
+
/** Promise chain that serialises all outbound requests */
|
|
41
|
+
requestQueue = Promise.resolve();
|
|
42
|
+
/** 5-minute session inactivity timeout (milliseconds) */
|
|
43
|
+
static SESSION_TIMEOUT_MS = 5 * 60 * 1000;
|
|
44
|
+
constructor(options) {
|
|
45
|
+
this.baseUrl = options.baseUrl;
|
|
46
|
+
this.username = options.username;
|
|
47
|
+
this.password = options.password;
|
|
48
|
+
this.requestIntervalMs = options.requestIntervalMs;
|
|
49
|
+
this.timeoutMs = options.timeoutMs;
|
|
50
|
+
}
|
|
51
|
+
// ─── Public HTTP methods ────────────────────────────────────────────────────
|
|
52
|
+
get(path) {
|
|
53
|
+
return this.enqueue(() => this.execute('GET', path));
|
|
54
|
+
}
|
|
55
|
+
post(path, body) {
|
|
56
|
+
return this.enqueue(() => this.execute('POST', path, body));
|
|
57
|
+
}
|
|
58
|
+
put(path, body) {
|
|
59
|
+
return this.enqueue(() => this.execute('PUT', path, body));
|
|
60
|
+
}
|
|
61
|
+
delete(path) {
|
|
62
|
+
return this.enqueue(() => this.execute('DELETE', path));
|
|
63
|
+
}
|
|
64
|
+
/** Returns the current cookie string for use in WebSocket connections */
|
|
65
|
+
getCookieHeader() {
|
|
66
|
+
return this.buildCookieHeader();
|
|
67
|
+
}
|
|
68
|
+
/** Clear all session state (called on disconnect) */
|
|
69
|
+
clearSession() {
|
|
70
|
+
this.cookies.clear();
|
|
71
|
+
this.digestChallenge = null;
|
|
72
|
+
this.nonceCount = 0;
|
|
73
|
+
this.lastActivityTime = 0;
|
|
74
|
+
}
|
|
75
|
+
// ─── Request queue ──────────────────────────────────────────────────────────
|
|
76
|
+
/**
|
|
77
|
+
* Append a function to the serial request queue, enforcing the minimum interval
|
|
78
|
+
* between requests. Error suppression on `this.requestQueue` (not on `result`)
|
|
79
|
+
* ensures queue continues processing even when individual requests fail.
|
|
80
|
+
*/
|
|
81
|
+
enqueue(fn) {
|
|
82
|
+
const result = this.requestQueue.then(async () => {
|
|
83
|
+
const elapsed = Date.now() - this.lastRequestTime;
|
|
84
|
+
if (this.requestIntervalMs > 0 && elapsed < this.requestIntervalMs) {
|
|
85
|
+
await sleep(this.requestIntervalMs - elapsed);
|
|
86
|
+
}
|
|
87
|
+
this.lastRequestTime = Date.now();
|
|
88
|
+
return fn();
|
|
89
|
+
});
|
|
90
|
+
// Detach error from the shared queue chain so a failed request does not block
|
|
91
|
+
// subsequent ones. Callers still receive the rejection via `result`.
|
|
92
|
+
this.requestQueue = result.then(() => undefined, () => undefined);
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
// ─── Core request execution ─────────────────────────────────────────────────
|
|
96
|
+
async execute(method, path, body) {
|
|
97
|
+
// Auto re-authenticate if the session may have expired
|
|
98
|
+
if (this.isSessionExpired()) {
|
|
99
|
+
this.cookies.clear();
|
|
100
|
+
this.digestChallenge = null;
|
|
101
|
+
this.nonceCount = 0;
|
|
102
|
+
}
|
|
103
|
+
let response = await this.rawFetch(method, path, body);
|
|
104
|
+
// 401 → perform digest handshake then retry once
|
|
105
|
+
if (response.status === 401) {
|
|
106
|
+
const wwwAuth = response.headers.get('www-authenticate');
|
|
107
|
+
if (!wwwAuth) {
|
|
108
|
+
throw new RwsError('401 without WWW-Authenticate header', 'AUTH_FAILED', 401);
|
|
109
|
+
}
|
|
110
|
+
this.digestChallenge = this.parseDigestChallenge(wwwAuth);
|
|
111
|
+
this.nonceCount = 0;
|
|
112
|
+
response = await this.rawFetch(method, path, body);
|
|
113
|
+
if (response.status === 401) {
|
|
114
|
+
// Second 401 — credentials are wrong
|
|
115
|
+
throw new RwsError('Authentication failed — check username and password', 'AUTH_FAILED', 401);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// 503 → wait 200ms and retry once
|
|
119
|
+
if (response.status === 503) {
|
|
120
|
+
await sleep(200);
|
|
121
|
+
response = await this.rawFetch(method, path, body);
|
|
122
|
+
if (response.status === 503) {
|
|
123
|
+
throw new RwsError('Controller busy (503) — retry later', 'CONTROLLER_BUSY', 503);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!this.isOk(response.status)) {
|
|
127
|
+
const bodyText = await response.text().catch(() => '');
|
|
128
|
+
throw new RwsError(`HTTP ${response.status} from ${method} ${path}`, this.mapHttpStatus(response.status), response.status, bodyText);
|
|
129
|
+
}
|
|
130
|
+
// Store cookies from response
|
|
131
|
+
this.storeCookies(response.headers);
|
|
132
|
+
this.lastActivityTime = Date.now();
|
|
133
|
+
const bodyText = await response.text().catch(() => '');
|
|
134
|
+
return { status: response.status, body: bodyText, headers: response.headers };
|
|
135
|
+
}
|
|
136
|
+
/** Issue a single HTTP request with digest auth header if we have a challenge */
|
|
137
|
+
async rawFetch(method, path, body) {
|
|
138
|
+
const url = `${this.baseUrl}${path}`;
|
|
139
|
+
const controller = new AbortController();
|
|
140
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
141
|
+
const headers = {
|
|
142
|
+
Accept: 'application/xhtml+xml, application/json',
|
|
143
|
+
};
|
|
144
|
+
if (body !== undefined) {
|
|
145
|
+
if (body instanceof Uint8Array) {
|
|
146
|
+
headers['Content-Type'] = 'application/octet-stream';
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
// Always set Content-Type for form submissions, even with empty body (e.g. resetpp)
|
|
150
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const cookieHeader = this.buildCookieHeader();
|
|
154
|
+
if (cookieHeader) {
|
|
155
|
+
headers['Cookie'] = cookieHeader;
|
|
156
|
+
}
|
|
157
|
+
if (this.digestChallenge) {
|
|
158
|
+
// The URI in the Authorization header and HA2 computation must be the path + query,
|
|
159
|
+
// NOT the full URL with scheme and host — a common implementation mistake.
|
|
160
|
+
headers['Authorization'] = this.buildAuthHeader(method, path);
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
return await fetch(url, {
|
|
164
|
+
method,
|
|
165
|
+
headers,
|
|
166
|
+
body: body !== undefined ? body : undefined,
|
|
167
|
+
signal: controller.signal,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch (e) {
|
|
171
|
+
if (e instanceof Error && e.name === 'AbortError') {
|
|
172
|
+
throw new RwsError(`Request timed out after ${this.timeoutMs}ms: ${method} ${path}`, 'NETWORK_ERROR');
|
|
173
|
+
}
|
|
174
|
+
throw new RwsError(`Network error: ${String(e)}`, 'NETWORK_ERROR');
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
clearTimeout(timer);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// ─── Digest auth ────────────────────────────────────────────────────────────
|
|
181
|
+
/**
|
|
182
|
+
* Parse the WWW-Authenticate: Digest ... header into a DigestChallenge.
|
|
183
|
+
* Handles both quoted and unquoted parameter values per RFC 2617.
|
|
184
|
+
*/
|
|
185
|
+
parseDigestChallenge(header) {
|
|
186
|
+
const prefix = 'Digest ';
|
|
187
|
+
if (!header.toLowerCase().startsWith('digest ')) {
|
|
188
|
+
throw new RwsError(`Unsupported auth scheme: "${header}"`, 'AUTH_FAILED');
|
|
189
|
+
}
|
|
190
|
+
const paramString = header.slice(prefix.length);
|
|
191
|
+
// Match key="quoted value" or key=unquoted-value
|
|
192
|
+
const paramPattern = /(\w+)=(?:"([^"]*)"|([\w.!@#$%^&*()\-_+=[\]{};:'<>,./\\?~`|]+))/g;
|
|
193
|
+
const params = {};
|
|
194
|
+
let m;
|
|
195
|
+
while ((m = paramPattern.exec(paramString)) !== null) {
|
|
196
|
+
// m[2] = quoted value, m[3] = unquoted value
|
|
197
|
+
params[m[1].toLowerCase()] = m[2] ?? m[3] ?? '';
|
|
198
|
+
}
|
|
199
|
+
if (!params['realm'])
|
|
200
|
+
throw new RwsError('WWW-Authenticate missing realm', 'AUTH_FAILED');
|
|
201
|
+
if (!params['nonce'])
|
|
202
|
+
throw new RwsError('WWW-Authenticate missing nonce', 'AUTH_FAILED');
|
|
203
|
+
return {
|
|
204
|
+
realm: params['realm'],
|
|
205
|
+
nonce: params['nonce'],
|
|
206
|
+
opaque: params['opaque'],
|
|
207
|
+
qop: params['qop'],
|
|
208
|
+
algorithm: params['algorithm'] ?? 'MD5',
|
|
209
|
+
stale: params['stale']?.toLowerCase() === 'true',
|
|
210
|
+
domain: params['domain'],
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Build the Authorization: Digest ... header value for the given request.
|
|
215
|
+
* Increments the nonce use counter (nc).
|
|
216
|
+
*
|
|
217
|
+
* RFC 2617 §3.2.2:
|
|
218
|
+
* HA1 = MD5(username:realm:password)
|
|
219
|
+
* HA2 = MD5(method:digestURI)
|
|
220
|
+
* response = MD5(HA1:nonce:nc:cnonce:qop:HA2) — when qop=auth
|
|
221
|
+
* response = MD5(HA1:nonce:HA2) — RFC 2069 compat (no qop)
|
|
222
|
+
*
|
|
223
|
+
* Important: the space in 'Default User' is NOT percent-encoded for HA1.
|
|
224
|
+
* The nc value is NOT quoted in the Authorization header.
|
|
225
|
+
* The URI is path+query only, not scheme://host:port/path.
|
|
226
|
+
*/
|
|
227
|
+
buildAuthHeader(method, uri) {
|
|
228
|
+
const challenge = this.digestChallenge;
|
|
229
|
+
const nc = (++this.nonceCount).toString(16).padStart(8, '0');
|
|
230
|
+
const cnonce = randomBytes(16).toString('hex');
|
|
231
|
+
const ha1 = md5(`${this.username}:${challenge.realm}:${this.password}`);
|
|
232
|
+
const ha2 = md5(`${method}:${uri}`);
|
|
233
|
+
let responseHash;
|
|
234
|
+
if (challenge.qop === 'auth' || challenge.qop === 'auth-int') {
|
|
235
|
+
// RFC 2617 qop mode
|
|
236
|
+
responseHash = md5(`${ha1}:${challenge.nonce}:${nc}:${cnonce}:auth:${ha2}`);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
// RFC 2069 compat — no qop
|
|
240
|
+
responseHash = md5(`${ha1}:${challenge.nonce}:${ha2}`);
|
|
241
|
+
}
|
|
242
|
+
const parts = [
|
|
243
|
+
`Digest username="${this.username}"`,
|
|
244
|
+
`realm="${challenge.realm}"`,
|
|
245
|
+
`nonce="${challenge.nonce}"`,
|
|
246
|
+
`uri="${uri}"`,
|
|
247
|
+
`algorithm=MD5`, // nc is NOT quoted
|
|
248
|
+
`nc=${nc}`,
|
|
249
|
+
`cnonce="${cnonce}"`,
|
|
250
|
+
`response="${responseHash}"`,
|
|
251
|
+
];
|
|
252
|
+
if (challenge.qop) {
|
|
253
|
+
parts.push(`qop=auth`);
|
|
254
|
+
}
|
|
255
|
+
if (challenge.opaque) {
|
|
256
|
+
parts.push(`opaque="${challenge.opaque}"`);
|
|
257
|
+
}
|
|
258
|
+
return parts.join(', ');
|
|
259
|
+
}
|
|
260
|
+
// ─── Cookie management ───────────────────────────────────────────────────────
|
|
261
|
+
/**
|
|
262
|
+
* Extract Set-Cookie headers from a response and store name=value pairs.
|
|
263
|
+
* Uses Headers.getSetCookie() (Node 18.14.1+) to correctly handle multiple
|
|
264
|
+
* Set-Cookie headers. Falls back to headers.get('set-cookie') on older Node 18,
|
|
265
|
+
* though this may misparse cookie values containing commas.
|
|
266
|
+
*/
|
|
267
|
+
storeCookies(headers) {
|
|
268
|
+
let setCookies;
|
|
269
|
+
// getSetCookie() is the WHATWG-spec method returning string[] — available Node 18.14.1+
|
|
270
|
+
if (typeof headers.getSetCookie === 'function') {
|
|
271
|
+
setCookies = headers.getSetCookie();
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
// Fallback: merge header may be comma-split incorrectly for complex cookie values,
|
|
275
|
+
// but acceptable for the simple ABBCX and -http-session- cookies IRC5 sends.
|
|
276
|
+
const merged = headers.get('set-cookie');
|
|
277
|
+
setCookies = merged ? merged.split(/,\s*(?=[^;,]+=)/) : [];
|
|
278
|
+
}
|
|
279
|
+
for (const cookie of setCookies) {
|
|
280
|
+
// Only take the name=value part before the first ';'
|
|
281
|
+
const [nameValue] = cookie.split(';');
|
|
282
|
+
if (!nameValue)
|
|
283
|
+
continue;
|
|
284
|
+
const eqIdx = nameValue.indexOf('=');
|
|
285
|
+
if (eqIdx === -1)
|
|
286
|
+
continue;
|
|
287
|
+
const name = nameValue.slice(0, eqIdx).trim();
|
|
288
|
+
const value = nameValue.slice(eqIdx + 1).trim();
|
|
289
|
+
if (name)
|
|
290
|
+
this.cookies.set(name, value);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
buildCookieHeader() {
|
|
294
|
+
return [...this.cookies.entries()].map(([k, v]) => `${k}=${v}`).join('; ');
|
|
295
|
+
}
|
|
296
|
+
// ─── Session expiry ──────────────────────────────────────────────────────────
|
|
297
|
+
isSessionExpired() {
|
|
298
|
+
return (this.lastActivityTime > 0 &&
|
|
299
|
+
Date.now() - this.lastActivityTime > HttpSession.SESSION_TIMEOUT_MS);
|
|
300
|
+
}
|
|
301
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
302
|
+
isOk(status) {
|
|
303
|
+
return status >= 200 && status < 300;
|
|
304
|
+
}
|
|
305
|
+
mapHttpStatus(status) {
|
|
306
|
+
switch (status) {
|
|
307
|
+
case 401:
|
|
308
|
+
case 403:
|
|
309
|
+
return 'AUTH_FAILED';
|
|
310
|
+
case 404:
|
|
311
|
+
return 'MODULE_NOT_FOUND';
|
|
312
|
+
case 429:
|
|
313
|
+
return 'RATE_LIMITED';
|
|
314
|
+
case 503:
|
|
315
|
+
return 'CONTROLLER_BUSY';
|
|
316
|
+
default:
|
|
317
|
+
return 'UNKNOWN';
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
//# sourceMappingURL=HttpSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpSession.js","sourceRoot":"","sources":["../src/HttpSession.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResourceMapper — pure functions that map RWS operations to URL paths and
|
|
3
|
+
* application/x-www-form-urlencoded request bodies.
|
|
4
|
+
*
|
|
5
|
+
* No HTTP, no state. All functions are individually exported for tree-shaking.
|
|
6
|
+
* Targets RWS 1.0 (RobotWare 6.x). Not compatible with RWS 2.0 / RobotWare 7.x.
|
|
7
|
+
*/
|
|
8
|
+
/** Path to read the current controller state (motoron, motoroff, etc.) */
|
|
9
|
+
export declare function controllerState(): string;
|
|
10
|
+
/** Path to read the current operation mode (AUTO, MANR, MANF) */
|
|
11
|
+
export declare function operationMode(): string;
|
|
12
|
+
/** Path to list all RAPID tasks */
|
|
13
|
+
export declare function rapidTasks(): string;
|
|
14
|
+
/** Path to read the RAPID execution state (running / stopped) */
|
|
15
|
+
export declare function rapidExecutionState(): string;
|
|
16
|
+
/** Path + body to start RAPID program execution */
|
|
17
|
+
export declare function startRapid(): {
|
|
18
|
+
path: string;
|
|
19
|
+
body: string;
|
|
20
|
+
};
|
|
21
|
+
/** Path + body to stop RAPID program execution */
|
|
22
|
+
export declare function stopRapid(): {
|
|
23
|
+
path: string;
|
|
24
|
+
body: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Path + body to reset the RAPID program pointer to main.
|
|
28
|
+
* The body is empty but Content-Type must still be application/x-www-form-urlencoded.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resetRapid(): {
|
|
31
|
+
path: string;
|
|
32
|
+
body: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Path to read joint-space positions for a mechanical unit.
|
|
36
|
+
* @param mechunit - Default 'ROB_1' (the primary robot mechanical unit)
|
|
37
|
+
*/
|
|
38
|
+
export declare function jointTarget(mechunit?: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Path to read Cartesian robot target.
|
|
41
|
+
* @param mechunit - Default 'ROB_1'
|
|
42
|
+
* @param tool - Active tool frame; default 'tool0'
|
|
43
|
+
* @param wobj - Active work object frame; default 'wobj0'
|
|
44
|
+
*/
|
|
45
|
+
export declare function robTarget(mechunit?: string, tool?: string, wobj?: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Path + body to load a RAPID module into a task.
|
|
48
|
+
* @param taskName - RAPID task name, e.g. 'T_ROB1'
|
|
49
|
+
* @param modulePath - Controller filesystem path, e.g. '$HOME/MyMod.mod'
|
|
50
|
+
* Do not double-encode the '$' prefix — the controller expects it literal.
|
|
51
|
+
*/
|
|
52
|
+
export declare function loadModule(taskName: string, modulePath: string, replace?: boolean): {
|
|
53
|
+
path: string;
|
|
54
|
+
body: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Path to retrieve details about a specific loaded module.
|
|
58
|
+
* @param taskName - RAPID task name
|
|
59
|
+
* @param moduleName - Module name (without path or extension)
|
|
60
|
+
*/
|
|
61
|
+
export declare function getModule(taskName: string, moduleName: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Path to list all modules loaded in a RAPID task.
|
|
64
|
+
* @param taskName - RAPID task name
|
|
65
|
+
*/
|
|
66
|
+
export declare function listModules(taskName: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* PUT path for uploading a file to the controller filesystem.
|
|
69
|
+
* Use '$HOME/' prefix to target the controller home directory.
|
|
70
|
+
* @param remotePath - Controller path, e.g. '$HOME/MyMod.mod' or 'HOME/MyMod.mod'
|
|
71
|
+
* A leading '/' is stripped to avoid double-slash in the URL.
|
|
72
|
+
*/
|
|
73
|
+
export declare function uploadFile(remotePath: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Path to read a digital/analog I/O signal value.
|
|
76
|
+
*
|
|
77
|
+
* @param network - I/O network name, e.g. 'Local'. Pass '' for virtual/flat signals.
|
|
78
|
+
* @param device - I/O device name, e.g. 'DRV_1'. Pass '' for virtual/flat signals.
|
|
79
|
+
* @param name - Signal name, e.g. 'DI_1'
|
|
80
|
+
*/
|
|
81
|
+
export declare function signal(network: string, device: string, name: string): string;
|
|
82
|
+
/**
|
|
83
|
+
* Path to write a digital/analog I/O signal value.
|
|
84
|
+
* The body with lvalue={value} is supplied by the caller (RwsClient.writeSignal).
|
|
85
|
+
*
|
|
86
|
+
* @param network - I/O network name. Pass '' for virtual/flat signals.
|
|
87
|
+
* @param device - I/O device name. Pass '' for virtual/flat signals.
|
|
88
|
+
* @param name - Signal name
|
|
89
|
+
*/
|
|
90
|
+
export declare function setSignal(network: string, device: string, name: string): {
|
|
91
|
+
path: string;
|
|
92
|
+
};
|
|
93
|
+
/** Path to create a new WebSocket subscription (POST /subscription) */
|
|
94
|
+
export declare function subscriptions(): string;
|
|
95
|
+
//# sourceMappingURL=ResourceMapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceMapper.d.ts","sourceRoot":"","sources":["../src/ResourceMapper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,0EAA0E;AAC1E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,iEAAiE;AACjE,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAID,mCAAmC;AACnC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,iEAAiE;AACjE,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,mDAAmD;AACnD,wBAAgB,UAAU,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAK3D;AAED,kDAAkD;AAClD,wBAAgB,SAAS,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAK1D;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAK3D;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,SAAU,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,QAAQ,SAAU,EAAE,IAAI,SAAU,EAAE,IAAI,SAAU,GAAG,MAAM,CAEpF;AAID;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAKhH;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpD;AAID;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAIrD;AAeD;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAIzF;AAID,uEAAuE;AACvE,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResourceMapper — pure functions that map RWS operations to URL paths and
|
|
3
|
+
* application/x-www-form-urlencoded request bodies.
|
|
4
|
+
*
|
|
5
|
+
* No HTTP, no state. All functions are individually exported for tree-shaking.
|
|
6
|
+
* Targets RWS 1.0 (RobotWare 6.x). Not compatible with RWS 2.0 / RobotWare 7.x.
|
|
7
|
+
*/
|
|
8
|
+
// ─── Controller ──────────────────────────────────────────────────────────────
|
|
9
|
+
/** Path to read the current controller state (motoron, motoroff, etc.) */
|
|
10
|
+
export function controllerState() {
|
|
11
|
+
return '/rw/panel/ctrlstate';
|
|
12
|
+
}
|
|
13
|
+
/** Path to read the current operation mode (AUTO, MANR, MANF) */
|
|
14
|
+
export function operationMode() {
|
|
15
|
+
return '/rw/panel/opmode';
|
|
16
|
+
}
|
|
17
|
+
// ─── RAPID ───────────────────────────────────────────────────────────────────
|
|
18
|
+
/** Path to list all RAPID tasks */
|
|
19
|
+
export function rapidTasks() {
|
|
20
|
+
return '/rw/rapid/tasks';
|
|
21
|
+
}
|
|
22
|
+
/** Path to read the RAPID execution state (running / stopped) */
|
|
23
|
+
export function rapidExecutionState() {
|
|
24
|
+
return '/rw/rapid/execution';
|
|
25
|
+
}
|
|
26
|
+
/** Path + body to start RAPID program execution */
|
|
27
|
+
export function startRapid() {
|
|
28
|
+
return {
|
|
29
|
+
path: '/rw/rapid/execution?action=start',
|
|
30
|
+
body: 'regain=continue&execmode=continue&cycle=forever&condition=none&stopatbp=disabled&alltaskbytsp=false',
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Path + body to stop RAPID program execution */
|
|
34
|
+
export function stopRapid() {
|
|
35
|
+
return {
|
|
36
|
+
path: '/rw/rapid/execution?action=stop',
|
|
37
|
+
body: 'stopmode=stop',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Path + body to reset the RAPID program pointer to main.
|
|
42
|
+
* The body is empty but Content-Type must still be application/x-www-form-urlencoded.
|
|
43
|
+
*/
|
|
44
|
+
export function resetRapid() {
|
|
45
|
+
return {
|
|
46
|
+
path: '/rw/rapid/execution?action=resetpp',
|
|
47
|
+
body: '',
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// ─── Motion ──────────────────────────────────────────────────────────────────
|
|
51
|
+
/**
|
|
52
|
+
* Path to read joint-space positions for a mechanical unit.
|
|
53
|
+
* @param mechunit - Default 'ROB_1' (the primary robot mechanical unit)
|
|
54
|
+
*/
|
|
55
|
+
export function jointTarget(mechunit = 'ROB_1') {
|
|
56
|
+
return `/rw/motionsystem/mechunits/${encodeURIComponent(mechunit)}/jointtarget`;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Path to read Cartesian robot target.
|
|
60
|
+
* @param mechunit - Default 'ROB_1'
|
|
61
|
+
* @param tool - Active tool frame; default 'tool0'
|
|
62
|
+
* @param wobj - Active work object frame; default 'wobj0'
|
|
63
|
+
*/
|
|
64
|
+
export function robTarget(mechunit = 'ROB_1', tool = 'tool0', wobj = 'wobj0') {
|
|
65
|
+
return `/rw/motionsystem/mechunits/${encodeURIComponent(mechunit)}/robtarget?tool=${encodeURIComponent(tool)}&wobj=${encodeURIComponent(wobj)}`;
|
|
66
|
+
}
|
|
67
|
+
// ─── Modules ─────────────────────────────────────────────────────────────────
|
|
68
|
+
/**
|
|
69
|
+
* Path + body to load a RAPID module into a task.
|
|
70
|
+
* @param taskName - RAPID task name, e.g. 'T_ROB1'
|
|
71
|
+
* @param modulePath - Controller filesystem path, e.g. '$HOME/MyMod.mod'
|
|
72
|
+
* Do not double-encode the '$' prefix — the controller expects it literal.
|
|
73
|
+
*/
|
|
74
|
+
export function loadModule(taskName, modulePath, replace = false) {
|
|
75
|
+
return {
|
|
76
|
+
path: `/rw/rapid/tasks/${encodeURIComponent(taskName)}?action=loadmod`,
|
|
77
|
+
body: `modulepath=${encodeURIComponent(modulePath)}&replace=${replace}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Path to retrieve details about a specific loaded module.
|
|
82
|
+
* @param taskName - RAPID task name
|
|
83
|
+
* @param moduleName - Module name (without path or extension)
|
|
84
|
+
*/
|
|
85
|
+
export function getModule(taskName, moduleName) {
|
|
86
|
+
return `/rw/rapid/tasks/${encodeURIComponent(taskName)}/modules/${encodeURIComponent(moduleName)}`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Path to list all modules loaded in a RAPID task.
|
|
90
|
+
* @param taskName - RAPID task name
|
|
91
|
+
*/
|
|
92
|
+
export function listModules(taskName) {
|
|
93
|
+
return `/rw/rapid/modules?task=${encodeURIComponent(taskName)}`;
|
|
94
|
+
}
|
|
95
|
+
// ─── File system ─────────────────────────────────────────────────────────────
|
|
96
|
+
/**
|
|
97
|
+
* PUT path for uploading a file to the controller filesystem.
|
|
98
|
+
* Use '$HOME/' prefix to target the controller home directory.
|
|
99
|
+
* @param remotePath - Controller path, e.g. '$HOME/MyMod.mod' or 'HOME/MyMod.mod'
|
|
100
|
+
* A leading '/' is stripped to avoid double-slash in the URL.
|
|
101
|
+
*/
|
|
102
|
+
export function uploadFile(remotePath) {
|
|
103
|
+
// Strip a leading '/' so the result is /fileservice/path, not /fileservice//path
|
|
104
|
+
const normalised = remotePath.replace(/^\//, '');
|
|
105
|
+
return `/fileservice/${normalised}`;
|
|
106
|
+
}
|
|
107
|
+
// ─── I/O ─────────────────────────────────────────────────────────────────────
|
|
108
|
+
/**
|
|
109
|
+
* Build the signal path segment from optional network/device/name.
|
|
110
|
+
* If network and device are empty, the signal is a virtual flat signal (no prefix).
|
|
111
|
+
*/
|
|
112
|
+
function signalPath(network, device, name) {
|
|
113
|
+
if (network && device) {
|
|
114
|
+
return `/rw/iosystem/signals/${encodeURIComponent(network)}/${encodeURIComponent(device)}/${encodeURIComponent(name)}`;
|
|
115
|
+
}
|
|
116
|
+
return `/rw/iosystem/signals/${encodeURIComponent(name)}`;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Path to read a digital/analog I/O signal value.
|
|
120
|
+
*
|
|
121
|
+
* @param network - I/O network name, e.g. 'Local'. Pass '' for virtual/flat signals.
|
|
122
|
+
* @param device - I/O device name, e.g. 'DRV_1'. Pass '' for virtual/flat signals.
|
|
123
|
+
* @param name - Signal name, e.g. 'DI_1'
|
|
124
|
+
*/
|
|
125
|
+
export function signal(network, device, name) {
|
|
126
|
+
return signalPath(network, device, name);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Path to write a digital/analog I/O signal value.
|
|
130
|
+
* The body with lvalue={value} is supplied by the caller (RwsClient.writeSignal).
|
|
131
|
+
*
|
|
132
|
+
* @param network - I/O network name. Pass '' for virtual/flat signals.
|
|
133
|
+
* @param device - I/O device name. Pass '' for virtual/flat signals.
|
|
134
|
+
* @param name - Signal name
|
|
135
|
+
*/
|
|
136
|
+
export function setSignal(network, device, name) {
|
|
137
|
+
return {
|
|
138
|
+
path: `${signalPath(network, device, name)}?action=set`,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// ─── Subscriptions ───────────────────────────────────────────────────────────
|
|
142
|
+
/** Path to create a new WebSocket subscription (POST /subscription) */
|
|
143
|
+
export function subscriptions() {
|
|
144
|
+
return '/subscription';
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=ResourceMapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceMapper.js","sourceRoot":"","sources":["../src/ResourceMapper.ts"],"names":[],"mappings":"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"}
|