@synapticon/motion-master-client 2.3.0-beta.0 → 6.0.0-alpha.110
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/dist/api-error.d.ts +25 -0
- package/dist/api-error.js +52 -0
- package/dist/client.d.ts +20 -0
- package/dist/client.js +37 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +8 -0
- package/dist/eni.d.ts +197 -0
- package/dist/eni.js +61 -0
- package/dist/generated/Api.d.ts +1886 -0
- package/dist/generated/Api.js +1293 -0
- package/dist/generated/data-contracts.d.ts +2282 -0
- package/dist/generated/data-contracts.js +12 -0
- package/dist/generated/http-client.d.ts +60 -0
- package/dist/generated/http-client.js +171 -0
- package/dist/hex.d.ts +2 -0
- package/dist/hex.js +20 -0
- package/dist/index.d.ts +13 -7
- package/dist/index.js +20 -22
- package/dist/lan.d.ts +4 -0
- package/dist/lan.js +59 -0
- package/dist/mmpd.d.ts +53 -0
- package/dist/mmpd.js +322 -0
- package/dist/sdo.d.ts +17 -0
- package/dist/sdo.js +219 -0
- package/dist/web-socket-connection.d.ts +70 -0
- package/dist/web-socket-connection.js +237 -0
- package/dist/wire-time.d.ts +2 -0
- package/dist/wire-time.js +18 -0
- package/package.json +29 -35
- package/.vscode/launch.json +0 -23
- package/README.md +0 -118
- package/box.config.json +0 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/motion-master-client-web-socket-connection.d.ts +0 -43
- package/dist/motion-master-client-web-socket-connection.d.ts.map +0 -1
- package/dist/motion-master-client-web-socket-connection.js +0 -91
- package/dist/motion-master-client-web-socket-connection.js.map +0 -1
- package/dist/motion-master-client.d.ts +0 -105
- package/dist/motion-master-client.d.ts.map +0 -1
- package/dist/motion-master-client.js +0 -348
- package/dist/motion-master-client.js.map +0 -1
- package/dist/motion-master-notification-subscribe-data.d.ts +0 -8
- package/dist/motion-master-notification-subscribe-data.d.ts.map +0 -1
- package/dist/motion-master-notification-subscribe-data.js +0 -3
- package/dist/motion-master-notification-subscribe-data.js.map +0 -1
- package/dist/motion-master-notification-web-socket-connection.d.ts +0 -56
- package/dist/motion-master-notification-web-socket-connection.d.ts.map +0 -1
- package/dist/motion-master-notification-web-socket-connection.js +0 -115
- package/dist/motion-master-notification-web-socket-connection.js.map +0 -1
- package/dist/motion-master-notification.d.ts +0 -31
- package/dist/motion-master-notification.d.ts.map +0 -1
- package/dist/motion-master-notification.js +0 -44
- package/dist/motion-master-notification.js.map +0 -1
- package/dist/util.d.ts +0 -16
- package/dist/util.d.ts.map +0 -1
- package/dist/util.js +0 -24
- package/dist/util.js.map +0 -1
- package/licenses.format.json +0 -4
- package/motion-master-client.config.json +0 -7
- package/smm_data_dic.json +0 -1213
- package/src/index.ts +0 -7
- package/src/motion-master-client-web-socket-connection.ts +0 -104
- package/src/motion-master-client.ts +0 -468
- package/src/motion-master-notification-subscribe-data.ts +0 -7
- package/src/motion-master-notification-web-socket-connection.ts +0 -143
- package/src/motion-master-notification.ts +0 -51
- package/src/util.ts +0 -22
- package/test.sh +0 -122
- package/tsconfig.json +0 -63
- package/tslint.json +0 -118
|
@@ -0,0 +1,1886 @@
|
|
|
1
|
+
import { AlStatusCode, AutoTuningError, AutoTuningRunRequest, AutoTuningRunResponse, AutoTuningStatus, BrakeState, CaptureSummary, Cia402Status, DcSyncStatus, DeviceDiagnostics, DeviceFile, DeviceParameter, Encoders, EscRegister, EsiParseResult, FirmwareCompatibility, FirmwarePackageName, FoeErrorCode, GameLoopHealth, HardwareDescription, HrdRecording, IntegroVariant, IntegroVariantOption, MailboxErrorCode, Monitoring, ObjectDataTypeInfo, OperationModes, OutputStageResult, ParameterCacheEntry, ParameterValue, PdoMapping, PdoMappingRequest, ProcedureListing, ProcedureRequest, ProcedureSnapshot, ProcessDataWatchdog, ProcessImageObject, SdoAbortCode, SlaveConfig, SlaveInformationInterface, UserCacheListing } from "./data-contracts.js";
|
|
2
|
+
import { HttpClient, RequestParams } from "./http-client.js";
|
|
3
|
+
export declare class Api<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
|
|
4
|
+
/**
|
|
5
|
+
* No description
|
|
6
|
+
*
|
|
7
|
+
* @name GetAdapters
|
|
8
|
+
* @summary List network adapters on the host
|
|
9
|
+
* @request GET:/api/adapters
|
|
10
|
+
*/
|
|
11
|
+
getAdapters: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
12
|
+
/**
|
|
13
|
+
* MAC address in colon-separated uppercase format
|
|
14
|
+
* @example "AA:BB:CC:DD:EE:FF"
|
|
15
|
+
*/
|
|
16
|
+
macLinux: string;
|
|
17
|
+
/**
|
|
18
|
+
* MAC address in dash-separated uppercase format
|
|
19
|
+
* @example "AA-BB-CC-DD-EE-FF"
|
|
20
|
+
*/
|
|
21
|
+
macWindows: string;
|
|
22
|
+
/**
|
|
23
|
+
* OS interface name (e.g. eth0 on Linux, \\Device\\NPF_{GUID} on Windows)
|
|
24
|
+
* @example "eth0"
|
|
25
|
+
*/
|
|
26
|
+
name: string;
|
|
27
|
+
/**
|
|
28
|
+
* Human-readable hardware description. Populated on Windows, where the interface name is a GUID device path that identifies nothing; empty on Linux and macOS, where the interface name is the identification. Clients must fall back to `name` when it is empty.
|
|
29
|
+
* @example "Realtek USB GbE Family Controller"
|
|
30
|
+
*/
|
|
31
|
+
description: string;
|
|
32
|
+
}[], any>>;
|
|
33
|
+
/**
|
|
34
|
+
* No description
|
|
35
|
+
*
|
|
36
|
+
* @name GetVersion
|
|
37
|
+
* @summary Get Motion Master version
|
|
38
|
+
* @request GET:/api/version
|
|
39
|
+
*/
|
|
40
|
+
getVersion: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
41
|
+
/** @example "6.0.0" */
|
|
42
|
+
version: string;
|
|
43
|
+
}, any>>;
|
|
44
|
+
/**
|
|
45
|
+
* @description Returns this document — the OpenAPI specification embedded in the running binary — as YAML. Lets a client discover the exact API contract of the server it is talking to without a packaged file or a matching source checkout; the served spec always matches the running version.
|
|
46
|
+
*
|
|
47
|
+
* @name GetSwaggerYml
|
|
48
|
+
* @summary Get this OpenAPI specification
|
|
49
|
+
* @request GET:/api/swagger.yml
|
|
50
|
+
*/
|
|
51
|
+
getSwaggerYml: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<string, any>>;
|
|
52
|
+
/**
|
|
53
|
+
* @description The effective configuration after merging the JSONC config file (if any) over the built-in defaults — the same `Config` the server booted with. The config file is either the one passed via `--config` or a `motion-master.jsonc` auto-discovered next to the executable (`--config` wins). Read-only; changing it requires editing the config file and restarting. The shape mirrors the config file (server, fieldbus, logging, tls, gameLoop, recorder, parameterCache, parameters).
|
|
54
|
+
*
|
|
55
|
+
* @name GetStartedConfig
|
|
56
|
+
* @summary Get the configuration Motion Master was started with
|
|
57
|
+
* @request GET:/api/config
|
|
58
|
+
*/
|
|
59
|
+
getStartedConfig: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Record<string, any>, any>>;
|
|
60
|
+
/**
|
|
61
|
+
* @description A best-effort snapshot of the operating system and hardware Motion Master is running on, for the Connection page's System panel. Every field is best-effort: one that cannot be determined on the current platform is returned empty (strings) or zero (numbers) rather than failing the request. Collected on demand — not cached.
|
|
62
|
+
*
|
|
63
|
+
* @name GetSystemInfo
|
|
64
|
+
* @summary Get host OS and hardware information
|
|
65
|
+
* @request GET:/api/system-info
|
|
66
|
+
*/
|
|
67
|
+
getSystemInfo: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
68
|
+
/**
|
|
69
|
+
* Friendly OS name.
|
|
70
|
+
* @example "Ubuntu 24.04 LTS"
|
|
71
|
+
*/
|
|
72
|
+
osName: string;
|
|
73
|
+
/**
|
|
74
|
+
* Kernel or OS build identifier.
|
|
75
|
+
* @example "6.8.0-31-generic"
|
|
76
|
+
*/
|
|
77
|
+
kernel: string;
|
|
78
|
+
/**
|
|
79
|
+
* Machine architecture.
|
|
80
|
+
* @example "x86_64"
|
|
81
|
+
*/
|
|
82
|
+
architecture: string;
|
|
83
|
+
/**
|
|
84
|
+
* Network host name.
|
|
85
|
+
* @example "motion-master-pi"
|
|
86
|
+
*/
|
|
87
|
+
hostname: string;
|
|
88
|
+
/**
|
|
89
|
+
* CPU brand string.
|
|
90
|
+
* @example "Intel(R) Core(TM) i7-1185G7 @ 3.00GHz"
|
|
91
|
+
*/
|
|
92
|
+
cpuModel: string;
|
|
93
|
+
/**
|
|
94
|
+
* Logical processor count.
|
|
95
|
+
* @example 8
|
|
96
|
+
*/
|
|
97
|
+
cpuCores: number;
|
|
98
|
+
/**
|
|
99
|
+
* Total physical RAM in bytes (0 if unknown).
|
|
100
|
+
* @format int64
|
|
101
|
+
* @example 16777216000
|
|
102
|
+
*/
|
|
103
|
+
totalMemoryBytes: number;
|
|
104
|
+
/**
|
|
105
|
+
* Capacity of the filesystem holding the working directory, in bytes.
|
|
106
|
+
* @format int64
|
|
107
|
+
* @example 250790436864
|
|
108
|
+
*/
|
|
109
|
+
diskTotalBytes: number;
|
|
110
|
+
/**
|
|
111
|
+
* Space available to an unprivileged process on that filesystem, in bytes.
|
|
112
|
+
* @format int64
|
|
113
|
+
* @example 98765432100
|
|
114
|
+
*/
|
|
115
|
+
diskFreeBytes: number;
|
|
116
|
+
/**
|
|
117
|
+
* Container runtime when running inside one ("docker", "podman", "containerd", "kubernetes", "lxc"); empty on bare metal.
|
|
118
|
+
* @example "docker"
|
|
119
|
+
*/
|
|
120
|
+
container: string;
|
|
121
|
+
/**
|
|
122
|
+
* Docker version reported by `docker --version` on the host; empty if the docker CLI is not installed/on PATH (including inside Motion Master's own image).
|
|
123
|
+
* @example "27.1.1"
|
|
124
|
+
*/
|
|
125
|
+
dockerVersion: string;
|
|
126
|
+
}, any>>;
|
|
127
|
+
/**
|
|
128
|
+
* @description Reports the validity window and identity of the certificate the server is currently serving. `expiresSoon` trips within 7 days of `notAfter`, so the PWA can prompt the user to refresh. Note that an already-expired certificate blocks the browser from reaching this endpoint at all; the binary self-heals an expired/missing certificate at startup (fetching from the rolling release) and exposes `--update-cert` for manual refresh. Returns 500 if the certificate file cannot be read or parsed.
|
|
129
|
+
*
|
|
130
|
+
* @name GetCert
|
|
131
|
+
* @summary Get the TLS certificate validity window
|
|
132
|
+
* @request GET:/api/cert
|
|
133
|
+
*/
|
|
134
|
+
getCert: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
135
|
+
/**
|
|
136
|
+
* Filesystem path of the certificate being served.
|
|
137
|
+
* @example "/opt/motion-master/cert.pem"
|
|
138
|
+
*/
|
|
139
|
+
path: string;
|
|
140
|
+
/**
|
|
141
|
+
* Subject common name (CN).
|
|
142
|
+
* @example "local.motion-master.synapticon.com"
|
|
143
|
+
*/
|
|
144
|
+
subject: string;
|
|
145
|
+
/**
|
|
146
|
+
* The certificate's subjectAltName DNS entries — the hostnames it is valid for, and what a browser actually checks (the CN is legacy and ignored). The bundled certificate covers both the loopback name and the `*.ip.…` wildcard used by off-loopback deployments, so one file serves either. Empty for a certificate with no SAN extension.
|
|
147
|
+
* @example ["local.motion-master.synapticon.com","*.ip.motion-master.synapticon.com"]
|
|
148
|
+
*/
|
|
149
|
+
dnsNames?: string[];
|
|
150
|
+
/**
|
|
151
|
+
* Issuer common name (CN).
|
|
152
|
+
* @example "R10"
|
|
153
|
+
*/
|
|
154
|
+
issuer: string;
|
|
155
|
+
/**
|
|
156
|
+
* Start of the validity window (ISO 8601 UTC).
|
|
157
|
+
* @format date-time
|
|
158
|
+
* @example "2026-05-01T00:00:00Z"
|
|
159
|
+
*/
|
|
160
|
+
notBefore: string;
|
|
161
|
+
/**
|
|
162
|
+
* End of the validity window / expiry (ISO 8601 UTC).
|
|
163
|
+
* @format date-time
|
|
164
|
+
* @example "2026-08-01T00:00:00Z"
|
|
165
|
+
*/
|
|
166
|
+
notAfter: string;
|
|
167
|
+
/**
|
|
168
|
+
* Whole days until expiry; negative once expired.
|
|
169
|
+
* @example 56
|
|
170
|
+
*/
|
|
171
|
+
daysRemaining: number;
|
|
172
|
+
/**
|
|
173
|
+
* Whether the certificate is already past notAfter.
|
|
174
|
+
* @example false
|
|
175
|
+
*/
|
|
176
|
+
expired: boolean;
|
|
177
|
+
/**
|
|
178
|
+
* True when expired or within 7 days of notAfter.
|
|
179
|
+
* @example false
|
|
180
|
+
*/
|
|
181
|
+
expiresSoon: boolean;
|
|
182
|
+
/** Every certificate present in the served PEM file, leaf first, in chain order (leaf → intermediate(s)). A fullchain PEM usually stops at the intermediate — the root lives in the OS trust store and is not transmitted — but the last entry's `issuer` still names that root. */
|
|
183
|
+
chain?: {
|
|
184
|
+
/**
|
|
185
|
+
* Subject common name (CN) of this certificate.
|
|
186
|
+
* @example "local.motion-master.synapticon.com"
|
|
187
|
+
*/
|
|
188
|
+
subject: string;
|
|
189
|
+
/**
|
|
190
|
+
* Issuer common name (CN) — the subject of the next link up.
|
|
191
|
+
* @example "R10"
|
|
192
|
+
*/
|
|
193
|
+
issuer: string;
|
|
194
|
+
/**
|
|
195
|
+
* Subject organization (O) — the friendly CA name (e.g. "Let's Encrypt") that the short CN does not carry; empty if absent (leaf certs often have no O).
|
|
196
|
+
* @example "Let's Encrypt"
|
|
197
|
+
*/
|
|
198
|
+
organization: string;
|
|
199
|
+
/**
|
|
200
|
+
* Issuer organization (O) — names the next link's (or, for the last link, the root's) organization; empty if absent.
|
|
201
|
+
* @example "Internet Security Research Group"
|
|
202
|
+
*/
|
|
203
|
+
issuerOrganization: string;
|
|
204
|
+
}[];
|
|
205
|
+
}, {
|
|
206
|
+
/**
|
|
207
|
+
* Human-readable reason the certificate could not be read.
|
|
208
|
+
* @example "cannot parse PEM certificate: /opt/motion-master/cert.pem"
|
|
209
|
+
*/
|
|
210
|
+
error: string;
|
|
211
|
+
}>>;
|
|
212
|
+
/**
|
|
213
|
+
* @description Downloads a fresh certificate and key from the rolling release, validates the pair (parses, CN matches, not expired, key matches cert), and atomically installs them next to the binary. The new certificate only takes effect after a restart (the TLS listener loads the certificate once at startup), indicated by `restartRequired` in the response. Use the still-valid proactive case; an already-expired certificate is healed by the binary at startup instead.
|
|
214
|
+
*
|
|
215
|
+
* @name RefreshCert
|
|
216
|
+
* @summary Fetch and install a fresh TLS certificate
|
|
217
|
+
* @request POST:/api/cert/refresh
|
|
218
|
+
*/
|
|
219
|
+
refreshCert: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
220
|
+
/** @example "/opt/motion-master/cert.pem" */
|
|
221
|
+
path?: string;
|
|
222
|
+
/** @example "local.motion-master.synapticon.com" */
|
|
223
|
+
subject?: string;
|
|
224
|
+
/** @example "R10" */
|
|
225
|
+
issuer?: string;
|
|
226
|
+
/** @format date-time */
|
|
227
|
+
notBefore?: string;
|
|
228
|
+
/** @format date-time */
|
|
229
|
+
notAfter: string;
|
|
230
|
+
/** @example 89 */
|
|
231
|
+
daysRemaining: number;
|
|
232
|
+
/** @example false */
|
|
233
|
+
expired?: boolean;
|
|
234
|
+
/** @example false */
|
|
235
|
+
expiresSoon?: boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Always true — restart Motion Master to serve the new certificate.
|
|
238
|
+
* @example true
|
|
239
|
+
*/
|
|
240
|
+
restartRequired: boolean;
|
|
241
|
+
}, {
|
|
242
|
+
/** @example "downloaded key does not match certificate" */
|
|
243
|
+
error: string;
|
|
244
|
+
} | {
|
|
245
|
+
/** @example "certificate refresh is not configured" */
|
|
246
|
+
error: string;
|
|
247
|
+
}>>;
|
|
248
|
+
/**
|
|
249
|
+
* No description
|
|
250
|
+
*
|
|
251
|
+
* @name GetDevice
|
|
252
|
+
* @summary Get a single fieldbus device by bus position
|
|
253
|
+
* @request GET:/api/devices/{slavePosition}
|
|
254
|
+
*/
|
|
255
|
+
getDevice: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
256
|
+
/**
|
|
257
|
+
* 1-based position on the fieldbus
|
|
258
|
+
* @example 1
|
|
259
|
+
*/
|
|
260
|
+
slavePosition: number;
|
|
261
|
+
/**
|
|
262
|
+
* Human-readable device name from SII EEPROM. For SOMANET drives this is the generic group name "SOMANET"; use productName to distinguish products.
|
|
263
|
+
* @example "SOMANET"
|
|
264
|
+
*/
|
|
265
|
+
name: string;
|
|
266
|
+
/**
|
|
267
|
+
* Canonical product name, independent of the SII EEPROM. For a recognised SOMANET product this distinguishes the product (e.g. "SOMANET Circulo"); otherwise it falls back to name.
|
|
268
|
+
* @example "SOMANET Node"
|
|
269
|
+
*/
|
|
270
|
+
productName: string;
|
|
271
|
+
/**
|
|
272
|
+
* Vendor ID from EEPROM
|
|
273
|
+
* @format int64
|
|
274
|
+
* @example 131073
|
|
275
|
+
*/
|
|
276
|
+
vendorId: number;
|
|
277
|
+
/**
|
|
278
|
+
* Product code from EEPROM
|
|
279
|
+
* @format int64
|
|
280
|
+
* @example 5570560
|
|
281
|
+
*/
|
|
282
|
+
productCode: number;
|
|
283
|
+
/**
|
|
284
|
+
* Revision number from EEPROM
|
|
285
|
+
* @format int64
|
|
286
|
+
* @example 1
|
|
287
|
+
*/
|
|
288
|
+
revisionNumber: number;
|
|
289
|
+
/**
|
|
290
|
+
* Serial number from EEPROM
|
|
291
|
+
* @format int64
|
|
292
|
+
* @example 12345
|
|
293
|
+
*/
|
|
294
|
+
serialNumber: number;
|
|
295
|
+
/**
|
|
296
|
+
* Whether the device implements the CiA402 drive profile (both controlword 0x6040 and statusword 0x6041 present in its object dictionary). Gates the CiA402 motion-control endpoints under /api/devices/{slavePosition}/cia402.
|
|
297
|
+
* @example true
|
|
298
|
+
*/
|
|
299
|
+
isCia402: boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Whether the device is a SOMANET device, which runs SOMANET firmware. The server decides this from the vendor ID: Synapticon (0x22D2) or Sensodrive (0x063A). Gates the SOMANET features, such as the SOMANET files and the SOMANET procedures.
|
|
302
|
+
* @example true
|
|
303
|
+
*/
|
|
304
|
+
isSomanet: boolean;
|
|
305
|
+
/**
|
|
306
|
+
* Whether an object-dictionary read for this device has failed since it was scanned. The automatic read on reaching a mailbox-active state is attempted once, so a device flagged here keeps an empty parameter list until `POST /api/devices/{slavePosition}/parameters/init` is called; that clears the flag on success.
|
|
307
|
+
* @example false
|
|
308
|
+
*/
|
|
309
|
+
parametersUnavailable: boolean;
|
|
310
|
+
/**
|
|
311
|
+
* The low byte of ESC register 0x0000, which names the slave controller family: 0x85 is a netX (Integro), 0xC0 the controller of a Circulo, 0x90 a TI PRU-ICSS (Jasper). Null when the register could not be read at the scan, and over SPoE.
|
|
312
|
+
* @format int32
|
|
313
|
+
* @example 192
|
|
314
|
+
*/
|
|
315
|
+
escType?: number | null;
|
|
316
|
+
/**
|
|
317
|
+
* Whether Motion Master writes each mailbox request to this device once and never sends it again. True for a Synapticon or Sensodrive device whose ESC type is not 0x85, because its EtherCAT stack locks its receive mailbox when it gets one request twice. False for a netX, which discards a repeat, and for every other vendor, where a write with no frame back is sent again.
|
|
318
|
+
* @example true
|
|
319
|
+
*/
|
|
320
|
+
mailboxWriteOnce?: boolean;
|
|
321
|
+
/**
|
|
322
|
+
* Whether the device has an EtherCAT Slave Controller: SII, ESC registers, distributed clocks and the ESC diagnostics. False over SPoE, where those endpoints answer 409.
|
|
323
|
+
* @example true
|
|
324
|
+
*/
|
|
325
|
+
supportsEsc?: boolean;
|
|
326
|
+
/**
|
|
327
|
+
* Whether the transport can blink the device's LEDs, which is what the `device-locate` procedure does. True over SPoE.
|
|
328
|
+
* @example false
|
|
329
|
+
*/
|
|
330
|
+
supportsLocate?: boolean;
|
|
331
|
+
}, void>>;
|
|
332
|
+
/**
|
|
333
|
+
* @description Constructs the requested fieldbus driver and makes it available for subsequent calls to /api/scan. The body is the `fieldbus` block of the config file, and the same rules check it. The driver defaults to SOEM when omitted. SOEM opens the network interface. It has no adapter auto-detect: a network adapter must be supplied, otherwise init fails. SPoE connects to each drive at scan time. It needs `ipAddresses`, one address per drive, and the list order is the position order.
|
|
334
|
+
*
|
|
335
|
+
* @name Init
|
|
336
|
+
* @summary Initialise the fieldbus driver
|
|
337
|
+
* @request POST:/api/init
|
|
338
|
+
*/
|
|
339
|
+
init: (data?: {
|
|
340
|
+
/**
|
|
341
|
+
* Fieldbus driver to use
|
|
342
|
+
* @default "soem"
|
|
343
|
+
* @example "soem"
|
|
344
|
+
*/
|
|
345
|
+
driver?: "soem" | "spoe";
|
|
346
|
+
/**
|
|
347
|
+
* SOEM only. Network interface name or MAC address. Required for SOEM — there is no auto-detect, so an empty value makes init fail.
|
|
348
|
+
* @example "eth0"
|
|
349
|
+
*/
|
|
350
|
+
adapter?: string;
|
|
351
|
+
/**
|
|
352
|
+
* SPoE only. One IP address per drive, at least one. The list order is the position order, and a drive that does not answer keeps its position.
|
|
353
|
+
* @example ["192.168.0.10"]
|
|
354
|
+
*/
|
|
355
|
+
ipAddresses?: string[];
|
|
356
|
+
/** SPoE only. */
|
|
357
|
+
spoe?: {
|
|
358
|
+
/**
|
|
359
|
+
* Who owns the drive's state. In `monitor` mode a PLC owns it, Motion Master only parametrises and observes, and a state change answers 409. In `control` mode Motion Master owns it.
|
|
360
|
+
* @default "monitor"
|
|
361
|
+
*/
|
|
362
|
+
mode?: "monitor" | "control";
|
|
363
|
+
/**
|
|
364
|
+
* Control mode only. The drive faults when no SPoE message arrives for this long. At least 50. Firmware with SPoE protocol 1.0 cannot set it and uses a fixed watchdog.
|
|
365
|
+
* @min 50
|
|
366
|
+
* @default 75
|
|
367
|
+
*/
|
|
368
|
+
watchdogMs?: number;
|
|
369
|
+
/**
|
|
370
|
+
* The TCP port of the SPoE server on every drive.
|
|
371
|
+
* @min 1
|
|
372
|
+
* @max 65535
|
|
373
|
+
* @default 8080
|
|
374
|
+
*/
|
|
375
|
+
port?: number;
|
|
376
|
+
};
|
|
377
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
378
|
+
/** @example true */
|
|
379
|
+
ok: boolean;
|
|
380
|
+
}, void | {
|
|
381
|
+
/** @example "already initialised — call reset() first" */
|
|
382
|
+
error: string;
|
|
383
|
+
} | {
|
|
384
|
+
/**
|
|
385
|
+
* Human-readable error message from the driver
|
|
386
|
+
* @example "FPRD slave 1: wkc=0"
|
|
387
|
+
*/
|
|
388
|
+
error: string;
|
|
389
|
+
}>>;
|
|
390
|
+
/**
|
|
391
|
+
* @description Compares the bus with the last scan. Two changes make that scan wrong. A device that resets, for example after a power cycle, loses the station address the scan gave it, and no longer answers at it. A device added to or removed from the chain changes the number of devices on the wire, even when every known device still answers. The server reads the AL state of every scanned device, as `GET /api/devices/state` does, and with SOEM it counts the devices on the wire with one broadcast read. A device that lost its station address still answers a broadcast, so it is counted. Before the first scan, `devicesScanned` is 0, so any device on the wire makes `required` true. A device swapped for another at the same position without a reset is not detected, because it keeps the old address and answers normally.
|
|
392
|
+
*
|
|
393
|
+
* @name GetScanStatus
|
|
394
|
+
* @summary Read whether the bus needs a new scan
|
|
395
|
+
* @request GET:/api/scan
|
|
396
|
+
*/
|
|
397
|
+
getScanStatus: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
398
|
+
/**
|
|
399
|
+
* True when `unreachable` is not empty, or when `devicesOnWire` is not null and differs from `devicesScanned`.
|
|
400
|
+
* @example true
|
|
401
|
+
*/
|
|
402
|
+
required: boolean;
|
|
403
|
+
/**
|
|
404
|
+
* The number of devices on the wire now. Null over SPoE, which cannot count them.
|
|
405
|
+
* @example 3
|
|
406
|
+
*/
|
|
407
|
+
devicesOnWire: number | null;
|
|
408
|
+
/**
|
|
409
|
+
* The number of devices the last scan found
|
|
410
|
+
* @example 2
|
|
411
|
+
*/
|
|
412
|
+
devicesScanned: number;
|
|
413
|
+
/**
|
|
414
|
+
* Positions whose `reachability` is not `answering`, in position order. `GET /api/devices/state` tells why for each one.
|
|
415
|
+
* @example [2]
|
|
416
|
+
*/
|
|
417
|
+
unreachable: number[];
|
|
418
|
+
}, {
|
|
419
|
+
/**
|
|
420
|
+
* Human-readable error message from the driver
|
|
421
|
+
* @example "FPRD slave 1: wkc=0"
|
|
422
|
+
*/
|
|
423
|
+
error: string;
|
|
424
|
+
}>>;
|
|
425
|
+
/**
|
|
426
|
+
* @description Scans the fieldbus for slaves and configures their sync managers and FMMUs. Must be called after a successful POST /api/init. With SOEM, slaves remain in INIT state after this call, and state transitions are driven by subsequent API calls. An SPoE drive starts in OP. When a scan finds a device already in SAFE-OP or OP, it reads that device's object dictionary and publishes the process image, so the exchange starts with no state change. The dictionary comes from the parameter cache when the cache has it. Otherwise the first read of a drive model takes several seconds. If this step fails, the scan still returns 200 and the server logs a warning. A later state change to SAFE-OP or OP maps the image again. An empty bus is a successful scan returning 0 slaves, not an error: the master cannot distinguish a bus with no devices powered from a disconnected one, and the user recovers by powering devices on and scanning again. A 500 is returned only on a genuine driver failure (e.g. no driver initialised). A scan does not wait for work already in flight. A procedure that is running keeps running against the devices it started on, and fails at its next bus transfer. Retained procedure snapshots are discarded, because a position may name different hardware after a scan. A scan frees the recording, the retained process images and the previous device set, so it first waits up to 200 ms for the real-time loop to leave the cycle it is in. If the loop is stalled — a cyclic task that overruns, or severe CPU contention — the scan fails with 500 and changes nothing, rather than freeing memory the loop is still reading. `GET /api/game-loop` shows the stall. The same applies to `POST /api/process-data`, which re-allocates the recorder. `POST /api/reset` never fails this way: it holds the memory back instead and reclaims it later.
|
|
427
|
+
*
|
|
428
|
+
* @name Scan
|
|
429
|
+
* @summary Scan the bus for slaves
|
|
430
|
+
* @request POST:/api/scan
|
|
431
|
+
*/
|
|
432
|
+
scan: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
433
|
+
/**
|
|
434
|
+
* Number of slaves discovered on the bus (0 if empty/unpowered)
|
|
435
|
+
* @example 3
|
|
436
|
+
*/
|
|
437
|
+
slaves: number;
|
|
438
|
+
}, {
|
|
439
|
+
/**
|
|
440
|
+
* Human-readable error message from the driver
|
|
441
|
+
* @example "FPRD slave 1: wkc=0"
|
|
442
|
+
*/
|
|
443
|
+
error: string;
|
|
444
|
+
}>>;
|
|
445
|
+
/**
|
|
446
|
+
* @description Tears down all master-side state — unpublishes the process image, frees the recorder, removes all Device objects, and closes the network interface (releasing the NIC). It does not command the slaves to any AL state; the master simply stops talking to the bus. After this returns, POST /api/init and POST /api/scan may be called again.
|
|
447
|
+
*
|
|
448
|
+
* @name Reset
|
|
449
|
+
* @summary Reset the fieldbus driver and clear the device list
|
|
450
|
+
* @request POST:/api/reset
|
|
451
|
+
*/
|
|
452
|
+
reset: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
453
|
+
/** @example true */
|
|
454
|
+
ok: boolean;
|
|
455
|
+
}, any>>;
|
|
456
|
+
/**
|
|
457
|
+
* @description Returns the most recent in-memory log lines as plain text, one entry per line. The ring buffer holds up to 100 000 entries (~10 MB).
|
|
458
|
+
*
|
|
459
|
+
* @name GetLog
|
|
460
|
+
* @summary Get recent log output
|
|
461
|
+
* @request GET:/api/log
|
|
462
|
+
*/
|
|
463
|
+
getLog: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<string, any>>;
|
|
464
|
+
/**
|
|
465
|
+
* @description Reports what Motion Master knows about the auto-tuning process. The tuning calculations run in a separate executable, which Motion Master starts at startup and reaches over loopback. That executable is downloaded by the install scripts rather than shipped in a release, so a machine may not have it — this endpoint is how a client tells the four cases apart: switched off in the configuration, not installed, installed but would not start, or running. The values are a startup snapshot. `started` says the process answered when Motion Master waited for it, not that it is alive now. Nothing polls it: a call is the honest test, and `POST /api/auto-tuning/run` makes one.
|
|
466
|
+
*
|
|
467
|
+
* @name GetAutoTuning
|
|
468
|
+
* @summary Auto-tuning process status
|
|
469
|
+
* @request GET:/api/auto-tuning
|
|
470
|
+
*/
|
|
471
|
+
getAutoTuning: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<AutoTuningStatus, any>>;
|
|
472
|
+
/**
|
|
473
|
+
* @description Forwards the request to the auto-tuning process and returns its reply unchanged. The body is a JSON object with `run`, naming the function, and `data`, holding that function's inputs — the same shape the auto-tuning program takes on its own API. **A rejected input is reported with 200 and an `error` property**, not with a 4xx. The auto-tuning program keeps 4xx and 5xx for a malformed request, an unknown function name, and a routine that threw, so a client tests for `error` in the body rather than relying on the status alone. Motion Master passes both through untouched; only 400, 502 and 503 below are its own. Measurement data travels in the body. `identify_plant_model` takes the chirp measurements as `data.csv` text, and the bode data comes back inline as `bode`, so no file is written and nothing needs a shared filesystem view. The schemas here are a copy of the auto-tuning program's own, taken from version 3.1.1, and they exist so that the generated clients are typed. That program's current description is served verbatim at `GET /api/auto-tuning/swagger.yml`, which is the authority if the two ever disagree.
|
|
474
|
+
*
|
|
475
|
+
* @name RunAutoTuning
|
|
476
|
+
* @summary Run an auto-tuning function
|
|
477
|
+
* @request POST:/api/auto-tuning/run
|
|
478
|
+
*/
|
|
479
|
+
runAutoTuning: (data: AutoTuningRunRequest, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<AutoTuningRunResponse, AutoTuningError | {
|
|
480
|
+
error: string;
|
|
481
|
+
}>>;
|
|
482
|
+
/**
|
|
483
|
+
* @description Serves the OpenAPI document the auto-tuning process carries, fetched from it on each request. The schemas under `/api/auto-tuning/run` above are a copy of these, so this is where to look when a version of the program disagrees with them.
|
|
484
|
+
*
|
|
485
|
+
* @name GetAutoTuningSpec
|
|
486
|
+
* @summary The auto-tuning program's own API description
|
|
487
|
+
* @request GET:/api/auto-tuning/swagger.yml
|
|
488
|
+
*/
|
|
489
|
+
getAutoTuningSpec: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<string, {
|
|
490
|
+
error: string;
|
|
491
|
+
}>>;
|
|
492
|
+
/**
|
|
493
|
+
* @description Returns the static catalogue of EtherCAT AL Status Codes defined in ETG.1000.6 §6.4.1. These codes appear in the alStatusCode field of the device state response when an error is present and identify the cause of the state transition failure.
|
|
494
|
+
*
|
|
495
|
+
* @name GetAlStatusCodes
|
|
496
|
+
* @summary List all known AL Status Codes
|
|
497
|
+
* @request GET:/api/meta/al-status-codes
|
|
498
|
+
*/
|
|
499
|
+
getAlStatusCodes: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<AlStatusCode[], any>>;
|
|
500
|
+
/**
|
|
501
|
+
* @description Returns the static catalogue of well-known EtherCAT Slave Controller registers from the Beckhoff ESC datasheet (Section II) and ETG.1000.4. Use the address and length fields as inputs to the device register read/write endpoints.
|
|
502
|
+
*
|
|
503
|
+
* @name GetRegisters
|
|
504
|
+
* @summary List all known ESC registers
|
|
505
|
+
* @request GET:/api/meta/esc-registers
|
|
506
|
+
*/
|
|
507
|
+
getRegisters: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<EscRegister[], any>>;
|
|
508
|
+
/**
|
|
509
|
+
* @description Returns the static catalogue of standard File over EtherCAT (FoE) error codes defined in ETG.1000.6 §5.5. These codes appear in the FoE ERROR packet sent by the slave when a file transfer fails, and are surfaced in the error message returned by the file read endpoint. Vendor-specific codes outside the 0x8000 range are not listed here.
|
|
510
|
+
*
|
|
511
|
+
* @name GetFoeErrorCodes
|
|
512
|
+
* @summary List all known FoE error codes
|
|
513
|
+
* @request GET:/api/meta/foe-error-codes
|
|
514
|
+
*/
|
|
515
|
+
getFoeErrorCodes: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<FoeErrorCode[], any>>;
|
|
516
|
+
/**
|
|
517
|
+
* @description Returns the static catalogue of CoE SDO abort codes defined in ETG.1000.6 §5.6.2.7.2, Table 41 (which reproduces the CANopen CiA 301 abort transfer codes). A slave returns one of these when a mailbox SDO read/write fails; the code is embedded in the error text returned by the SDO endpoints.
|
|
518
|
+
*
|
|
519
|
+
* @name GetSdoAbortCodes
|
|
520
|
+
* @summary List all known CoE SDO abort codes
|
|
521
|
+
* @request GET:/api/meta/sdo-abort-codes
|
|
522
|
+
*/
|
|
523
|
+
getSdoAbortCodes: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<SdoAbortCode[], any>>;
|
|
524
|
+
/**
|
|
525
|
+
* @description The register maps of the two iC-Haus chips inside a Circulo's internal encoder — the reference tables for POST /api/devices/{slavePosition}/procedures/encoder-register-communication, and documentation in their own right. Static: they describe the chips, not any connected device, so no bus and no scan are needed. Two chips, and the iC-MU is the one in charge. The iC-MU is the position encoder proper, a magnetic off-axis absolute chip speaking BiSS-C to the drive. The iC-PVL is a battery-buffered Hall multiturn counter behind it, reached over I2C through the iC-MU rather than directly. The response is a list of register *spaces*, not of registers, because an address alone names nothing: the same iC-PVL address 0x00 is a configuration register in one space and the status register in another, depending on which I2C device id addressed it. Each space says which chip it belongs to and how it is reached. A row is one address, or the range the datasheet prints as one row — `address` and `lastAddress` are equal in the ordinary case. `fields` lists the named pieces of the register, most significant bit first, each with the datasheet's own one-line description; it is empty exactly when `reserved` is true. `layout` is those same fields rendered as the datasheet prints the row, e.g. `GC_M(1:0) | GF_M(5:0)`, derived rather than stored so it cannot disagree with them. `spiOnly` marks the iC-MU's 0x80-0xAF, which is reachable over SPI only and so beyond the drive's register communication service. A field's `bits` is its own bit slice as the register map prints it, not its position within the byte: `GC_M(1:0)` occupies bits 7:6 of address 0x00 and reads "1:0" because those are the field's two bits. A value wider than one register is spread across several, which is why `RESABZ` reads "7:0" at 0x13 and "15:8" at 0x14. Granularity follows each datasheet's own register map. The iC-PVL prints its status registers bit by bit, so those arrive as eight fields; the iC-MU prints its own as `STATUS0(7:0)`, so that is one field. Transcribed from the vendors' datasheets: iC-MU Series Rev B1 (Tables 90 and 91) and iC-PVL Rev F2 (Tables 5, 6 and 7), with descriptions from their CONFIGURATION PARAMETERS indexes and, for the iC-PVL status bytes, its status tables. The prose behind those one-liners is not reproduced.
|
|
526
|
+
*
|
|
527
|
+
* @name GetIcHausRegisters
|
|
528
|
+
* @summary The Circulo internal encoder's register maps
|
|
529
|
+
* @request GET:/api/meta/ic-haus-registers
|
|
530
|
+
*/
|
|
531
|
+
getIcHausRegisters: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
532
|
+
/** @example "iC-MU" */
|
|
533
|
+
chip: "iC-MU" | "iC-PVL";
|
|
534
|
+
/**
|
|
535
|
+
* The datasheet's own name for the space.
|
|
536
|
+
* @example "CONF, bank 0, addresses 0x00-0x3F"
|
|
537
|
+
*/
|
|
538
|
+
name: string;
|
|
539
|
+
/** How the space is reached, which is what decides whether the register communication service can read it at all. */
|
|
540
|
+
addressing: string;
|
|
541
|
+
registers: {
|
|
542
|
+
/**
|
|
543
|
+
* The address, or the first of a printed range.
|
|
544
|
+
* @example 15
|
|
545
|
+
*/
|
|
546
|
+
address: number;
|
|
547
|
+
/**
|
|
548
|
+
* The last address of the range; equal to address for a single-address row.
|
|
549
|
+
* @example 15
|
|
550
|
+
*/
|
|
551
|
+
lastAddress: number;
|
|
552
|
+
/**
|
|
553
|
+
* The fields rendered as the datasheet prints the row. "RESERVED" for a reserved row.
|
|
554
|
+
* @example "SPO_MT(3:0) | MPC(3:0)"
|
|
555
|
+
*/
|
|
556
|
+
layout: string;
|
|
557
|
+
/** The named pieces of this register, most significant bit first. Empty when reserved. */
|
|
558
|
+
fields: {
|
|
559
|
+
/**
|
|
560
|
+
* The datasheet's own name for the field.
|
|
561
|
+
* @example "SPO_MT"
|
|
562
|
+
*/
|
|
563
|
+
name: string;
|
|
564
|
+
/**
|
|
565
|
+
* The field's own bit slice as the register map prints it, empty where it prints a bare name. Not the position within the byte.
|
|
566
|
+
* @example "3:0"
|
|
567
|
+
*/
|
|
568
|
+
bits: string;
|
|
569
|
+
/**
|
|
570
|
+
* The datasheet's one-line description of the field.
|
|
571
|
+
* @example "Offset external multiturn"
|
|
572
|
+
*/
|
|
573
|
+
description: string;
|
|
574
|
+
}[];
|
|
575
|
+
/** @example false */
|
|
576
|
+
reserved: boolean;
|
|
577
|
+
/**
|
|
578
|
+
* Reachable over SPI only, so the register communication service cannot touch it.
|
|
579
|
+
* @example false
|
|
580
|
+
*/
|
|
581
|
+
spiOnly: boolean;
|
|
582
|
+
}[];
|
|
583
|
+
}[], any>>;
|
|
584
|
+
/**
|
|
585
|
+
* @description The register map of the Integro's internal (Kübler) encoder — the reference table for POST /api/devices/{slavePosition}/procedures/kuebler-register-communication, and documentation in its own right. Static: it describes the encoder type, not any connected device, so it needs no bus and no scan. Transcribed from the vendor's own draft table, then corrected against what the encoder really does: the draft calls four registers not implemented that the encoder calibration sequence reads or writes, and leaves out four more. Each entry carries the width, the access type, whether the encoder implements it, and the vendor's bit definitions verbatim, which for a bit-field register is the only place its meaning is recorded. A register the draft does not document says so in `definition`, because a reader has nowhere else to look. `format` says how to read the assembled value, because signedness is not uniform and one register is not a single number at all: `unsigned`, `signed`, `bitField` (the number means nothing on its own), or `signedHalves` — two signed 16-bit values packed into 32 bits, which register 0x3C is the only case of. `readableInOneCommand` says whether one command can carry the register, since the command's length byte caps at 4 bytes. Every register fits today, so it is true for all of them.
|
|
586
|
+
*
|
|
587
|
+
* @name GetKueblerRegisters
|
|
588
|
+
* @summary The Integro internal encoder's register map
|
|
589
|
+
* @request GET:/api/meta/kuebler-registers
|
|
590
|
+
*/
|
|
591
|
+
getKueblerRegisters: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
592
|
+
/**
|
|
593
|
+
* Register address, as OS command 19 carries it.
|
|
594
|
+
* @example 48
|
|
595
|
+
*/
|
|
596
|
+
address: number;
|
|
597
|
+
/**
|
|
598
|
+
* Width in bits — 8, 16, 32, or 64.
|
|
599
|
+
* @example 32
|
|
600
|
+
*/
|
|
601
|
+
bits: number;
|
|
602
|
+
/**
|
|
603
|
+
* The vendor's own name for the register.
|
|
604
|
+
* @example "Absolute position ST"
|
|
605
|
+
*/
|
|
606
|
+
name: string;
|
|
607
|
+
/** @example "ro" */
|
|
608
|
+
access: "ro" | "wo" | "rw";
|
|
609
|
+
/**
|
|
610
|
+
* Whether the encoder implements it, per the vendor's draft.
|
|
611
|
+
* @example true
|
|
612
|
+
*/
|
|
613
|
+
implemented: boolean;
|
|
614
|
+
/**
|
|
615
|
+
* How to read the assembled value.
|
|
616
|
+
* @example "unsigned"
|
|
617
|
+
*/
|
|
618
|
+
format: "unsigned" | "signed" | "bitField" | "signedHalves";
|
|
619
|
+
/**
|
|
620
|
+
* The vendor's bit definitions, clauses joined with "; ".
|
|
621
|
+
* @example "Left aligned 32 bit singleturn position"
|
|
622
|
+
*/
|
|
623
|
+
definition: string;
|
|
624
|
+
/**
|
|
625
|
+
* False only for the 64-bit register, which exceeds the command's 4-byte length field.
|
|
626
|
+
* @example true
|
|
627
|
+
*/
|
|
628
|
+
readableInOneCommand: boolean;
|
|
629
|
+
}[], any>>;
|
|
630
|
+
/**
|
|
631
|
+
* @description Returns the static catalogue of CoE mailbox error codes defined in ETG.1000.4, Table 30 ("Error Reply Service Data"). A slave returns one of these when the mailbox layer (below a specific protocol such as CoE/FoE) rejects a transfer; the code is embedded in the error text the mailbox endpoints return.
|
|
632
|
+
*
|
|
633
|
+
* @name GetMailboxErrorCodes
|
|
634
|
+
* @summary List all known CoE mailbox error codes
|
|
635
|
+
* @request GET:/api/meta/mailbox-error-codes
|
|
636
|
+
*/
|
|
637
|
+
getMailboxErrorCodes: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<MailboxErrorCode[], any>>;
|
|
638
|
+
/**
|
|
639
|
+
* @description Returns the static catalogue of ETG.1020 data type codes used in CoE object dictionary entries. Each entry of a `DeviceParameter` carries a `dataType` field whose value is one of the codes listed here.
|
|
640
|
+
*
|
|
641
|
+
* @name GetObjectDataTypes
|
|
642
|
+
* @summary List all known CoE object dictionary data types
|
|
643
|
+
* @request GET:/api/meta/object-data-types
|
|
644
|
+
*/
|
|
645
|
+
getObjectDataTypes: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<ObjectDataTypeInfo[], any>>;
|
|
646
|
+
/**
|
|
647
|
+
* @description Enumerates the entire CoE object dictionary of the device at `slavePosition` via the SDO Info service ("Get Object List" → "Get Object Description" → "Get Entry Description") and rebuilds its parameter map. The device must be in PRE-OP, SAFE-OP, or OP (mailbox communication active). On a fully populated drive the call can take several seconds. When `readValues=true` each entry is additionally read via SDO upload and the decoded value is stored on the parameter. An entry that fails to read keeps the value of an earlier read with `syncState` `stale`, or the type-appropriate default with `syncState` `unknown`, and the call still succeeds. Check `syncState` to find the entries that were not read.
|
|
648
|
+
*
|
|
649
|
+
* @name InitializeDeviceParameters
|
|
650
|
+
* @summary Initialise the parameter list for a device by enumerating its object dictionary
|
|
651
|
+
* @request POST:/api/devices/{slavePosition}/parameters/init
|
|
652
|
+
*/
|
|
653
|
+
initializeDeviceParameters: (slavePosition: number, query?: {
|
|
654
|
+
/**
|
|
655
|
+
* When `true`, perform an SDO upload for every entry and decode the value. Defaults to `false` — only schema (name, type, access) is populated.
|
|
656
|
+
* @default false
|
|
657
|
+
*/
|
|
658
|
+
readValues?: boolean;
|
|
659
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<DeviceParameter[], void | {
|
|
660
|
+
/**
|
|
661
|
+
* Human-readable error message from the driver
|
|
662
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
663
|
+
*/
|
|
664
|
+
error: string;
|
|
665
|
+
}>>;
|
|
666
|
+
/**
|
|
667
|
+
* @description Re-reads the value of every readable parameter already loaded for the device at `slavePosition`, leaving the parameter list itself intact (it does not re-enumerate the object dictionary — use `POST …/parameters/init` for that). Each value is read PDO-aware: from the live process image when the device is exchanging and the object is PDO-mapped, otherwise via an SDO upload over the mailbox. Write-only objects are skipped. Best-effort: an entry that fails to read keeps its cached value, a `synced` entry becomes `stale`, and the call still succeeds. Returns the refreshed list, ordered by `(index, subindex)`.
|
|
668
|
+
*
|
|
669
|
+
* @name ReadAllDeviceParameters
|
|
670
|
+
* @summary Refresh the cached value of every parameter without re-enumerating the dictionary
|
|
671
|
+
* @request POST:/api/devices/{slavePosition}/parameters/read
|
|
672
|
+
*/
|
|
673
|
+
readAllDeviceParameters: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<DeviceParameter[], void | {
|
|
674
|
+
/**
|
|
675
|
+
* Human-readable error message from the driver
|
|
676
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
677
|
+
*/
|
|
678
|
+
error: string;
|
|
679
|
+
}>>;
|
|
680
|
+
/**
|
|
681
|
+
* @description Returns the parameter list populated by the most recent call to `POST /api/devices/{slavePosition}/parameters/init`. Empty before the first call. Entries are ordered ascending by `(index, subindex)`.
|
|
682
|
+
*
|
|
683
|
+
* @name GetDeviceParameters
|
|
684
|
+
* @summary Read the previously initialised parameter list for a device
|
|
685
|
+
* @request GET:/api/devices/{slavePosition}/parameters
|
|
686
|
+
*/
|
|
687
|
+
getDeviceParameters: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<DeviceParameter[], void>>;
|
|
688
|
+
/**
|
|
689
|
+
* @description Reads one parameter of the device at `slavePosition` and returns the full `DeviceParameter` (value plus metadata: data type, access, sync state). Unlike the raw `GET …/sdo/{index}/{subindex}` endpoint, this is PDO-aware. With `source=auto` (the default) the value is taken from the live process image when the device is exchanging and the object is PDO-mapped, otherwise via an SDO upload, otherwise from the cache. With `source=cache` the cached value is served with no bus access at all. Both `index` and `subindex` accept decimal or hexadecimal notation; prefix with `0x` for hex (e.g. `0x6064` or `24676` for object 0x6064).
|
|
690
|
+
*
|
|
691
|
+
* @name ReadParameter
|
|
692
|
+
* @summary Read a single parameter value (PDO-aware, with optional cache-only mode)
|
|
693
|
+
* @request GET:/api/devices/{slavePosition}/parameters/{index}/{subindex}
|
|
694
|
+
*/
|
|
695
|
+
readParameter: (slavePosition: number, index: number, subindex: number, query?: {
|
|
696
|
+
/**
|
|
697
|
+
* `auto` (default) reads PDO-when-exchanging else SDO else cache; `cache` returns the cached value with no bus access.
|
|
698
|
+
* @default "auto"
|
|
699
|
+
*/
|
|
700
|
+
source?: "auto" | "cache";
|
|
701
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<DeviceParameter, void | {
|
|
702
|
+
/**
|
|
703
|
+
* Human-readable error message from the driver
|
|
704
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
705
|
+
*/
|
|
706
|
+
error: string;
|
|
707
|
+
}>>;
|
|
708
|
+
/**
|
|
709
|
+
* @description Writes one parameter of the device at `slavePosition`. The value is converted to the parameter's declared data type, then routed: staged into the process image when the device is exchanging and the object is output (RxPDO) mapped — sent on the next cycle — otherwise written via an SDO download, otherwise held in the cache as pending until the device is back online. This is the endpoint to set a target (e.g. target torque 0x6071) or the modes of operation: it knows which objects are PDO-mapped and stages them into the process data, falling back to SDO transparently. Returns the updated `DeviceParameter` (with the converted value and resulting sync state). A value the data type cannot hold is refused with 400, and nothing is written. That is a number outside the limits of an integer type (300 or -1 for an UNSIGNED8), a number with a fraction for an integer type, or a number outside the range of a REAL32. Every value that fits the data type is sent unchanged, even one outside the object's documented range, because the drive decides whether a value is valid. To send arbitrary bytes, use `sdoDownload`. Both `index` and `subindex` accept decimal or hexadecimal notation; prefix with `0x` for hex.
|
|
710
|
+
*
|
|
711
|
+
* @name WriteParameter
|
|
712
|
+
* @summary Write a single parameter value (PDO-aware)
|
|
713
|
+
* @request PUT:/api/devices/{slavePosition}/parameters/{index}/{subindex}
|
|
714
|
+
*/
|
|
715
|
+
writeParameter: (slavePosition: number, index: number, subindex: number, data: {
|
|
716
|
+
/**
|
|
717
|
+
* The value to set. The server converts it to the declared type of the parameter. `ParameterValue` says which JSON type each `dataType` uses.
|
|
718
|
+
* @example 100
|
|
719
|
+
*/
|
|
720
|
+
value: ParameterValue;
|
|
721
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<DeviceParameter, void | {
|
|
722
|
+
/**
|
|
723
|
+
* Human-readable error message from the driver
|
|
724
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
725
|
+
*/
|
|
726
|
+
error: string;
|
|
727
|
+
}>>;
|
|
728
|
+
/**
|
|
729
|
+
* @description Reads `length` bytes from the ESC register at `address` on the slave at `slavePosition` using a Configured-Address Read (FPRD) datagram. Pass `address` in decimal (e.g. 272 for DL Status at 0x0110).
|
|
730
|
+
*
|
|
731
|
+
* @name ReadRegister
|
|
732
|
+
* @summary Read bytes from an ESC register
|
|
733
|
+
* @request GET:/api/devices/{slavePosition}/registers/{address}
|
|
734
|
+
*/
|
|
735
|
+
readRegister: (slavePosition: number, address: number, query: {
|
|
736
|
+
/**
|
|
737
|
+
* Number of bytes to read
|
|
738
|
+
* @min 1
|
|
739
|
+
* @example 2
|
|
740
|
+
*/
|
|
741
|
+
length: number;
|
|
742
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
743
|
+
/**
|
|
744
|
+
* Register bytes in ascending address order
|
|
745
|
+
* @example [65,0]
|
|
746
|
+
*/
|
|
747
|
+
data: number[];
|
|
748
|
+
}, void | {
|
|
749
|
+
error: string;
|
|
750
|
+
} | {
|
|
751
|
+
/**
|
|
752
|
+
* Human-readable error message from the driver
|
|
753
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
754
|
+
*/
|
|
755
|
+
error: string;
|
|
756
|
+
}>>;
|
|
757
|
+
/**
|
|
758
|
+
* @description Writes bytes to the ESC register at `address` on the slave at `slavePosition` using a Configured-Address Write (FPWR) datagram. Pass `address` in decimal (e.g. 272 for DL Status at 0x0110).
|
|
759
|
+
*
|
|
760
|
+
* @name WriteRegister
|
|
761
|
+
* @summary Write bytes to an ESC register
|
|
762
|
+
* @request POST:/api/devices/{slavePosition}/registers/{address}
|
|
763
|
+
*/
|
|
764
|
+
writeRegister: (slavePosition: number, address: number, data: {
|
|
765
|
+
/**
|
|
766
|
+
* Bytes to write in ascending address order
|
|
767
|
+
* @example [1,0]
|
|
768
|
+
*/
|
|
769
|
+
data: number[];
|
|
770
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
771
|
+
/** @example true */
|
|
772
|
+
ok: boolean;
|
|
773
|
+
}, void | {
|
|
774
|
+
error: string;
|
|
775
|
+
} | {
|
|
776
|
+
/**
|
|
777
|
+
* Human-readable error message from the driver
|
|
778
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
779
|
+
*/
|
|
780
|
+
error: string;
|
|
781
|
+
}>>;
|
|
782
|
+
/**
|
|
783
|
+
* @description Reads the process-data watchdog timeout the slave at `slavePosition` is configured with, decoded from the watchdog divider (0x0400) and process-data watchdog time (0x0420) ESC registers. This is the configured timeout itself, not the expiration counter exposed by `GET /api/devices/diagnostics`. A device in OP that misses process data past this timeout faults itself to SAFE-OP+error; raising it lets a device tolerate the brief PDO pause of a whole-bus re-map.
|
|
784
|
+
*
|
|
785
|
+
* @name GetProcessDataWatchdog
|
|
786
|
+
* @summary Read the process-data (sync-manager) watchdog configuration
|
|
787
|
+
* @request GET:/api/devices/{slavePosition}/watchdog
|
|
788
|
+
*/
|
|
789
|
+
getProcessDataWatchdog: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<ProcessDataWatchdog, void | {
|
|
790
|
+
error: string;
|
|
791
|
+
} | {
|
|
792
|
+
/**
|
|
793
|
+
* Human-readable error message from the driver
|
|
794
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
795
|
+
*/
|
|
796
|
+
error: string;
|
|
797
|
+
}>>;
|
|
798
|
+
/**
|
|
799
|
+
* @description Sets the process-data watchdog timeout of the slave at `slavePosition`, writing the process-data watchdog time register (0x0420). The device's watchdog divider (0x0400) is left untouched (it is shared with the PDI watchdog), so the achieved timeout is rounded to that divider's tick base — the response reports the value actually programmed. A `timeoutMs` of 0 disables the watchdog. The write persists across re-maps and re-scans until the ESC reloads EEPROM (power cycle).
|
|
800
|
+
*
|
|
801
|
+
* @name SetProcessDataWatchdog
|
|
802
|
+
* @summary Set the process-data (sync-manager) watchdog timeout
|
|
803
|
+
* @request PUT:/api/devices/{slavePosition}/watchdog
|
|
804
|
+
*/
|
|
805
|
+
setProcessDataWatchdog: (slavePosition: number, data: {
|
|
806
|
+
/**
|
|
807
|
+
* Desired watchdog timeout in milliseconds; 0 disables the watchdog
|
|
808
|
+
* @format double
|
|
809
|
+
* @min 0
|
|
810
|
+
* @example 200
|
|
811
|
+
*/
|
|
812
|
+
timeoutMs: number;
|
|
813
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<ProcessDataWatchdog, void | {
|
|
814
|
+
error: string;
|
|
815
|
+
} | {
|
|
816
|
+
/**
|
|
817
|
+
* Human-readable error message from the driver
|
|
818
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
819
|
+
*/
|
|
820
|
+
error: string;
|
|
821
|
+
}>>;
|
|
822
|
+
/**
|
|
823
|
+
* @description Reads the PDO mapping of the slave at `slavePosition` over CoE, grouped by mapping object: the sync-manager assignment (0x1C12 outputs / 0x1C13 inputs) and, for each assigned mapping object (0x16xx / 0x1Axx), its `pdoIndex` and ordered entries. `outputs` are RxPDO objects (master→slave), `inputs` are TxPDO objects (slave→master). Each entry carries its derived `bitOffset` within the direction's window. This is the grouped, round-trippable counterpart of the flat, whole-bus `GET /api/process-image`. Reads fresh over SDO, so the device's mailbox must be active (PRE-OP, SAFE-OP, or OP); a device in INIT or BOOT yields 409.
|
|
824
|
+
*
|
|
825
|
+
* @name GetDevicePdoMapping
|
|
826
|
+
* @summary Read a device's PDO mapping grouped by object (CoE)
|
|
827
|
+
* @request GET:/api/devices/{slavePosition}/pdo-mapping
|
|
828
|
+
*/
|
|
829
|
+
getDevicePdoMapping: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<PdoMapping, void | {
|
|
830
|
+
/**
|
|
831
|
+
* Human-readable error message from the driver
|
|
832
|
+
* @example "FPRD slave 1: wkc=0"
|
|
833
|
+
*/
|
|
834
|
+
error: string;
|
|
835
|
+
}>>;
|
|
836
|
+
/**
|
|
837
|
+
* @description Reconfigures the PDO mapping of the slave at `slavePosition` over CoE: both directions' sync-manager assignment (0x1C12 outputs / 0x1C13 inputs) and the referenced mapping objects (0x16xx / 0x1Axx). `outputs` are RxPDO objects (master→slave), `inputs` are TxPDO objects (slave→master); the array order is the sync-manager assignment order, which fixes each object's position in the process image. Both directions must be present — an empty array clears that sync manager's assignment. **The device must be in PRE-OP.** The mapping and assignment objects are writable only in PRE-OP; in SAFE-OP/OP the sync managers are active and the slave rejects the write, and INIT/BOOT have no CoE mailbox. This is the "drop to PRE-OP, remap, climb back" flow: take the device to PRE-OP (`POST /api/devices/state`), call this, then transition it back to SAFE-OP/OP — at which point the whole-bus process image is re-mapped from the new mapping. The write follows the CoE ordering rule (clear assignment, rewrite each mapping object, then re-assign), is read back and verified, and is retried a few times so a dropped mailbox frame cannot leave the object dictionary half-configured. The response is the device's grouped read-back mapping (same shape as GET), whose `bitOffset` values are derived by the device (the request omits them). This endpoint does not itself change the AL state or re-map the process image.
|
|
838
|
+
*
|
|
839
|
+
* @name WriteDevicePdoMapping
|
|
840
|
+
* @summary Rewrite a device's PDO mapping (CoE)
|
|
841
|
+
* @request PUT:/api/devices/{slavePosition}/pdo-mapping
|
|
842
|
+
*/
|
|
843
|
+
writeDevicePdoMapping: (slavePosition: number, data: PdoMappingRequest, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<PdoMapping, void | {
|
|
844
|
+
/**
|
|
845
|
+
* Human-readable error message from the driver
|
|
846
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
847
|
+
*/
|
|
848
|
+
error: string;
|
|
849
|
+
}>>;
|
|
850
|
+
/**
|
|
851
|
+
* @description Returns the drive's current control state — the decoded state-machine state, the raw status (0x6041) and control (0x6040) words, and the active operation mode (display object 0x6061). The values are read live (from the process image when the device is exchanging, else over SDO), so poll this to drive a motion UI. Only valid for a CiA402 device (see the isCia402 flag on GET /api/devices).
|
|
852
|
+
*
|
|
853
|
+
* @name GetCia402Status
|
|
854
|
+
* @summary Read a device's CiA402 control snapshot
|
|
855
|
+
* @request GET:/api/devices/{slavePosition}/cia402
|
|
856
|
+
*/
|
|
857
|
+
getCia402Status: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Cia402Status, void>>;
|
|
858
|
+
/**
|
|
859
|
+
* @description Every operation mode the device has, standard and manufacturer-specific, with what the drive says about each. The standard modes are CiA402's (ETG.6010 §6.8.1) and carry the bit of "Supported drive modes" (0x6502) that advertises them, decoded into `supported`. The manufacturer modes are the vendor's own — the negative half of 0x6060 — and are listed only for a device whose vendor this server knows; their `supported` is null, because 0x6502 reserves bits 16-31 for the vendor without defining them, so a drive has no way to advertise one that a master could read. That null means "the drive does not say", not "no". Read this once per device and cache it: it is a static property of the firmware, and the one thing that makes a negative value of 0x6061 nameable rather than "Unknown".
|
|
860
|
+
*
|
|
861
|
+
* @name GetOperationModes
|
|
862
|
+
* @summary List a device's operation modes
|
|
863
|
+
* @request GET:/api/devices/{slavePosition}/operation-modes
|
|
864
|
+
*/
|
|
865
|
+
getOperationModes: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<OperationModes, void>>;
|
|
866
|
+
/**
|
|
867
|
+
* @description Writes the requested operation mode to 0x6060 and returns the resulting control snapshot. The drive reflects the accepted mode in 0x6061 (the modeOfOperation of the response) once it takes effect. Any value object 0x6060 can hold is accepted, standard or manufacturer-specific — the negative half of that range belongs to the vendor, so a SOMANET's diagnostics (-2) or system identification (-4) go through here like any other. Whether a given drive has the mode is the drive's answer, seen in the modeOfOperation of the response; GET /api/devices/{slavePosition}/operation-modes is what lists them beforehand.
|
|
868
|
+
*
|
|
869
|
+
* @name SetCia402OperationMode
|
|
870
|
+
* @summary Set a device's CiA402 operation mode
|
|
871
|
+
* @request POST:/api/devices/{slavePosition}/cia402/mode
|
|
872
|
+
*/
|
|
873
|
+
setCia402OperationMode: (slavePosition: number, data: {
|
|
874
|
+
/**
|
|
875
|
+
* Operation mode to request (the 0x6060 value). Standard modes are 0 NoMode, 1 Profile Position, 2 Velocity, 3 Profile Velocity, 4 Profile Torque, 6 Homing, 7 Interpolated Position, 8 Cyclic Sync Position, 9 Cyclic Sync Velocity, 10 Cyclic Sync Torque, 11 Cyclic Sync Torque with Commutation Angle; negative values are the vendor's.
|
|
876
|
+
* @min -128
|
|
877
|
+
* @max 127
|
|
878
|
+
* @example 9
|
|
879
|
+
*/
|
|
880
|
+
mode: number;
|
|
881
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Cia402Status, void>>;
|
|
882
|
+
/**
|
|
883
|
+
* @description Walks the CiA402 device-control state machine to the state you name, issuing whatever transitions that takes and re-reading the drive between each — so multi-hop paths are ordinary: Switch On Disabled up to Operation Enabled, Quick Stop Active back down to Ready To Switch On. Starting from Fault begins with a fault reset, and a fault whose cause is still present is reported as such (with the drive's 0x603F error code) rather than as a timeout. Only the five states a master can command are accepted. Not Ready To Switch On, Fault Reaction Active and Fault are entered by the drive itself and are rejected as a bad request. **Asking for Operation Enabled while the drive is in Quick Stop Active leaves that quick stop** (CiA402 transition 16), because naming the destination is an explicit instruction to go there. The "enable" command on the sibling endpoint deliberately does not, so a procedure preparing a drive cannot undo somebody's stop by accident. The device must be exchanging process data for any of this to progress — the statusword has to update between polls, and the firmware refuses Operation Enabled unless master communication is live. Returns the resulting control snapshot.
|
|
884
|
+
*
|
|
885
|
+
* @name TransitionToCia402State
|
|
886
|
+
* @summary Bring a drive to a CiA402 state
|
|
887
|
+
* @request POST:/api/devices/{slavePosition}/cia402/state
|
|
888
|
+
*/
|
|
889
|
+
transitionToCia402State: (slavePosition: number, data: {
|
|
890
|
+
/**
|
|
891
|
+
* The state to bring the drive to.
|
|
892
|
+
* @example "OperationEnabled"
|
|
893
|
+
*/
|
|
894
|
+
state: "SwitchOnDisabled" | "ReadyToSwitchOn" | "SwitchedOn" | "OperationEnabled" | "QuickStopActive";
|
|
895
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Cia402Status, void>>;
|
|
896
|
+
/**
|
|
897
|
+
* @description Drives the CiA402 device-control state machine. "enable" walks every intermediate transition to Operation Enabled (clearing a fault first if needed); "disable" goes to Switch On Disabled; "quickStop" triggers a quick stop; "faultReset" clears a latched fault. The device must be exchanging process data for "enable" to make progress. Returns the resulting control snapshot. Use POST /api/devices/{slavePosition}/cia402/state to name a destination instead of an action — it reaches states these four cannot, and it is the one that will leave a quick stop. "enable" here deliberately will not.
|
|
898
|
+
*
|
|
899
|
+
* @name RunCia402Command
|
|
900
|
+
* @summary Run a CiA402 state-machine command
|
|
901
|
+
* @request POST:/api/devices/{slavePosition}/cia402/command
|
|
902
|
+
*/
|
|
903
|
+
runCia402Command: (slavePosition: number, data: {
|
|
904
|
+
/**
|
|
905
|
+
* The state-machine action to perform.
|
|
906
|
+
* @example "enable"
|
|
907
|
+
*/
|
|
908
|
+
command: "enable" | "disable" | "quickStop" | "faultReset";
|
|
909
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Cia402Status, void>>;
|
|
910
|
+
/**
|
|
911
|
+
* @description Writes the one setpoint that matches the active operation mode — target position (0x607A, INTEGER32) in PP/CSP, target velocity (0x60FF, INTEGER32) in PV/CSV, or target torque (0x6071, INTEGER16, per-mille of rated) in PT/CST. All are signed: negative values command reverse motion or regenerative torque. Routes through the live process image when the object is PDO-mapped and the device is exchanging, else an SDO download.
|
|
912
|
+
*
|
|
913
|
+
* @name SetCia402Target
|
|
914
|
+
* @summary Set a CiA402 cyclic setpoint (target)
|
|
915
|
+
* @request POST:/api/devices/{slavePosition}/cia402/target
|
|
916
|
+
*/
|
|
917
|
+
setCia402Target: (slavePosition: number, data: {
|
|
918
|
+
/**
|
|
919
|
+
* Which setpoint to write (pick the one matching the active mode).
|
|
920
|
+
* @example "velocity"
|
|
921
|
+
*/
|
|
922
|
+
target: "position" | "velocity" | "torque";
|
|
923
|
+
/**
|
|
924
|
+
* The setpoint value in the object's own units (signed). For torque it is per-mille of rated and is narrowed to INTEGER16.
|
|
925
|
+
* @example 1000
|
|
926
|
+
*/
|
|
927
|
+
value: number;
|
|
928
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<void, void>>;
|
|
929
|
+
/**
|
|
930
|
+
* @description Copies the actual value into the target of one kind: position actual value (0x6064) into target position (0x607A), velocity actual value (0x606C) into target velocity (0x60FF), or torque actual value (0x6077) into target torque (0x6071). Without `kind` the pair is the one the active operation mode (0x6061) acts on. A drive holds its actual position only until the first setpoint reaches it. In CSP the master sends 0x607A every cycle, so a drive enabled with a stale target position steps to it at once, and that step can pull the supply down. Call this before you enable a drive in CSP. Motion Master never does it on its own: an enable writes the controlword and nothing else.
|
|
931
|
+
*
|
|
932
|
+
* @name SetCia402TargetToActual
|
|
933
|
+
* @summary Set a CiA402 target to its actual value
|
|
934
|
+
* @request POST:/api/devices/{slavePosition}/cia402/target/actual
|
|
935
|
+
*/
|
|
936
|
+
setCia402TargetToActual: (slavePosition: number, query?: {
|
|
937
|
+
/**
|
|
938
|
+
* Which pair to copy. Omit it to copy the pair of the active operation mode.
|
|
939
|
+
* @example "position"
|
|
940
|
+
*/
|
|
941
|
+
kind?: "position" | "velocity" | "torque";
|
|
942
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
943
|
+
/**
|
|
944
|
+
* The pair that was copied.
|
|
945
|
+
* @example "position"
|
|
946
|
+
*/
|
|
947
|
+
kind: "position" | "velocity" | "torque";
|
|
948
|
+
/**
|
|
949
|
+
* The value written, in the object's own units. Torque is per mille of rated, widened from INTEGER16.
|
|
950
|
+
* @example 123456
|
|
951
|
+
*/
|
|
952
|
+
value: number;
|
|
953
|
+
}, void>>;
|
|
954
|
+
/**
|
|
955
|
+
* @description Returns every procedure available on the device, each with its descriptor and the state of its current or last run. One request is enough to render a whole per-device procedures view: the descriptor carries the title, description and caveats to display, and the snapshot says whether anything is running or how the last run went. The list is per device, not global — a procedure is offered only where it applies, so a third-party slave reports an empty list rather than controls that could only ever fail. A procedure that has never run reports an idle snapshot (`status` `idle`, `runCount` 0, every step `idle`), so every entry has the same shape.
|
|
956
|
+
*
|
|
957
|
+
* @name ListProcedures
|
|
958
|
+
* @summary List the procedures a device supports
|
|
959
|
+
* @request GET:/api/devices/{slavePosition}/procedures
|
|
960
|
+
*/
|
|
961
|
+
listProcedures: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<ProcedureListing[], void>>;
|
|
962
|
+
/**
|
|
963
|
+
* @description Starts the named procedure and returns as soon as the run is under way — this does **not** wait for it to finish. Poll `GET` on the same path for its outcome, or `DELETE` to cancel it. The request body carries the procedure's parameters, and each descriptor from `GET /api/devices/{slavePosition}/procedures` reports its own in `parameters` — name, type, bounds, default, and whether it is required — which is enough to build a form for any procedure without hard-coding one per name. A procedure that takes no parameters may be started with no body. Only one procedure may run on a device at a time; a second start is refused with 409 while the first is in flight. Most procedures require an active mailbox, so the device must be in PRE-OP, SAFE-OP or OP. A run the drive answers with an error is not a failure of *this* request — it is reported in the snapshot as a failed run.
|
|
964
|
+
*
|
|
965
|
+
* @name StartProcedure
|
|
966
|
+
* @summary Start a procedure on a device
|
|
967
|
+
* @request POST:/api/devices/{slavePosition}/procedures/{procedureName}
|
|
968
|
+
*/
|
|
969
|
+
startProcedure: (slavePosition: number, procedureName: string, data?: ProcedureRequest, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<ProcedureSnapshot, void>>;
|
|
970
|
+
/**
|
|
971
|
+
* @description Returns the current run, or the last one to have finished. This is the whole progress surface — there is no push channel — and polling it is lossless: every finished step keeps its terminal status and value, so a step that both starts and completes between two polls is still reported as succeeded. A polling loop is `while status == "running"`. A procedure that has never run is not an absence: it reports an idle snapshot built from the procedure's step template, so a client renders one shape and needs no empty-state branch. The snapshot is retained after a run ends, so a client that reconnects (or a user returning to a page) sees how the last run went. It is dropped when the device set is rebuilt by a scan or reset, because bus positions may then name different hardware.
|
|
972
|
+
*
|
|
973
|
+
* @name GetProcedure
|
|
974
|
+
* @summary Read the state of a procedure on a device
|
|
975
|
+
* @request GET:/api/devices/{slavePosition}/procedures/{procedureName}
|
|
976
|
+
*/
|
|
977
|
+
getProcedure: (slavePosition: number, procedureName: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<ProcedureSnapshot, void>>;
|
|
978
|
+
/**
|
|
979
|
+
* @description Asks the running procedure to stop and returns immediately. Where the procedure is waiting on the drive it also tells the drive to abort (for an OS command, 0x1024 = 3), so a run that is waiting stops when asked rather than carrying on to completion. The run then finishes with status `cancelled`. This cancels the *run*, not the record: the snapshot remains and reports how far it got.
|
|
980
|
+
*
|
|
981
|
+
* @name CancelProcedure
|
|
982
|
+
* @summary Cancel a running procedure on a device
|
|
983
|
+
* @request DELETE:/api/devices/{slavePosition}/procedures/{procedureName}
|
|
984
|
+
*/
|
|
985
|
+
cancelProcedure: (slavePosition: number, procedureName: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<void, void>>;
|
|
986
|
+
/**
|
|
987
|
+
* @description Reports both encoder configuration records, 0x2110 (encoder 1) and 0x2112 (encoder 2), and the encoder each controller uses: position control from 0x2012:09, velocity control from 0x2011:05, commutation from 0x2010:0C. A record whose type is `none` is still listed, because the controller fields refer to the ordinal. Read this to learn what one revolution is in position counts. A position in 0x6064 or 0x607A is in counts of the position encoder, unscaled by the gear ratio (0x6091), so one revolution of that encoder is its `resolution`. The feed constant (0x6092) is not applied here.
|
|
988
|
+
*
|
|
989
|
+
* @name GetEncoders
|
|
990
|
+
* @summary Read a SOMANET drive's encoders and which controller uses which
|
|
991
|
+
* @request GET:/api/devices/{slavePosition}/encoders
|
|
992
|
+
*/
|
|
993
|
+
getEncoders: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Encoders, void>>;
|
|
994
|
+
/**
|
|
995
|
+
* @description Reports the brake objects (0x2004) that decide what a release or engage will do: its current state, the release strategy, the pull time and the pull/hold voltages. Read this before commanding the brake. `softwareControllable` is false when the release strategy is `manualOutputVoltage`, meaning the firmware does not drive the brake at all and both commands below are no-ops. `releaseMovesShaft` is true for a pin brake, whose release procedure turns the motor to lift the load off the pin.
|
|
996
|
+
*
|
|
997
|
+
* @name GetBrake
|
|
998
|
+
* @summary Read a drive's brake configuration and state
|
|
999
|
+
* @request GET:/api/devices/{slavePosition}/brake
|
|
1000
|
+
*/
|
|
1001
|
+
getBrake: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<BrakeState, void>>;
|
|
1002
|
+
/**
|
|
1003
|
+
* @description Reads the files the `hrd-streaming` procedure recorded, concatenates them in order and decodes them into samples. Run that procedure first; this endpoint only reads what is already on the drive. **`data` is required and must match what was recorded.** Nothing on the drive says which signal its files hold, so the wrong selection reinterprets the same bytes as a different layout and returns plausible nonsense. The procedure's `configure-stream` step reports the selection it used for exactly this reason. Samples travel positionally — `columns` names the fields of each row, once, the way a monitoring topic ships its parameter order once — because a full recording is up to ten thousand rows. `trailingBytes` is what was left over past the last whole sample: the drive allocates its files in fixed-size blocks, so a recording that does not fill the last block ends in padding rather than data. Answers **JSON or CSV**, chosen by the `Accept` header. CSV is the same numbers in the same column order, one header row then one row per sample — a file to open in a spreadsheet rather than JSON to read, which for ten thousand rows is usually what is wanted. Values are decoded, not raw: `velocityRpm` is converted out of the file's Q15 fixed point (exactly — multiply by 32768 to recover the stored integer), while `torquePermil` and the encoder's `raw` word are the file's own values. Blocks for the transfer, which is up to five 8 KB FoE reads plus the listing.
|
|
1004
|
+
*
|
|
1005
|
+
* @name ReadHrdRecording
|
|
1006
|
+
* @summary Read back a drive's high resolution data recording
|
|
1007
|
+
* @request GET:/api/devices/{slavePosition}/hrd
|
|
1008
|
+
*/
|
|
1009
|
+
readHrdRecording: (slavePosition: number, query: {
|
|
1010
|
+
/**
|
|
1011
|
+
* Which layout the files hold — the same selection the recording was made with.
|
|
1012
|
+
* @example "encoder-raw"
|
|
1013
|
+
*/
|
|
1014
|
+
data: "encoder-raw" | "system-identification";
|
|
1015
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<HrdRecording, void>>;
|
|
1016
|
+
/**
|
|
1017
|
+
* @description Writes "disengaged" to the brake state object (0x2004:07) and waits the drive's pull time (0x2004:03) plus `settle` before answering, because the firmware blocks motion — and motion-related OS commands — until the pull time expires. Answers with the brake state read back. **The release only actually happens while the drive is in OP ENABLED.** In any other state the write merely energises the brake output (phase D). Note also that entering OP ENABLED releases the brake automatically in normal operation but **not** in diagnostics mode, where the master owns the brake — which is why a diagnostics procedure has to call this. **On a pin brake this moves the shaft**: the controller raises current progressively until the load has lifted off the pin by the minimum displacement (0x2004:08), reversing direction if it reaches the current ceiling (0x2004:09, a percentage of rated current) first. Check `releaseMovesShaft` on `GET .../brake`. Brake release is open-loop — nothing confirms the brake let go — so the wait is the only margin there is. A brake whose release strategy is `manualOutputVoltage` is left alone and the returned state says so; that is not an error. **A released brake stays released**: nothing re-engages it for you, so on a vertical or loaded axis engage it again when you are done.
|
|
1018
|
+
*
|
|
1019
|
+
* @name ReleaseBrake
|
|
1020
|
+
* @summary Release (disengage) a drive's brake
|
|
1021
|
+
* @request POST:/api/devices/{slavePosition}/brake/release
|
|
1022
|
+
*/
|
|
1023
|
+
releaseBrake: (slavePosition: number, query?: {
|
|
1024
|
+
/**
|
|
1025
|
+
* Extra wait in milliseconds on top of the drive's pull time. Size it for the machine — release is open-loop, so this is the only margin between "commanded" and "assumed released".
|
|
1026
|
+
* @min 0
|
|
1027
|
+
* @default 50
|
|
1028
|
+
* @example 50
|
|
1029
|
+
*/
|
|
1030
|
+
settle?: number;
|
|
1031
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<BrakeState, void>>;
|
|
1032
|
+
/**
|
|
1033
|
+
* @description Writes "engaged" to the brake state object (0x2004:07) and waits `settle` before answering with the brake state read back. There is no pull time on the way in — a brake is spring-engaged, so engaging it is the removal of voltage — so the wait is only `settle`. As with release, a brake whose release strategy is `manualOutputVoltage` is left alone and the returned state says so.
|
|
1034
|
+
*
|
|
1035
|
+
* @name EngageBrake
|
|
1036
|
+
* @summary Engage a drive's brake
|
|
1037
|
+
* @request POST:/api/devices/{slavePosition}/brake/engage
|
|
1038
|
+
*/
|
|
1039
|
+
engageBrake: (slavePosition: number, query?: {
|
|
1040
|
+
/**
|
|
1041
|
+
* How long to wait in milliseconds after commanding the brake before answering.
|
|
1042
|
+
* @min 0
|
|
1043
|
+
* @default 50
|
|
1044
|
+
* @example 50
|
|
1045
|
+
*/
|
|
1046
|
+
settle?: number;
|
|
1047
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<BrakeState, void>>;
|
|
1048
|
+
/**
|
|
1049
|
+
* @description Performs a CoE SDO upload — reads the value of object `index:subindex` from the device at `slavePosition` and returns the raw bytes as a JSON array. Both `index` and `subindex` accept decimal or hexadecimal notation; prefix with `0x` for hex (e.g. `0x6064` or `24676` for object 0x6064).
|
|
1050
|
+
*
|
|
1051
|
+
* @name SdoUpload
|
|
1052
|
+
* @summary Upload an object dictionary entry from a device (CoE SDO upload)
|
|
1053
|
+
* @request GET:/api/devices/{slavePosition}/sdo/{index}/{subindex}
|
|
1054
|
+
*/
|
|
1055
|
+
sdoUpload: (slavePosition: number, index: number, subindex: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1056
|
+
/**
|
|
1057
|
+
* Object bytes as transferred by the SDO upload
|
|
1058
|
+
* @example [0,0,0,0]
|
|
1059
|
+
*/
|
|
1060
|
+
data: number[];
|
|
1061
|
+
}, void | {
|
|
1062
|
+
/**
|
|
1063
|
+
* Human-readable error message from the driver
|
|
1064
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
1065
|
+
*/
|
|
1066
|
+
error: string;
|
|
1067
|
+
}>>;
|
|
1068
|
+
/**
|
|
1069
|
+
* @description Performs a CoE SDO download — writes the raw bytes in the request body to object `index:subindex` on the device at `slavePosition`. The byte count must match the object's length. Requires the device to be in PRE-OP, SAFE-OP, or OP (mailbox communication active). Both `index` and `subindex` accept decimal or hexadecimal notation; prefix with `0x` for hex (e.g. `0x6064` or `24676`).
|
|
1070
|
+
*
|
|
1071
|
+
* @name SdoDownload
|
|
1072
|
+
* @summary Download an object dictionary entry to a device (CoE SDO download)
|
|
1073
|
+
* @request PUT:/api/devices/{slavePosition}/sdo/{index}/{subindex}
|
|
1074
|
+
*/
|
|
1075
|
+
sdoDownload: (slavePosition: number, index: number, subindex: number, data: {
|
|
1076
|
+
/**
|
|
1077
|
+
* Object bytes to write (little-endian, must match the object length)
|
|
1078
|
+
* @example [100,0,0,0]
|
|
1079
|
+
*/
|
|
1080
|
+
data: number[];
|
|
1081
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1082
|
+
/** @example true */
|
|
1083
|
+
ok: boolean;
|
|
1084
|
+
}, void | {
|
|
1085
|
+
/**
|
|
1086
|
+
* Human-readable error message from the driver
|
|
1087
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
1088
|
+
*/
|
|
1089
|
+
error: string;
|
|
1090
|
+
}>>;
|
|
1091
|
+
/**
|
|
1092
|
+
* @description Lists what the device holds — firmware images, the ESI, logs, configuration and any high resolution data recording — with the size it reports for each. **Vendor-specific despite reading like a filesystem listing.** EtherCAT defines no directory service, so SOMANET firmware serves its own as a pseudo-file (`fs-getlist`) read over FoE. A device that is not a SOMANET drive is refused rather than probed. `byteCount` is absent when the device reported a name without a size, which is a formatting quirk of one entry rather than a reason to hide the file.
|
|
1093
|
+
*
|
|
1094
|
+
* @name ListDeviceFiles
|
|
1095
|
+
* @summary List the files stored on a device
|
|
1096
|
+
* @request GET:/api/devices/{slavePosition}/files
|
|
1097
|
+
*/
|
|
1098
|
+
listDeviceFiles: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<DeviceFile[], void>>;
|
|
1099
|
+
/**
|
|
1100
|
+
* @description Reads and decodes the device's `.hardware_description` file over FoE — its product id and revision, serial number, the components it is built from, and the assembly it was packaged into. It is also the only source of the descriptor that decides which firmware belongs on the device, which is what most callers want it for (see `/api/devices/{slavePosition}/firmware-compatibility`). **Readable in BOOT as well as PRE-OP and above.** The bootloader deliberately allows this one file, which is what lets a compatibility check work on a drive a failed install left stranded there — precisely when knowing whether the package was the right one matters most.
|
|
1101
|
+
*
|
|
1102
|
+
* @name GetDeviceHardwareDescription
|
|
1103
|
+
* @summary Read what a device says it is
|
|
1104
|
+
* @request GET:/api/devices/{slavePosition}/hardware-description
|
|
1105
|
+
*/
|
|
1106
|
+
getDeviceHardwareDescription: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<HardwareDescription, void>>;
|
|
1107
|
+
/**
|
|
1108
|
+
* @description Reads and decodes the device's `.variant` file over FoE — which features the Integro was licensed with. **A 404 is the ordinary answer for most devices.** Only Integro drives carry this file, so the resource being absent is normal rather than a problem. Its one property that matters beyond inspection is `fieldbusProtocol`, which the hardware description deliberately does not carry and a full firmware descriptor ends with.
|
|
1109
|
+
*
|
|
1110
|
+
* @name GetDeviceIntegroVariant
|
|
1111
|
+
* @summary Read a device's Integro variant file
|
|
1112
|
+
* @request GET:/api/devices/{slavePosition}/variant
|
|
1113
|
+
*/
|
|
1114
|
+
getDeviceIntegroVariant: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<IntegroVariant, void>>;
|
|
1115
|
+
/**
|
|
1116
|
+
* @description Reads the device's `.hardware_description` and `.variant`, assembles the full firmware descriptors it accepts, and compares them against the descriptor in `filename`. **A mismatch is a `200` carrying `compatible: false`**, not an error status: the client asked a question and got an answer, and the body names both descriptors so it can say which hardware the package was for. A `4xx` means the question could not be asked — the filename is not a package name, or the hardware description could not be read. **Nothing acts on the answer.** The firmware installation procedure writes whatever it is given, on purpose, so this exists to tell a user before they start.
|
|
1117
|
+
*
|
|
1118
|
+
* @name CheckDeviceFirmwareCompatibility
|
|
1119
|
+
* @summary Check whether a firmware package belongs on a device
|
|
1120
|
+
* @request GET:/api/devices/{slavePosition}/firmware-compatibility
|
|
1121
|
+
*/
|
|
1122
|
+
checkDeviceFirmwareCompatibility: (slavePosition: number, query: {
|
|
1123
|
+
/**
|
|
1124
|
+
* The package filename, with no directory part.
|
|
1125
|
+
* @example "package_SOMANET-Circulo-7_8500-04-2332_motion-drive_v5.6.10.zip"
|
|
1126
|
+
*/
|
|
1127
|
+
filename: string;
|
|
1128
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<FirmwareCompatibility, void>>;
|
|
1129
|
+
/**
|
|
1130
|
+
* @description Sends an FoE read request for `filename` to the device at `slavePosition` and returns the raw file bytes. FoE is available in Boot, Pre-Op, Safe-Op, and Op states (device-dependent); the caller is responsible for ensuring the device is in a suitable state before calling. The call blocks until the full file has been received. Over EtherCAT it waits up to 6 s for the device's answer and tries a read that gets no answer up to 3 times, so a device that never answers takes about 18 s to fail. A refusal from the device is not tried again. After a failure without an answer, Motion Master aborts the transfer on the device, so that the next request works. Over SPoE it waits the configured file timeout for each packet. When the device refuses the read, the error names the FoE error code it sent and its meaning, and the device's error text when that adds anything, e.g. `FOEread slave 1 'x.bin' failed (FoE error 0x8001: Not found)`. A device that never answered gives `(no response)`.
|
|
1131
|
+
*
|
|
1132
|
+
* @name FoeReadFile
|
|
1133
|
+
* @summary Read a file from a device via FoE (File over EtherCAT)
|
|
1134
|
+
* @request GET:/api/devices/{slavePosition}/files/{filename}
|
|
1135
|
+
*/
|
|
1136
|
+
foeReadFile: (slavePosition: number, filename: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Blob, void | {
|
|
1137
|
+
/**
|
|
1138
|
+
* Human-readable error message from the driver
|
|
1139
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
1140
|
+
*/
|
|
1141
|
+
error: string;
|
|
1142
|
+
}>>;
|
|
1143
|
+
/**
|
|
1144
|
+
* @description Sends an FoE write request for `filename` to the device at `slavePosition`, streaming the raw request body as the file contents. FoE is available in Boot, Pre-Op, Safe-Op, and Op states (device-dependent); the caller is responsible for ensuring the device is in a suitable state before calling. Over EtherCAT it waits up to 10 s for the device to acknowledge each packet. A write that fails without an answer is aborted on the device and is not tried again.
|
|
1145
|
+
*
|
|
1146
|
+
* @name FoeWriteFile
|
|
1147
|
+
* @summary Write a file to a device via FoE (File over EtherCAT)
|
|
1148
|
+
* @request PUT:/api/devices/{slavePosition}/files/{filename}
|
|
1149
|
+
*/
|
|
1150
|
+
foeWriteFile: (slavePosition: number, filename: string, data: File, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1151
|
+
/** @example true */
|
|
1152
|
+
ok?: boolean;
|
|
1153
|
+
}, void | {
|
|
1154
|
+
/**
|
|
1155
|
+
* Human-readable error message from the driver
|
|
1156
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
1157
|
+
*/
|
|
1158
|
+
error: string;
|
|
1159
|
+
}>>;
|
|
1160
|
+
/**
|
|
1161
|
+
* @description Deletes `filename` from the flash of the device at `slavePosition`. Motion Master waits up to 10 s for the device to answer, and 30 s for the ESI (`SOMANET_CiA_402.xml.zip`), because the device answers only after it has erased the file. **Vendor-specific despite reading like a filesystem operation.** FoE has no delete, so SOMANET firmware acts on a pseudo-file instead: reading the name `fs-remove=<filename>` removes that file. This endpoint exists so no client has to know that, and a device that is not a SOMANET drive is refused rather than probed. **A file that was not there answers 200.** The caller asked for the file to be gone, and it is. Every other FoE failure is a 500 naming the reason. The file is gone from flash immediately. Deleting `config.csv` discards the stored parameter values, so the drive falls back to its defaults on the next power cycle.
|
|
1162
|
+
*
|
|
1163
|
+
* @name DeleteDeviceFile
|
|
1164
|
+
* @summary Delete a file from a device
|
|
1165
|
+
* @request DELETE:/api/devices/{slavePosition}/files/{filename}
|
|
1166
|
+
*/
|
|
1167
|
+
deleteDeviceFile: (slavePosition: number, filename: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1168
|
+
/** @example true */
|
|
1169
|
+
ok?: boolean;
|
|
1170
|
+
}, void | {
|
|
1171
|
+
/**
|
|
1172
|
+
* Human-readable error message from the driver
|
|
1173
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
1174
|
+
*/
|
|
1175
|
+
error: string;
|
|
1176
|
+
}>>;
|
|
1177
|
+
/**
|
|
1178
|
+
* @description Reads the raw SII EEPROM image of the device at `slavePosition` through the ESC's EEPROM-control registers and returns either the parsed structure or the raw bytes, selected by the `Accept` request header. With `Accept: application/json` (or `*\/*`, or no `Accept` header) the parsed `SlaveInformationInterface` is returned — the 128-byte fixed header plus the decoded category section (strings, general info, FMMU/Sync-Manager and PDO defaults, distributed-clock settings). With `Accept: application/octet-stream` the raw EEPROM image is returned unparsed, suitable for a hex dump or archival. EEPROM access is a control-plane operation and is most reliable while the device is in INIT or PRE-OP. String-index fields in the parsed structure (e.g. `general.nameIdx`) are 1-based references into `category.strings`.
|
|
1179
|
+
*
|
|
1180
|
+
* @name ReadSii
|
|
1181
|
+
* @summary Read a device's SII (Slave Information Interface / EEPROM)
|
|
1182
|
+
* @request GET:/api/devices/{slavePosition}/sii
|
|
1183
|
+
*/
|
|
1184
|
+
readSii: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<SlaveInformationInterface, void | {
|
|
1185
|
+
error: string;
|
|
1186
|
+
} | {
|
|
1187
|
+
/**
|
|
1188
|
+
* Human-readable error message from the driver
|
|
1189
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
1190
|
+
*/
|
|
1191
|
+
error: string;
|
|
1192
|
+
}>>;
|
|
1193
|
+
/**
|
|
1194
|
+
* @description Writes the raw SII image in the request body to the device's EEPROM, one 16-bit word at a time. The image is parse-validated first and rejected if it is not a well-formed SII (a guard against bricking the device). **Destructive:** a wrong image can leave the device unidentifiable until re-flashed. The device adopts the new contents only after a **power cycle**, and the write is most reliable while the device is in INIT or PRE-OP. Intended for restoring a previously downloaded image.
|
|
1195
|
+
*
|
|
1196
|
+
* @name WriteSii
|
|
1197
|
+
* @summary Write a raw SII (EEPROM) image to a device
|
|
1198
|
+
* @request PUT:/api/devices/{slavePosition}/sii
|
|
1199
|
+
*/
|
|
1200
|
+
writeSii: (slavePosition: number, data: File, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1201
|
+
/** @example true */
|
|
1202
|
+
ok?: boolean;
|
|
1203
|
+
}, void | {
|
|
1204
|
+
error: string;
|
|
1205
|
+
} | {
|
|
1206
|
+
/**
|
|
1207
|
+
* Human-readable error message from the driver
|
|
1208
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
1209
|
+
*/
|
|
1210
|
+
error: string;
|
|
1211
|
+
}>>;
|
|
1212
|
+
/**
|
|
1213
|
+
* @description Decodes a raw SII EEPROM image supplied in the request body and returns the parsed structure — the same decoder the device read path uses, exposed as a bus-independent utility. No device is involved; the Tools SII page uses this to view previously downloaded `.bin` files offline.
|
|
1214
|
+
*
|
|
1215
|
+
* @name ParseSii
|
|
1216
|
+
* @summary Parse a raw SII (EEPROM) image
|
|
1217
|
+
* @request POST:/api/sii/parse
|
|
1218
|
+
*/
|
|
1219
|
+
parseSii: (data: File, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<SlaveInformationInterface, void>>;
|
|
1220
|
+
/**
|
|
1221
|
+
* @description Breaks a firmware package filename into the five fields the SOMANET naming convention defines (Hardware description specification §3.4.2) — `package_<hardware>_<fullFirmwareDescriptor>_<software>_v<version>.zip` — and, where the descriptor is the numeric `<id>-<version>[-<key>[-<fieldbus>]]` kind, decodes it further. The specification allows a descriptor that is not (its own example `Branded-Drive-Elite` carries `MyProduct-v25-key3-ecat`), so those four fields are omitted rather than guessed. Bus-independent, like `/api/sii/parse` and `/api/esi/parse`, but a `GET` with a query because there is no file to upload — only a short string. This is the same decoder firmware installation uses to decide whether a package can be cached, so what it reports is what that will do.
|
|
1222
|
+
*
|
|
1223
|
+
* @name GetFirmwarePackageName
|
|
1224
|
+
* @summary Decode a SOMANET firmware package filename
|
|
1225
|
+
* @request GET:/api/firmware-package-name
|
|
1226
|
+
*/
|
|
1227
|
+
getFirmwarePackageName: (query: {
|
|
1228
|
+
/**
|
|
1229
|
+
* The package filename, with no directory part.
|
|
1230
|
+
* @example "package_SOMANET-Circulo-7_8500-04-2332_motion-drive_v5.6.10.zip"
|
|
1231
|
+
*/
|
|
1232
|
+
filename: string;
|
|
1233
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<FirmwarePackageName, void>>;
|
|
1234
|
+
/**
|
|
1235
|
+
* @description Decodes a `.hardware_description` supplied in the request body. No device is involved — the same parse a device read uses, so a file saved from one device can be inspected with no hardware present. Three things fail a parse: content that is not JSON, content with no `device` object, and a device carrying no `id` or no `version`. Everything else is accepted as written. Those three required fields are exactly what a descriptor is built from, which is also what makes this a usable type check — arbitrary JSON is rejected rather than yielding an empty descriptor. The `fileVersion` major is reported but not enforced: a bump means "a new parser is needed", but refusing an unknown one would make a drive flashed with a future file unreadable today.
|
|
1236
|
+
*
|
|
1237
|
+
* @name ParseHardwareDescription
|
|
1238
|
+
* @summary Parse a .hardware_description file
|
|
1239
|
+
* @request POST:/api/hardware-description/parse
|
|
1240
|
+
*/
|
|
1241
|
+
parseHardwareDescription: (data: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<HardwareDescription, void>>;
|
|
1242
|
+
/**
|
|
1243
|
+
* @description Decodes a `.variant` file supplied in the request body. Binary rather than text, hence a `POST` with bytes like `/api/sii/parse` rather than a query like `/api/firmware-package-name`. Trailing bytes past the last option are accepted: the firmware reads only as many options as the count claims and ignores the rest, so refusing padding would reject a file the drive is happy with.
|
|
1244
|
+
*
|
|
1245
|
+
* @name ParseIntegroVariant
|
|
1246
|
+
* @summary Parse a .variant file
|
|
1247
|
+
* @request POST:/api/integro-variant/parse
|
|
1248
|
+
*/
|
|
1249
|
+
parseIntegroVariant: (data: File, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<IntegroVariant, void>>;
|
|
1250
|
+
/**
|
|
1251
|
+
* @description Every option an Integro can be licensed with, in code order. Static data: no device, no bus, no request body. Served so a client can explain a decoded file — or simply show what is available — without carrying a second copy of a table that belongs to the firmware. The codes ascend with real gaps, and the catalogue keeps codes current firmware no longer implements, because files written years ago still carry them.
|
|
1252
|
+
*
|
|
1253
|
+
* @name ListIntegroVariantOptions
|
|
1254
|
+
* @summary The whole Integro variant option catalogue
|
|
1255
|
+
* @request GET:/api/integro-variant/options
|
|
1256
|
+
*/
|
|
1257
|
+
listIntegroVariantOptions: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<IntegroVariantOption[], any>>;
|
|
1258
|
+
/**
|
|
1259
|
+
* @description Decodes an ENI document supplied in the request body. No device is involved, and that is the point: the useful case is reading a configuration somebody else's tool wrote — acontis EC-Engineer, TwinCAT — rather than the one this master exports from `GET /api/eni`. **An ENI is a script, not a description.** Every configuration step in it is an EtherCAT datagram or a CoE download tagged with the AL-state transition it belongs to, so a listing of the raw elements would show `FPWR to 2064, data 0018060064000100` and leave the reading undone. Each datagram therefore carries a `register` object naming what its `ado` selects, with the instance for a repeating block, and `decoded` fields where the payload is a sync-manager or FMMU register block. A write to AL Control reports `requestsState`, and the read that follows it reports `waitsForState`. Every enumeration is spelled out beside its value — `cmd` 5 with `cmdName` `FPWR`, transitions as `IP`/`PS`/`SO` — and every payload carries its hex beside its byte count, because the reader of this JSON is a person rather than a master. Tolerant by design. Only three things fail: XML that will not parse, a root that is not `EtherCATConfig`, and a missing `Config`. Anything else costs that value and a line in `warnings`, including an element this model has no room for. The sample documents ETG itself ships need that tolerance: two of them omit elements their own schema marks mandatory, and a previous port of `A` is spec-legal while ENI Schema 1.7 enumerates only `B`, `C` and `D`.
|
|
1260
|
+
*
|
|
1261
|
+
* @name ParseEni
|
|
1262
|
+
* @summary Parse an EtherCAT Network Information (ENI) file
|
|
1263
|
+
* @request POST:/api/eni/parse
|
|
1264
|
+
*/
|
|
1265
|
+
parseEni: (data: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1266
|
+
/** The master, every device, the cyclic frame and the process image, keyed by the model's own field names. */
|
|
1267
|
+
network: object;
|
|
1268
|
+
/** One line per element seen and not modelled, or per value that would not decode. Each names a place in the document. */
|
|
1269
|
+
warnings: string[];
|
|
1270
|
+
summary: {
|
|
1271
|
+
/** Devices in the document */
|
|
1272
|
+
devices: number;
|
|
1273
|
+
/** EtherCAT init commands, master and devices together */
|
|
1274
|
+
datagrams: number;
|
|
1275
|
+
/** CoE init commands, which live under a device's mailbox */
|
|
1276
|
+
coeTransfers: number;
|
|
1277
|
+
};
|
|
1278
|
+
}, void>>;
|
|
1279
|
+
/**
|
|
1280
|
+
* @description Decodes a vendor's ESI XML supplied in the request body. No device is involved — the Tools page uses this to inspect an ESI with no hardware present, which is the only way to see object descriptions, enum option labels, engineering units and min/max bounds: the CoE SDO-Information service reports none of them. The response carries the vendor, every module, and **every device with its own assembled `entries` table** — one row per addressable `(index, subindex)`, merged from the device's own dictionary plus the dictionaries of the modules its slots reference, with each row recording in `source` where it came from. Object-level annotation (an object's description and raw properties) is attached to **subindex 0 only** — that row *is* the object — rather than repeated onto every subindex. A RECORD member still carries its own description on its own row; an ARRAY element carries none, because the ESI describes an array once rather than per element. To read an object's text for any subindex, look at subindex 0 of the same index. Where a slot offers mutually exclusive module variants the merge necessarily collides; it is resolved last-wins and reported in that device's `warnings`. Pass `modules` to model one concrete configuration instead.
|
|
1281
|
+
*
|
|
1282
|
+
* @name ParseEsi
|
|
1283
|
+
* @summary Parse an EtherCAT Slave Information (ESI) file
|
|
1284
|
+
* @request POST:/api/esi/parse
|
|
1285
|
+
*/
|
|
1286
|
+
parseEsi: (data: string, query?: {
|
|
1287
|
+
/** Comma-separated `ModuleIdent` values (hexadecimal or decimal) restricting the merge, applied to every device by intersection with the idents that device's slots actually reference. Omit to merge every module each device references. */
|
|
1288
|
+
modules?: string;
|
|
1289
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<EsiParseResult, void>>;
|
|
1290
|
+
/**
|
|
1291
|
+
* @description Reads live link-quality and watchdog diagnostics from each slave's EtherCAT Slave Controller (DL Status 0x0110, error-counter block 0x0300–0x0313, watchdog block 0x0440–0x0443) via FPRD. Counters are 8-bit, saturate at 255, and are cleared only by a power cycle or explicit write — poll this endpoint and watch for a rising delta rather than an absolute value. The per-port counters localise a degrading link to a specific cable/connector; the watchdog counters distinguish a slave that stopped receiving process data from a master-side problem. Omit `positions` to query all discovered devices. Returns 500 for transports without an ESC (e.g. SPoE).
|
|
1292
|
+
*
|
|
1293
|
+
* @name GetDeviceDiagnostics
|
|
1294
|
+
* @summary Read live ESC health diagnostics for devices
|
|
1295
|
+
* @request GET:/api/devices/diagnostics
|
|
1296
|
+
*/
|
|
1297
|
+
getDeviceDiagnostics: (query?: {
|
|
1298
|
+
/**
|
|
1299
|
+
* Comma-separated list of 1-based slave positions to query (e.g. `1,2,3`). Omit to query all discovered devices.
|
|
1300
|
+
* @example "1,2"
|
|
1301
|
+
*/
|
|
1302
|
+
positions?: string;
|
|
1303
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<DeviceDiagnostics[], void | {
|
|
1304
|
+
error: string;
|
|
1305
|
+
} | {
|
|
1306
|
+
/**
|
|
1307
|
+
* Human-readable error message from the driver
|
|
1308
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
1309
|
+
*/
|
|
1310
|
+
error: string;
|
|
1311
|
+
}>>;
|
|
1312
|
+
/**
|
|
1313
|
+
* @description Reads each slave's distributed-clock unit live from its EtherCAT Slave Controller (system-time delay 0x0928 and system-time difference 0x092C) via FPRD. The reference clock is the first DC-capable slave; every other DC slave continuously corrects its local clock toward it, and `systemTimeDifference` is the live deviation in nanoseconds. The figure is meaningful only while the bus is exchanging process data in SAFE-OP/OP (the reference time is distributed in the cyclic frame) and converges toward zero as the slaves' drift loops settle — poll this endpoint and watch for a slave whose deviation stays large or grows rather than an absolute value. Non-DC slaves report `dcCapable` false with zeroed values. Omit `positions` to query all discovered devices. Returns 500 for transports without an ESC (e.g. SPoE).
|
|
1314
|
+
*
|
|
1315
|
+
* @name GetDcSync
|
|
1316
|
+
* @summary Read live distributed-clock synchronisation status for devices
|
|
1317
|
+
* @request GET:/api/dc-sync
|
|
1318
|
+
*/
|
|
1319
|
+
getDcSync: (query?: {
|
|
1320
|
+
/**
|
|
1321
|
+
* Comma-separated list of 1-based slave positions to query (e.g. `1,2,3`). Omit to query all discovered devices.
|
|
1322
|
+
* @example "1,2"
|
|
1323
|
+
*/
|
|
1324
|
+
positions?: string;
|
|
1325
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<DcSyncStatus[], void | {
|
|
1326
|
+
error: string;
|
|
1327
|
+
} | {
|
|
1328
|
+
/**
|
|
1329
|
+
* Human-readable error message from the driver
|
|
1330
|
+
* @example "SDOread slave 1 0x2345:01 failed (no response — mailbox timeout)"
|
|
1331
|
+
*/
|
|
1332
|
+
error: string;
|
|
1333
|
+
}>>;
|
|
1334
|
+
/**
|
|
1335
|
+
* @description Runs the capture program `motion-master-capture`, which ships beside the server binary, on the adapter the bus is on, waits for it to exit, and answers the summary. The program records every EtherCAT frame that leaves or enters the adapter with a kernel timestamp and writes them as a pcap file under `captures/` in the user cache, so the file is listed, downloaded and deleted through the `/api/user-cache` routes and opens in Wireshark. The summary matches each frame the master sent to the frame that came back for it, by the index and the header of its first datagram, and reports per kind of frame how late the returns were. The cyclic process-data frame is one kind; mailbox and register datagrams, the control plane, are the other. The bands are the three waits the driver uses, 2 ms, 20 ms and 100 ms, and they are cumulative: a frame later than 100 ms counts in all three. A frame sent again with the same index and header while its first copy had no answer counts once, as `resent`, and its return is timed from the first copy. The time is the kernel's, taken at the boundary to the NIC driver on both sides: when the frame is handed to the driver, and when the driver hands its return back. So the number covers the NIC, the wire and the device, and not the host's own queues and scheduling between that boundary and Motion Master. A capture that shows late frames puts the delay on the wire or in the device. A clean capture beside the server's own warnings, "mailbox write(s) got no frame back", puts it inside the host. Read the two together. One capture at a time. The capture adds no frame to the bus and runs on a thread of its own, so the bus is not touched. The program needs `CAP_NET_RAW`, which the packages grant it at install.
|
|
1336
|
+
*
|
|
1337
|
+
* @name RunCapture
|
|
1338
|
+
* @summary Record the EtherCAT frames of the bus adapter for a number of seconds
|
|
1339
|
+
* @request POST:/api/captures
|
|
1340
|
+
*/
|
|
1341
|
+
runCapture: (data?: {
|
|
1342
|
+
/**
|
|
1343
|
+
* How long to record. A capture is a measurement a person starts.
|
|
1344
|
+
* @min 1
|
|
1345
|
+
* @max 120
|
|
1346
|
+
* @default 30
|
|
1347
|
+
*/
|
|
1348
|
+
seconds?: number;
|
|
1349
|
+
/**
|
|
1350
|
+
* The adapter to record, when no bus is up. Defaults to the adapter of the bus.
|
|
1351
|
+
* @example "enp0s13f0u1u2"
|
|
1352
|
+
*/
|
|
1353
|
+
adapter?: string;
|
|
1354
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1355
|
+
/**
|
|
1356
|
+
* The pcap file, relative to the user-cache root
|
|
1357
|
+
* @example "captures/capture-20261022-143005-enp0s13f0u1u2.pcap"
|
|
1358
|
+
*/
|
|
1359
|
+
path: string;
|
|
1360
|
+
/** @example "enp0s13f0u1u2" */
|
|
1361
|
+
adapter: string;
|
|
1362
|
+
/** @example 30 */
|
|
1363
|
+
seconds: number;
|
|
1364
|
+
/** How late the frames of a capture came back. See `POST /api/captures`. */
|
|
1365
|
+
summary: CaptureSummary;
|
|
1366
|
+
}, void | {
|
|
1367
|
+
error: string;
|
|
1368
|
+
}>>;
|
|
1369
|
+
/**
|
|
1370
|
+
* @description Reads `captures/{name}` from the user cache and answers the summary that `POST /api/captures` answers, over any Ethernet pcap: a file the server recorded, or one from `tcpdump` on another host that a user put into `captures/` with `PUT /api/user-cache/captures/{name}`. Microsecond and nanosecond timestamps and both byte orders are read.
|
|
1371
|
+
*
|
|
1372
|
+
* @name GetCaptureSummary
|
|
1373
|
+
* @summary Summarise a pcap file in the user cache
|
|
1374
|
+
* @request GET:/api/captures/{name}
|
|
1375
|
+
*/
|
|
1376
|
+
getCaptureSummary: (name: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1377
|
+
/** @example "captures/capture-20261022-143005-enp0s13f0u1u2.pcap" */
|
|
1378
|
+
path: string;
|
|
1379
|
+
/** How late the frames of a capture came back. See `POST /api/captures`. */
|
|
1380
|
+
summary: CaptureSummary;
|
|
1381
|
+
}, void>>;
|
|
1382
|
+
/**
|
|
1383
|
+
* @description Reads the current EtherCAT Application Layer state for one or more devices. Omit the `positions` query parameter to query all discovered devices.
|
|
1384
|
+
*
|
|
1385
|
+
* @name GetDeviceStates
|
|
1386
|
+
* @summary Read current AL state for devices
|
|
1387
|
+
* @request GET:/api/devices/state
|
|
1388
|
+
*/
|
|
1389
|
+
getDeviceStates: (query?: {
|
|
1390
|
+
/**
|
|
1391
|
+
* Comma-separated list of 1-based slave positions to query (e.g. `1,2,3`). Omit to query all discovered devices.
|
|
1392
|
+
* @example "1,2"
|
|
1393
|
+
*/
|
|
1394
|
+
positions?: string;
|
|
1395
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1396
|
+
/**
|
|
1397
|
+
* 1-based position on the fieldbus
|
|
1398
|
+
* @example 1
|
|
1399
|
+
*/
|
|
1400
|
+
slavePosition: number;
|
|
1401
|
+
/**
|
|
1402
|
+
* Raw AL Status register value (ETG.1000.6 §6.4.1). Bits 3:0 encode the state; bit 4 is the error indicator.
|
|
1403
|
+
* @example 17
|
|
1404
|
+
*/
|
|
1405
|
+
alStatus: number;
|
|
1406
|
+
/**
|
|
1407
|
+
* Current AL state decoded from alStatus (ETG.1000.6 encoding): 1 = Init, 2 = PreOp, 3 = Boot, 4 = SafeOp, 8 = Op. 0 when the device does not answer (see `reachability`).
|
|
1408
|
+
* @example 1
|
|
1409
|
+
*/
|
|
1410
|
+
alState: 0 | 1 | 2 | 3 | 4 | 8;
|
|
1411
|
+
/**
|
|
1412
|
+
* True when the AL Status error indicator bit (bit 4) is set
|
|
1413
|
+
* @example true
|
|
1414
|
+
*/
|
|
1415
|
+
error: boolean;
|
|
1416
|
+
/**
|
|
1417
|
+
* AL Status Code register (ETG.1000.6 §6.4.1). Non-zero when error is true; identifies the error cause (e.g. 0x0014 = No valid firmware).
|
|
1418
|
+
* @example 20
|
|
1419
|
+
*/
|
|
1420
|
+
alStatusCode: number;
|
|
1421
|
+
/**
|
|
1422
|
+
* Whether the device answers at the station address the master gave it. `addressLost`: nothing answers at that address, but a device answers at its wire position. A reset, such as a power cycle, clears the address. Run `POST /api/scan` to command it again. `notAnswering`: nothing answers at that address or at its wire position. Check the cabling and the power. If devices were removed from the chain, run a scan. The wire position is checked by position only, so after a change to the chain the device that answers there can be a different one. When the value is not `answering`, the state of the device is unknown, and `alStatus`, `alState` and `alStatusCode` are 0.
|
|
1423
|
+
* @example "answering"
|
|
1424
|
+
*/
|
|
1425
|
+
reachability: "answering" | "addressLost" | "notAnswering";
|
|
1426
|
+
}[], void | {
|
|
1427
|
+
/**
|
|
1428
|
+
* Human-readable error message from the driver
|
|
1429
|
+
* @example "FPRD slave 1: wkc=0"
|
|
1430
|
+
*/
|
|
1431
|
+
error: string;
|
|
1432
|
+
}>>;
|
|
1433
|
+
/**
|
|
1434
|
+
* @description Commands one or more devices to the requested EtherCAT Application Layer state and blocks until all targeted devices arrive or the timeout elapses. The settled state of every targeted device is then read back and returned in `devices`, each with a `reached` flag; `ok` is true only when every device reached the target. A device that did not reach it carries an `alStatusCode` explaining why. A device that does not answer at its address is not commanded, so the request does not wait out the timeout for it. Its `reachability` says why, and the other devices are still commanded. Omit `positions` or pass an empty array to target all discovered devices. State values are the standard AL state register encodings from ETG.1000.6: 1 (Init), 2 (PreOp), 3 (Boot), 4 (SafeOp), 8 (Op).
|
|
1435
|
+
*
|
|
1436
|
+
* @name TransitionToState
|
|
1437
|
+
* @summary Transition devices to an EtherCAT AL state
|
|
1438
|
+
* @request POST:/api/devices/state
|
|
1439
|
+
*/
|
|
1440
|
+
transitionToState: (data: {
|
|
1441
|
+
/**
|
|
1442
|
+
* 1-based slave positions to target. Omit or pass an empty array to target all discovered devices.
|
|
1443
|
+
* @example [1,2]
|
|
1444
|
+
*/
|
|
1445
|
+
positions?: number[];
|
|
1446
|
+
/**
|
|
1447
|
+
* Target EtherCAT AL state (ETG.1000.6 AL control register encoding): 1 = Init, 2 = PreOp, 3 = Boot, 4 = SafeOp, 8 = Op.
|
|
1448
|
+
* @example 8
|
|
1449
|
+
*/
|
|
1450
|
+
state: 1 | 2 | 3 | 4 | 8;
|
|
1451
|
+
/**
|
|
1452
|
+
* Maximum time to wait for all devices, in milliseconds
|
|
1453
|
+
* @default 5000
|
|
1454
|
+
* @example 5000
|
|
1455
|
+
*/
|
|
1456
|
+
timeout?: number;
|
|
1457
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1458
|
+
/**
|
|
1459
|
+
* True only when every targeted device reached the target state.
|
|
1460
|
+
* @example true
|
|
1461
|
+
*/
|
|
1462
|
+
ok: boolean;
|
|
1463
|
+
/** Settled state of each targeted device, in the order targeted. */
|
|
1464
|
+
devices: {
|
|
1465
|
+
/**
|
|
1466
|
+
* 1-based position on the fieldbus
|
|
1467
|
+
* @example 1
|
|
1468
|
+
*/
|
|
1469
|
+
slavePosition: number;
|
|
1470
|
+
/**
|
|
1471
|
+
* Raw AL Status register value (ETG.1000.6 §6.4.1). Bits 3:0 encode the state; bit 4 is the error indicator.
|
|
1472
|
+
* @example 2
|
|
1473
|
+
*/
|
|
1474
|
+
alStatus: number;
|
|
1475
|
+
/**
|
|
1476
|
+
* Current AL state decoded from alStatus (ETG.1000.6 encoding): 1 = Init, 2 = PreOp, 3 = Boot, 4 = SafeOp, 8 = Op. 0 when the device does not answer (see `reachability`).
|
|
1477
|
+
* @example 2
|
|
1478
|
+
*/
|
|
1479
|
+
alState: 0 | 1 | 2 | 3 | 4 | 8;
|
|
1480
|
+
/**
|
|
1481
|
+
* True when the AL Status error indicator bit (bit 4) is set
|
|
1482
|
+
* @example false
|
|
1483
|
+
*/
|
|
1484
|
+
error: boolean;
|
|
1485
|
+
/**
|
|
1486
|
+
* AL Status Code register (ETG.1000.6 §6.4.1). Non-zero when error is true; identifies the error cause (e.g. 0x0014 = No valid firmware).
|
|
1487
|
+
* @example 0
|
|
1488
|
+
*/
|
|
1489
|
+
alStatusCode: number;
|
|
1490
|
+
/**
|
|
1491
|
+
* Whether the device answers at the station address the master gave it. `addressLost`: nothing answers at that address, but a device answers at its wire position. A reset, such as a power cycle, clears the address. Run `POST /api/scan` to command it again. `notAnswering`: nothing answers at that address or at its wire position. Check the cabling and the power. If devices were removed from the chain, run a scan. The wire position is checked by position only, so after a change to the chain the device that answers there can be a different one. When the value is not `answering`, the state of the device is unknown, and `alStatus`, `alState` and `alStatusCode` are 0.
|
|
1492
|
+
* @example "answering"
|
|
1493
|
+
*/
|
|
1494
|
+
reachability: "answering" | "addressLost" | "notAnswering";
|
|
1495
|
+
/**
|
|
1496
|
+
* True when this device reached the requested target state (error clear and alState equal to the requested state).
|
|
1497
|
+
* @example true
|
|
1498
|
+
*/
|
|
1499
|
+
reached: boolean;
|
|
1500
|
+
}[];
|
|
1501
|
+
}, void | {
|
|
1502
|
+
/** Why the driver refuses state changes */
|
|
1503
|
+
error: string;
|
|
1504
|
+
} | {
|
|
1505
|
+
/**
|
|
1506
|
+
* Human-readable error message from the driver
|
|
1507
|
+
* @example "FPRD slave 1: wkc=0"
|
|
1508
|
+
*/
|
|
1509
|
+
error: string;
|
|
1510
|
+
}>>;
|
|
1511
|
+
/**
|
|
1512
|
+
* No description
|
|
1513
|
+
*
|
|
1514
|
+
* @name GetDevices
|
|
1515
|
+
* @summary List all fieldbus devices
|
|
1516
|
+
* @request GET:/api/devices
|
|
1517
|
+
*/
|
|
1518
|
+
getDevices: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1519
|
+
/**
|
|
1520
|
+
* 1-based position on the fieldbus
|
|
1521
|
+
* @example 1
|
|
1522
|
+
*/
|
|
1523
|
+
slavePosition: number;
|
|
1524
|
+
/**
|
|
1525
|
+
* Human-readable device name from SII EEPROM. For SOMANET drives this is the generic group name "SOMANET"; use productName to distinguish products.
|
|
1526
|
+
* @example "SOMANET"
|
|
1527
|
+
*/
|
|
1528
|
+
name: string;
|
|
1529
|
+
/**
|
|
1530
|
+
* Canonical product name, independent of the SII EEPROM. For a recognised SOMANET product this distinguishes the product (e.g. "SOMANET Circulo"); otherwise it falls back to name.
|
|
1531
|
+
* @example "SOMANET Node"
|
|
1532
|
+
*/
|
|
1533
|
+
productName: string;
|
|
1534
|
+
/**
|
|
1535
|
+
* Vendor ID from EEPROM
|
|
1536
|
+
* @format int64
|
|
1537
|
+
* @example 131073
|
|
1538
|
+
*/
|
|
1539
|
+
vendorId: number;
|
|
1540
|
+
/**
|
|
1541
|
+
* Product code from EEPROM
|
|
1542
|
+
* @format int64
|
|
1543
|
+
* @example 5570560
|
|
1544
|
+
*/
|
|
1545
|
+
productCode: number;
|
|
1546
|
+
/**
|
|
1547
|
+
* Revision number from EEPROM
|
|
1548
|
+
* @format int64
|
|
1549
|
+
* @example 1
|
|
1550
|
+
*/
|
|
1551
|
+
revisionNumber: number;
|
|
1552
|
+
/**
|
|
1553
|
+
* Serial number from EEPROM
|
|
1554
|
+
* @format int64
|
|
1555
|
+
* @example 12345
|
|
1556
|
+
*/
|
|
1557
|
+
serialNumber: number;
|
|
1558
|
+
/**
|
|
1559
|
+
* Whether the device implements the CiA402 drive profile (both controlword 0x6040 and statusword 0x6041 present in its object dictionary). Gates the CiA402 motion-control endpoints under /api/devices/{slavePosition}/cia402.
|
|
1560
|
+
* @example true
|
|
1561
|
+
*/
|
|
1562
|
+
isCia402: boolean;
|
|
1563
|
+
/**
|
|
1564
|
+
* Whether the device is a SOMANET device, which runs SOMANET firmware. The server decides this from the vendor ID: Synapticon (0x22D2) or Sensodrive (0x063A). Gates the SOMANET features, such as the SOMANET files and the SOMANET procedures.
|
|
1565
|
+
* @example true
|
|
1566
|
+
*/
|
|
1567
|
+
isSomanet: boolean;
|
|
1568
|
+
/**
|
|
1569
|
+
* Whether an object-dictionary read for this device has failed since it was scanned. The automatic read on reaching a mailbox-active state is attempted once, so a device flagged here keeps an empty parameter list until `POST /api/devices/{slavePosition}/parameters/init` is called; that clears the flag on success.
|
|
1570
|
+
* @example false
|
|
1571
|
+
*/
|
|
1572
|
+
parametersUnavailable: boolean;
|
|
1573
|
+
/**
|
|
1574
|
+
* The low byte of ESC register 0x0000, which names the slave controller family: 0x85 is a netX (Integro), 0xC0 the controller of a Circulo, 0x90 a TI PRU-ICSS (Jasper). Null when the register could not be read at the scan, and over SPoE.
|
|
1575
|
+
* @format int32
|
|
1576
|
+
* @example 192
|
|
1577
|
+
*/
|
|
1578
|
+
escType?: number | null;
|
|
1579
|
+
/**
|
|
1580
|
+
* Whether Motion Master writes each mailbox request to this device once and never sends it again. True for a Synapticon or Sensodrive device whose ESC type is not 0x85, because its EtherCAT stack locks its receive mailbox when it gets one request twice. False for a netX, which discards a repeat, and for every other vendor, where a write with no frame back is sent again.
|
|
1581
|
+
* @example true
|
|
1582
|
+
*/
|
|
1583
|
+
mailboxWriteOnce?: boolean;
|
|
1584
|
+
/**
|
|
1585
|
+
* Whether the device has an EtherCAT Slave Controller: SII, ESC registers, distributed clocks and the ESC diagnostics. False over SPoE, where those endpoints answer 409.
|
|
1586
|
+
* @example true
|
|
1587
|
+
*/
|
|
1588
|
+
supportsEsc?: boolean;
|
|
1589
|
+
/**
|
|
1590
|
+
* Whether the transport can blink the device's LEDs, which is what the `device-locate` procedure does. True over SPoE.
|
|
1591
|
+
* @example false
|
|
1592
|
+
*/
|
|
1593
|
+
supportsLocate?: boolean;
|
|
1594
|
+
}[], any>>;
|
|
1595
|
+
/**
|
|
1596
|
+
* @description Returns the whole-bus process image: the byte sizes of each direction, the expected and last working counters and overall health, the number of retained image generations (one per re-map since the last reset), and every mapped object resolved to its absolute bit offset. While an image is live `configured` is true and the layout describes it. When no image is published (no device is in SAFE-OP/OP) but at least one generation has been mapped, `configured` is false and the layout describes the most recent retained generation — the last-known mapping — so a bus that has dropped out of SAFE-OP/OP stays inspectable; `lastWkc` then holds the final exchange value and working-counter health does not apply. The object lists are empty only before any image has ever been mapped. Object `name` is populated only for devices whose object dictionary has been enumerated.
|
|
1597
|
+
*
|
|
1598
|
+
* @name GetProcessImage
|
|
1599
|
+
* @summary Inspect the published EtherCAT process image
|
|
1600
|
+
* @request GET:/api/process-image
|
|
1601
|
+
*/
|
|
1602
|
+
getProcessImage: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1603
|
+
/**
|
|
1604
|
+
* Whether an image is currently published for exchange
|
|
1605
|
+
* @example true
|
|
1606
|
+
*/
|
|
1607
|
+
configured: boolean;
|
|
1608
|
+
/**
|
|
1609
|
+
* Size of the output image (master→slave) in bytes
|
|
1610
|
+
* @example 12
|
|
1611
|
+
*/
|
|
1612
|
+
outputBytes: number;
|
|
1613
|
+
/**
|
|
1614
|
+
* Size of the input image (slave→master) in bytes
|
|
1615
|
+
* @example 16
|
|
1616
|
+
*/
|
|
1617
|
+
inputBytes: number;
|
|
1618
|
+
/**
|
|
1619
|
+
* Working counter expected from the devices currently exchanging. A device in SAFE-OP or OP counts 2 for mapped outputs and 1 for mapped inputs. A device below SAFE-OP, or with the AL error flag set, counts 0.
|
|
1620
|
+
* @example 3
|
|
1621
|
+
*/
|
|
1622
|
+
expectedWkc: number;
|
|
1623
|
+
/**
|
|
1624
|
+
* Working counter from the most recent exchange (0 before any)
|
|
1625
|
+
* @example 3
|
|
1626
|
+
*/
|
|
1627
|
+
lastWkc: number;
|
|
1628
|
+
/**
|
|
1629
|
+
* Whether the last working counter meets the expected value
|
|
1630
|
+
* @example true
|
|
1631
|
+
*/
|
|
1632
|
+
healthy: boolean;
|
|
1633
|
+
/**
|
|
1634
|
+
* Cycles that answered with a working counter below the value expected at the time, counted since `POST /api/init` and cleared only by `POST /api/reset`. `healthy` is a sample of the most recent cycle and so cannot see a fault that has already cleared; this count can.
|
|
1635
|
+
*
|
|
1636
|
+
* It spans every re-map rather than resetting per image, because a re-map happens whenever a device is brought into or out of SAFE-OP/OP — which is exactly when someone is chasing a fault. `generations` says how many images the count spans. Cycles missed while a device was being deliberately commanded out of an exchange state are not counted: the expectation is lowered before the transition is commanded.
|
|
1637
|
+
* @format int64
|
|
1638
|
+
* @example 0
|
|
1639
|
+
*/
|
|
1640
|
+
shortWkcCycles: number;
|
|
1641
|
+
/**
|
|
1642
|
+
* Input frames the driver dropped since the process data was configured, summed over all devices. Only a transport that buffers input frames can drop one: a SPoE drive returns its frames in batches, and the oldest are dropped when the real-time loop falls more than 30 cycles behind. Every other transport reports 0.
|
|
1643
|
+
* @format int64
|
|
1644
|
+
* @example 0
|
|
1645
|
+
*/
|
|
1646
|
+
droppedInputFrames: number;
|
|
1647
|
+
/**
|
|
1648
|
+
* Epoch microseconds of the first such cycle, 0 if there has been none
|
|
1649
|
+
* @format int64
|
|
1650
|
+
* @example 0
|
|
1651
|
+
*/
|
|
1652
|
+
firstShortWkcUs: number;
|
|
1653
|
+
/**
|
|
1654
|
+
* Epoch microseconds of the most recent such cycle, 0 if there has been none
|
|
1655
|
+
* @format int64
|
|
1656
|
+
* @example 0
|
|
1657
|
+
*/
|
|
1658
|
+
lastShortWkcUs: number;
|
|
1659
|
+
/**
|
|
1660
|
+
* Number of process images retained since the last reset
|
|
1661
|
+
* @example 1
|
|
1662
|
+
*/
|
|
1663
|
+
generations: number;
|
|
1664
|
+
/** Output-mapped objects (RxPDO), in image order */
|
|
1665
|
+
outputs: ProcessImageObject[];
|
|
1666
|
+
/** Input-mapped objects (TxPDO), in image order */
|
|
1667
|
+
inputs: ProcessImageObject[];
|
|
1668
|
+
}, any>>;
|
|
1669
|
+
/**
|
|
1670
|
+
* @description Returns a point-in-time snapshot of the RT cyclic loop: the configured period and target rate, the cumulative achieved rate since start, the executed- and skipped-cycle counters, per-cycle task-execution timing (last / worst / mean), and whether real-time scheduling was acquired. Skipped cycles accumulate whenever the loop cannot meet its period (common on non-RT hosts such as Windows userspace) — a steadily rising `skippedCycles`, or an `achievedHz` well below `targetHz`, means the configured period is too aggressive for the hardware. Poll this endpoint and diff `executedCycles`/`skippedCycles` against `timestampUs` to chart the instantaneous rate over time.
|
|
1671
|
+
*
|
|
1672
|
+
* @name GetGameLoop
|
|
1673
|
+
* @summary Inspect real-time game-loop health
|
|
1674
|
+
* @request GET:/api/game-loop
|
|
1675
|
+
*/
|
|
1676
|
+
getGameLoop: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<GameLoopHealth, any>>;
|
|
1677
|
+
/**
|
|
1678
|
+
* @description Retimes the running RT loop to a new cycle period, in microseconds. The change takes effect within one cycle and is transient — it is not written back to the config file, so a restart reverts to the configured `gameLoop.periodUs`. Intended for tuning on hosts that cannot sustain the configured rate: if `skippedCycles` climbs steadily (common on Windows userspace), raise the period (e.g. from 1000 to 2000 µs) until the loop meets its grid. Only the master cadence is retimed — the process-data recorder ring is not resized, and no drive-side watchdog is touched, so raising the period toward a drive's PDO/SM watchdog window can fault that drive. Applying a period starts a fresh health epoch: the cumulative counters (`executedCycles`, `skippedCycles`, the `achievedHz` average, and `maxExecNs`/`avgExecNs`) reset so the snapshot reflects only the new period — letting you see straight away whether the change improved the loop's health. Returns the updated health snapshot.
|
|
1679
|
+
*
|
|
1680
|
+
* @name SetGameLoopPeriod
|
|
1681
|
+
* @summary Change the real-time cycle period
|
|
1682
|
+
* @request PUT:/api/game-loop
|
|
1683
|
+
*/
|
|
1684
|
+
setGameLoopPeriod: (data: {
|
|
1685
|
+
/**
|
|
1686
|
+
* New cycle period in microseconds. Must be greater than 0.
|
|
1687
|
+
* @format int64
|
|
1688
|
+
* @min 1
|
|
1689
|
+
* @example 2000
|
|
1690
|
+
*/
|
|
1691
|
+
periodUs: number;
|
|
1692
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<GameLoopHealth, void>>;
|
|
1693
|
+
/**
|
|
1694
|
+
* @description Streams the same `.mmpd` serialisation as the POST variant (the recorder's current span, with the process image embedded as a header) directly in the response body instead of writing a file — for the client SDK / browser, which parses the bytes offline. Request with `Accept: application/octet-stream`. Same span semantics as the POST; works in any state.
|
|
1695
|
+
*
|
|
1696
|
+
* @name StreamProcessDataDump
|
|
1697
|
+
* @summary Stream the recorder ring as a binary .mmpd
|
|
1698
|
+
* @request GET:/api/process-data/dump
|
|
1699
|
+
*/
|
|
1700
|
+
streamProcessDataDump: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Blob, {
|
|
1701
|
+
/** Human-readable reason the dump could not be produced */
|
|
1702
|
+
error: string;
|
|
1703
|
+
}>>;
|
|
1704
|
+
/**
|
|
1705
|
+
* @description Serialises the process-data recorder's current span — every cycle from the oldest still in the ring up to the newest at the instant of the call — to a `.mmpd` file and returns its path. Each cycle's full raw input and output images, sequence, and epoch-nanosecond timestamp are written, with the process image (per-device identity and PDO object layout, including object names and data types where the object dictionary has been enumerated) embedded as a header, so the file decodes fully offline with no running Motion Master and no live bus. Works in any state: while devices are exchanging (SAFE-OP/OP) it captures tail→head at that moment and ignores cycles recorded afterwards; after the bus has left the exchange states it uses the most recent retained image layout. The file is written under the configured `recorder.dumpDir`, created if absent; by default that is a `dumps` subdirectory of the user-cache root, so the written file is also reachable through the `/api/user-cache` endpoints — list it, download it, or delete it there. Only the path is returned here. (Setting an explicit `recorder.dumpDir` outside the cache root opts out of that; the file is then only reachable from a shell on the server.)
|
|
1706
|
+
*
|
|
1707
|
+
* @name DumpProcessData
|
|
1708
|
+
* @summary Dump the recorder ring to a binary .mmpd file
|
|
1709
|
+
* @request POST:/api/process-data/dump
|
|
1710
|
+
*/
|
|
1711
|
+
dumpProcessData: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1712
|
+
/**
|
|
1713
|
+
* Absolute path of the written .mmpd file
|
|
1714
|
+
* @example "/tmp/motion-master/dump-20260610T141530Z-300123.mmpd"
|
|
1715
|
+
*/
|
|
1716
|
+
path: string;
|
|
1717
|
+
}, {
|
|
1718
|
+
/**
|
|
1719
|
+
* Human-readable reason the dump could not be produced
|
|
1720
|
+
* @example "the recorder is empty — no cycles have been recorded yet"
|
|
1721
|
+
*/
|
|
1722
|
+
error: string;
|
|
1723
|
+
}>>;
|
|
1724
|
+
/**
|
|
1725
|
+
* @description Stages many output (RxPDO) objects at once — the "send all" action of the Process Data page. Each value is converted to the object's declared data type and, when the object is output-mapped and its device is exchanging (SAFE-OP/OP), written into the output image so it is sent on the next real-time cycle and re-sent every cycle thereafter (set-once, sent-continuously). The batch is best-effort atomic: values are staged sequentially, so a batch can straddle two consecutive ~1 ms cycles. The request never fails as a whole — each object gets its own result, so the client can flag any object that was not cyclically staged (unknown device, a value the data type cannot hold, object not output-mapped, or bus not exchanging; in the last two cases the value is still written via SDO/cache, just not cyclically driven). A value the data type cannot hold is refused in its own result and nothing is written for it, by the same rule as `writeParameter`.
|
|
1726
|
+
*
|
|
1727
|
+
* @name StageProcessDataOutputs
|
|
1728
|
+
* @summary Stage a batch of output values into the process image
|
|
1729
|
+
* @request POST:/api/process-data/outputs
|
|
1730
|
+
*/
|
|
1731
|
+
stageProcessDataOutputs: (data: any[][], params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1732
|
+
results: OutputStageResult[];
|
|
1733
|
+
}, {
|
|
1734
|
+
error: string;
|
|
1735
|
+
}>>;
|
|
1736
|
+
/**
|
|
1737
|
+
* @description Returns the static ESC configuration the master programmed into every slave during the last scan: station/alias addresses, mapped process-data sizes, the mailbox transport windows, the distributed-clock setup, and the configured Sync Managers and FMMUs. Read from cached state with no bus I/O and valid once the bus has been scanned. The list is empty before any scan, or when the active transport has no ESC (e.g. SPoE). Numeric fields (SM/FMMU type, mailbox protocol bits, SM flags) are raw register values; the client decodes them. `deviceName` is empty when no known device occupies the slave.
|
|
1738
|
+
*
|
|
1739
|
+
* @name GetBusConfig
|
|
1740
|
+
* @summary Inspect each slave's static EtherCAT Slave Controller configuration
|
|
1741
|
+
* @request GET:/api/bus-config
|
|
1742
|
+
*/
|
|
1743
|
+
getBusConfig: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<SlaveConfig[], any>>;
|
|
1744
|
+
/**
|
|
1745
|
+
* @description Returns the bus as an ENI document, the vendor-neutral configuration a third-party master (acontis EC-Master, TwinCAT, CODESYS) replays to bring the same bus up. Where an ESI file describes one device family, an ENI describes one assembled network, and it is imperative rather than declarative: every configuration step is an EtherCAT datagram or a CoE download tagged with the AL-state transition it belongs to. The document carries each device's identity and addresses, its Sync Manager and FMMU register writes, its mailbox windows, its PDO assignment as CoE downloads, the AL-state walk with a read that holds the master until the device arrives, the cyclic frame, and the named process image. Conforms to ENI Schema 1.7 (ETG.2100). The bus must be configured. FMMUs and logical addresses come into being at the SAFE-OP transition, so a bus in PRE-OP has no mapping to describe and the call returns 409. **This drives the bus.** Each device's SII is read for its port layout and bootstrap mailbox, and its PDO assignment is read over CoE, so the call costs one EEPROM read and a short burst of SDO uploads per device. It is an export action, not an accessor. Distributed clocks are left out, so the generated configuration runs in free-run — which is how Motion Master runs the bus itself. The `DC` element needs an `AssignActivate` word, and a SOMANET drive does not carry the SII category that holds one. `X-Eni-Warnings` counts the parts that were asked for and not answered; each is also logged. A warning costs one optional element, never the document: a device whose SII will not read keeps every init command.
|
|
1746
|
+
*
|
|
1747
|
+
* @name ExportEni
|
|
1748
|
+
* @summary Export the bus as an EtherCAT Network Information (ENI) file
|
|
1749
|
+
* @request GET:/api/eni
|
|
1750
|
+
*/
|
|
1751
|
+
exportEni: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<File, {
|
|
1752
|
+
/** Human-readable reason the export could not be produced */
|
|
1753
|
+
error: string;
|
|
1754
|
+
} | {
|
|
1755
|
+
/** The field that could not be written */
|
|
1756
|
+
error: string;
|
|
1757
|
+
} | {
|
|
1758
|
+
error: string;
|
|
1759
|
+
}>>;
|
|
1760
|
+
/**
|
|
1761
|
+
* @description Returns every registered monitoring as a resource — its configuration plus, per parameter, how its value is sourced, and the current buffer fill.
|
|
1762
|
+
*
|
|
1763
|
+
* @name ListMonitorings
|
|
1764
|
+
* @summary List all monitorings
|
|
1765
|
+
* @request GET:/api/monitorings
|
|
1766
|
+
*/
|
|
1767
|
+
listMonitorings: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Monitoring[], any>>;
|
|
1768
|
+
/**
|
|
1769
|
+
* @description Registers a monitoring and starts sampling it off the real-time thread. Each parameter is classified once against the published process image: PDO-mapped objects are decoded from the live image; the rest are polled over SDO in the background. Create monitorings after the bus is operational so PDO objects are recognised as PDO. Monitoring is live-only — a parameter samples `null` while its owning device is not exchanging (SAFE-OP/OP).
|
|
1770
|
+
*
|
|
1771
|
+
* @name CreateMonitoring
|
|
1772
|
+
* @summary Create a monitoring
|
|
1773
|
+
* @request POST:/api/monitorings
|
|
1774
|
+
*/
|
|
1775
|
+
createMonitoring: (data: {
|
|
1776
|
+
/**
|
|
1777
|
+
* URL-safe unique id; also the WebSocket topic.
|
|
1778
|
+
* @pattern ^[A-Za-z0-9._-]{1,64}$
|
|
1779
|
+
* @example "left-leg"
|
|
1780
|
+
*/
|
|
1781
|
+
topic: string;
|
|
1782
|
+
/**
|
|
1783
|
+
* Optional human-readable label.
|
|
1784
|
+
* @example "Left Leg"
|
|
1785
|
+
*/
|
|
1786
|
+
name?: string;
|
|
1787
|
+
/**
|
|
1788
|
+
* Flush cadence in milliseconds (5–2000). Not a sample rate: every recorded cycle since the last flush is delivered, so a longer interval yields a larger batch rather than fewer samples. 16 ms (~one batch per 60 Hz display frame) is a good default for live plotting.
|
|
1789
|
+
* @min 5
|
|
1790
|
+
* @max 2000
|
|
1791
|
+
* @example 16
|
|
1792
|
+
*/
|
|
1793
|
+
interval: number;
|
|
1794
|
+
/**
|
|
1795
|
+
* Objects to sample, each as `[devicePosition, index, subindex]`.
|
|
1796
|
+
* @minItems 1
|
|
1797
|
+
* @example [[1,8240,1],[1,24676,0]]
|
|
1798
|
+
*/
|
|
1799
|
+
parameters: number[][];
|
|
1800
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Monitoring, {
|
|
1801
|
+
error: string;
|
|
1802
|
+
}>>;
|
|
1803
|
+
/**
|
|
1804
|
+
* No description
|
|
1805
|
+
*
|
|
1806
|
+
* @name GetMonitoring
|
|
1807
|
+
* @summary Get a monitoring
|
|
1808
|
+
* @request GET:/api/monitorings/{topic}
|
|
1809
|
+
*/
|
|
1810
|
+
getMonitoring: (topic: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Monitoring, void>>;
|
|
1811
|
+
/**
|
|
1812
|
+
* @description Stops sampling and releases the monitoring's SDO parameters from the shared refresher — an object no remaining monitoring needs stops being polled.
|
|
1813
|
+
*
|
|
1814
|
+
* @name DeleteMonitoring
|
|
1815
|
+
* @summary Delete a monitoring
|
|
1816
|
+
* @request DELETE:/api/monitorings/{topic}
|
|
1817
|
+
*/
|
|
1818
|
+
deleteMonitoring: (topic: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<void, void>>;
|
|
1819
|
+
/**
|
|
1820
|
+
* @description Returns one entry per cached parameter-definition file on disk, keyed by device identity (vendor, product, revision). The cache stores only the object-dictionary *definitions* (not live values), so a scan of previously-seen hardware can skip the slow SDO enumeration. Independent of the bus — works whether or not a driver is initialised.
|
|
1821
|
+
*
|
|
1822
|
+
* @name ListParameterCacheEntries
|
|
1823
|
+
* @summary List on-disk parameter caches
|
|
1824
|
+
* @request GET:/api/parameter-cache
|
|
1825
|
+
*/
|
|
1826
|
+
listParameterCacheEntries: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<ParameterCacheEntry[], any>>;
|
|
1827
|
+
/**
|
|
1828
|
+
* @description Returns the raw JSON cache file for the given id, verbatim, so it can be saved or inspected offline.
|
|
1829
|
+
*
|
|
1830
|
+
* @name GetParameterCache
|
|
1831
|
+
* @summary Download a parameter-cache file
|
|
1832
|
+
* @request GET:/api/parameter-cache/{id}
|
|
1833
|
+
*/
|
|
1834
|
+
getParameterCache: (id: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<object, void>>;
|
|
1835
|
+
/**
|
|
1836
|
+
* @description Removes one cached file from disk. The next scan of that hardware re-enumerates it. Useful when a vendor reused a revision across an object-dictionary change.
|
|
1837
|
+
*
|
|
1838
|
+
* @name DeleteParameterCache
|
|
1839
|
+
* @summary Delete a parameter-cache file
|
|
1840
|
+
* @request DELETE:/api/parameter-cache/{id}
|
|
1841
|
+
*/
|
|
1842
|
+
deleteParameterCache: (id: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<void, void>>;
|
|
1843
|
+
/**
|
|
1844
|
+
* @description Returns every file in Motion Master's per-user cache directory, flattened: one entry per file with its full path relative to the cache root, whatever the nesting. Directories have no entries of their own. Independent of the bus — works whether or not a driver is initialised. The cache is a plain file store for data that should outlive a restart. The store itself neither validates nor interprets an upload — `PUT` accepts any bytes at any valid path, and putting a file here does not, on its own, make Motion Master do anything with it; the client chooses the paths. That is separate from whether a *feature* reads a given file, and several do: `parameters/` (the on-disk object-dictionary cache) and `dumps/` (`.mmpd` recorder dumps) are written and consumed by those features, with more to follow. Their files appear in this listing alongside everything else, so a client must not assume every entry was uploaded through this API, nor that deleting one is inconsequential.
|
|
1845
|
+
*
|
|
1846
|
+
* @name ListUserCacheFiles
|
|
1847
|
+
* @summary List the files in the user cache
|
|
1848
|
+
* @request GET:/api/user-cache
|
|
1849
|
+
*/
|
|
1850
|
+
listUserCacheFiles: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<UserCacheListing, void>>;
|
|
1851
|
+
/**
|
|
1852
|
+
* @description Returns the file verbatim, always as `application/octet-stream` and always with `Content-Disposition: attachment`, `X-Content-Type-Options: nosniff` and a `default-src 'none'; sandbox` CSP. The bytes are whatever a user uploaded, served from the API's own origin, so a browser must never *render* them — a rendered upload would be stored XSS against the origin that controls the drives, which CORS cannot help with. No extension is trusted to name a content type, and the attachment carries no `filename` (the path is user-controlled and must not reach a response header). Clients read the bytes and name the saved file themselves.
|
|
1853
|
+
*
|
|
1854
|
+
* @name GetUserCacheFile
|
|
1855
|
+
* @summary Download a user-cache file
|
|
1856
|
+
* @request GET:/api/user-cache/{path}
|
|
1857
|
+
*/
|
|
1858
|
+
getUserCacheFile: (path: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Blob, void>>;
|
|
1859
|
+
/**
|
|
1860
|
+
* @description Writes the request body to the given path, creating parent directories as needed and replacing any existing file. The write is atomic — a concurrent reader sees either the old contents or the new one, never a partial file. The body is taken as raw bytes whatever its content type.
|
|
1861
|
+
*
|
|
1862
|
+
* @name PutUserCacheFile
|
|
1863
|
+
* @summary Upload a user-cache file
|
|
1864
|
+
* @request PUT:/api/user-cache/{path}
|
|
1865
|
+
*/
|
|
1866
|
+
putUserCacheFile: (path: string, data: File, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
|
|
1867
|
+
/**
|
|
1868
|
+
* The path written, relative to the cache root.
|
|
1869
|
+
* @example "configs/machine-a.json"
|
|
1870
|
+
*/
|
|
1871
|
+
path: string;
|
|
1872
|
+
/**
|
|
1873
|
+
* Bytes written.
|
|
1874
|
+
* @example 20480
|
|
1875
|
+
*/
|
|
1876
|
+
size: number;
|
|
1877
|
+
}, void>>;
|
|
1878
|
+
/**
|
|
1879
|
+
* @description Removes a file, or a directory and everything under it. Directories left empty between the removed path and the cache root are pruned, so no husks remain. A file the running server holds open is refused — see `deletable` on `UserCacheFile`.
|
|
1880
|
+
*
|
|
1881
|
+
* @name DeleteUserCacheFile
|
|
1882
|
+
* @summary Delete a user-cache file or directory
|
|
1883
|
+
* @request DELETE:/api/user-cache/{path}
|
|
1884
|
+
*/
|
|
1885
|
+
deleteUserCacheFile: (path: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<void, void>>;
|
|
1886
|
+
}
|