@synapticon/motion-master-client 6.0.0-alpha.61 → 6.0.0-alpha.63

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.
@@ -1,4 +1,4 @@
1
- import { AlStatusCode, Cia402Status, DcSyncStatus, DeviceDiagnostics, DeviceParameter, EscRegister, FoeErrorCode, GameLoopHealth, MailboxErrorCode, Monitoring, ObjectDataTypeInfo, OutputStageResult, ParameterCacheEntry, PdoMapping, PdoMappingRequest, ProcessDataWatchdog, ProcessImageObject, SdoAbortCode, SlaveConfig, SlaveInformationInterface } from "./data-contracts.js";
1
+ import { AlStatusCode, Cia402Status, DcSyncStatus, DeviceDiagnostics, DeviceParameter, EscRegister, EsiParseResult, FoeErrorCode, GameLoopHealth, MailboxErrorCode, Monitoring, ObjectDataTypeInfo, OutputStageResult, ParameterCacheEntry, PdoMapping, PdoMappingRequest, ProcessDataWatchdog, ProcessImageObject, SdoAbortCode, SlaveConfig, SlaveInformationInterface, UserCacheListing } from "./data-contracts.js";
2
2
  import { HttpClient, RequestParams } from "./http-client.js";
3
3
  export declare class Api<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
4
4
  /**
@@ -827,6 +827,17 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
827
827
  * @request POST:/api/sii/parse
828
828
  */
829
829
  parseSii: (data: File, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<SlaveInformationInterface, void>>;
830
+ /**
831
+ * @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.
832
+ *
833
+ * @name ParseEsi
834
+ * @summary Parse an EtherCAT Slave Information (ESI) file
835
+ * @request POST:/api/esi/parse
836
+ */
837
+ parseEsi: (data: string, query?: {
838
+ /** 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. */
839
+ modules?: string;
840
+ }, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<EsiParseResult, void>>;
830
841
  /**
831
842
  * @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).
832
843
  *
@@ -1120,7 +1131,7 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
1120
1131
  error: string;
1121
1132
  }>>;
1122
1133
  /**
1123
- * @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` (default: a `motion-master` subdirectory of the OS temporary directory), created if absent. Motion Master binds 127.0.0.1, so the file is on the caller's own machine — only the path is returned (there is no download, list, or delete endpoint).
1134
+ * @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.)
1124
1135
  *
1125
1136
  * @name DumpProcessData
1126
1137
  * @summary Dump the recorder ring to a binary .mmpd file
@@ -1221,17 +1232,17 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
1221
1232
  /**
1222
1233
  * @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.
1223
1234
  *
1224
- * @name ListParameterCaches
1235
+ * @name ListParameterCacheEntries
1225
1236
  * @summary List on-disk parameter caches
1226
- * @request GET:/api/parameter-caches
1237
+ * @request GET:/api/parameter-cache
1227
1238
  */
1228
- listParameterCaches: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<ParameterCacheEntry[], any>>;
1239
+ listParameterCacheEntries: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<ParameterCacheEntry[], any>>;
1229
1240
  /**
1230
1241
  * @description Returns the raw JSON cache file for the given id, verbatim, so it can be saved or inspected offline.
1231
1242
  *
1232
1243
  * @name GetParameterCache
1233
1244
  * @summary Download a parameter-cache file
1234
- * @request GET:/api/parameter-caches/{id}
1245
+ * @request GET:/api/parameter-cache/{id}
1235
1246
  */
1236
1247
  getParameterCache: (id: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<object, void>>;
1237
1248
  /**
@@ -1239,7 +1250,50 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
1239
1250
  *
1240
1251
  * @name DeleteParameterCache
1241
1252
  * @summary Delete a parameter-cache file
1242
- * @request DELETE:/api/parameter-caches/{id}
1253
+ * @request DELETE:/api/parameter-cache/{id}
1243
1254
  */
1244
1255
  deleteParameterCache: (id: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<void, void>>;
1256
+ /**
1257
+ * @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.
1258
+ *
1259
+ * @name ListUserCacheFiles
1260
+ * @summary List the files in the user cache
1261
+ * @request GET:/api/user-cache
1262
+ */
1263
+ listUserCacheFiles: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<UserCacheListing, void>>;
1264
+ /**
1265
+ * @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.
1266
+ *
1267
+ * @name GetUserCacheFile
1268
+ * @summary Download a user-cache file
1269
+ * @request GET:/api/user-cache/{path}
1270
+ */
1271
+ getUserCacheFile: (path: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<Blob, void>>;
1272
+ /**
1273
+ * @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.
1274
+ *
1275
+ * @name PutUserCacheFile
1276
+ * @summary Upload a user-cache file
1277
+ * @request PUT:/api/user-cache/{path}
1278
+ */
1279
+ putUserCacheFile: (path: string, data: File, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<{
1280
+ /**
1281
+ * The path written, relative to the cache root.
1282
+ * @example "configs/machine-a.json"
1283
+ */
1284
+ path: string;
1285
+ /**
1286
+ * Bytes written.
1287
+ * @example 20480
1288
+ */
1289
+ size: number;
1290
+ }, void>>;
1291
+ /**
1292
+ * @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.
1293
+ *
1294
+ * @name DeleteUserCacheFile
1295
+ * @summary Delete a user-cache file or directory
1296
+ * @request DELETE:/api/user-cache/{path}
1297
+ */
1298
+ deleteUserCacheFile: (path: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<void, void>>;
1245
1299
  }
@@ -577,6 +577,21 @@ export class Api extends HttpClient {
577
577
  format: "json",
578
578
  ...params,
579
579
  });
580
+ /**
581
+ * @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.
582
+ *
583
+ * @name ParseEsi
584
+ * @summary Parse an EtherCAT Slave Information (ESI) file
585
+ * @request POST:/api/esi/parse
586
+ */
587
+ parseEsi = (data, query, params = {}) => this.request({
588
+ path: `/api/esi/parse`,
589
+ method: "POST",
590
+ query: query,
591
+ body: data,
592
+ format: "json",
593
+ ...params,
594
+ });
580
595
  /**
581
596
  * @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).
582
597
  *
@@ -701,7 +716,7 @@ export class Api extends HttpClient {
701
716
  ...params,
702
717
  });
703
718
  /**
704
- * @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` (default: a `motion-master` subdirectory of the OS temporary directory), created if absent. Motion Master binds 127.0.0.1, so the file is on the caller's own machine — only the path is returned (there is no download, list, or delete endpoint).
719
+ * @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.)
705
720
  *
706
721
  * @name DumpProcessData
707
722
  * @summary Dump the recorder ring to a binary .mmpd file
@@ -797,12 +812,12 @@ export class Api extends HttpClient {
797
812
  /**
798
813
  * @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.
799
814
  *
800
- * @name ListParameterCaches
815
+ * @name ListParameterCacheEntries
801
816
  * @summary List on-disk parameter caches
802
- * @request GET:/api/parameter-caches
817
+ * @request GET:/api/parameter-cache
803
818
  */
804
- listParameterCaches = (params = {}) => this.request({
805
- path: `/api/parameter-caches`,
819
+ listParameterCacheEntries = (params = {}) => this.request({
820
+ path: `/api/parameter-cache`,
806
821
  method: "GET",
807
822
  format: "json",
808
823
  ...params,
@@ -812,10 +827,10 @@ export class Api extends HttpClient {
812
827
  *
813
828
  * @name GetParameterCache
814
829
  * @summary Download a parameter-cache file
815
- * @request GET:/api/parameter-caches/{id}
830
+ * @request GET:/api/parameter-cache/{id}
816
831
  */
817
832
  getParameterCache = (id, params = {}) => this.request({
818
- path: `/api/parameter-caches/${id}`,
833
+ path: `/api/parameter-cache/${id}`,
819
834
  method: "GET",
820
835
  format: "json",
821
836
  ...params,
@@ -825,10 +840,61 @@ export class Api extends HttpClient {
825
840
  *
826
841
  * @name DeleteParameterCache
827
842
  * @summary Delete a parameter-cache file
828
- * @request DELETE:/api/parameter-caches/{id}
843
+ * @request DELETE:/api/parameter-cache/{id}
829
844
  */
830
845
  deleteParameterCache = (id, params = {}) => this.request({
831
- path: `/api/parameter-caches/${id}`,
846
+ path: `/api/parameter-cache/${id}`,
847
+ method: "DELETE",
848
+ ...params,
849
+ });
850
+ /**
851
+ * @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.
852
+ *
853
+ * @name ListUserCacheFiles
854
+ * @summary List the files in the user cache
855
+ * @request GET:/api/user-cache
856
+ */
857
+ listUserCacheFiles = (params = {}) => this.request({
858
+ path: `/api/user-cache`,
859
+ method: "GET",
860
+ format: "json",
861
+ ...params,
862
+ });
863
+ /**
864
+ * @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.
865
+ *
866
+ * @name GetUserCacheFile
867
+ * @summary Download a user-cache file
868
+ * @request GET:/api/user-cache/{path}
869
+ */
870
+ getUserCacheFile = (path, params = {}) => this.request({
871
+ path: `/api/user-cache/${path}`,
872
+ method: "GET",
873
+ ...params,
874
+ });
875
+ /**
876
+ * @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.
877
+ *
878
+ * @name PutUserCacheFile
879
+ * @summary Upload a user-cache file
880
+ * @request PUT:/api/user-cache/{path}
881
+ */
882
+ putUserCacheFile = (path, data, params = {}) => this.request({
883
+ path: `/api/user-cache/${path}`,
884
+ method: "PUT",
885
+ body: data,
886
+ format: "json",
887
+ ...params,
888
+ });
889
+ /**
890
+ * @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.
891
+ *
892
+ * @name DeleteUserCacheFile
893
+ * @summary Delete a user-cache file or directory
894
+ * @request DELETE:/api/user-cache/{path}
895
+ */
896
+ deleteUserCacheFile = (path, params = {}) => this.request({
897
+ path: `/api/user-cache/${path}`,
832
898
  method: "DELETE",
833
899
  ...params,
834
900
  });
@@ -89,6 +89,16 @@ export interface GameLoopHealth {
89
89
  * @example false
90
90
  */
91
91
  memLocked: boolean;
92
+ /**
93
+ * Core the real-time thread was configured to pin to (gameLoop.cpuAffinity), or -1 when unpinned. Pointing this at an isolcpus core is what gives the RT thread a core to itself; only that thread is pinned, so the HTTP, WebSocket and monitoring threads stay on the remaining cores.
94
+ * @example -1
95
+ */
96
+ cpuAffinity: number;
97
+ /**
98
+ * Whether the pin took. Always false when cpuAffinity is -1 (nothing was asked for); false while cpuAffinity is >= 0 means the request failed and the thread is running unpinned.
99
+ * @example false
100
+ */
101
+ cpuPinned: boolean;
92
102
  /**
93
103
  * Server wall-clock timestamp (epoch microseconds) when sampled
94
104
  * @format int64
@@ -96,6 +106,33 @@ export interface GameLoopHealth {
96
106
  */
97
107
  timestampUs: number;
98
108
  }
109
+ /** The user cache's location on disk plus every file it holds. */
110
+ export interface UserCacheListing {
111
+ /**
112
+ * Absolute path of the cache directory on the server's filesystem. Platform-dependent (and overridable via the `userCache.directory` config key), so it is reported rather than assumed — show it to the user so they can find the files themselves.
113
+ * @example "/home/user/.cache/motion-master"
114
+ */
115
+ root: string;
116
+ files: UserCacheFile[];
117
+ }
118
+ /** One file in the user cache. */
119
+ export interface UserCacheFile {
120
+ /**
121
+ * Path relative to the cache root, always with `/` separators. Use it verbatim in the download/upload/delete endpoints.
122
+ * @example "configs/machine-a.json"
123
+ */
124
+ path: string;
125
+ /**
126
+ * File size in bytes.
127
+ * @example 20480
128
+ */
129
+ size: number;
130
+ /**
131
+ * Last-write time, in milliseconds since the Unix epoch.
132
+ * @example 1783968687738
133
+ */
134
+ modifiedMs: number;
135
+ }
99
136
  /** Summary of one on-disk parameter-cache file (its identity, size, and count). */
100
137
  export interface ParameterCacheEntry {
101
138
  /**
@@ -929,3 +966,129 @@ export interface SiiPdo {
929
966
  flags?: number;
930
967
  }[];
931
968
  }
969
+ /** One addressable `(index, subindex)` of a device's object dictionary, assembled from the ESI. `defaultData`/`minData`/`maxData` are **raw little-endian bytes** as uppercase hexBinary, the same spelling the ESI itself uses — the first byte is the least significant, so `92010200` is `0x00020192`. Decode them with `dataType`; a byte-wise comparison of `minData` against `maxData` is wrong when `isSigned`. */
970
+ export interface EsiEntry {
971
+ /** Effective CoE index */
972
+ index: number;
973
+ subindex: number;
974
+ /** Index as written in the source dictionary; omitted when unrelocated */
975
+ rawIndex?: number;
976
+ /** The parent object's name — identical across all its subindices */
977
+ objectName: string;
978
+ /** This subindex's own name */
979
+ entryName: string;
980
+ /** The ESI's display-name override, else `entryName` */
981
+ displayName: string;
982
+ objectCode: "VAR" | "ARRAY" | "RECORD";
983
+ /** The CoE object code (ETG.1000.6 §5) — 7, 8 or 9 */
984
+ objectCodeValue?: number;
985
+ /** Highest subindex; omitted for a VAR */
986
+ numberOfEntries?: number;
987
+ /**
988
+ * ESI/IEC 61131-3 type name, e.g. `UDINT`, `STRING(50)`
989
+ * @example "UDINT"
990
+ */
991
+ dataTypeName: string;
992
+ /**
993
+ * ETG.1020 code, matching `DeviceParameter.dataType`; 0 if unresolved
994
+ * @example 7
995
+ */
996
+ dataType: number;
997
+ isSigned: boolean;
998
+ bitSize: number;
999
+ /** Offset within the object's complete-access image */
1000
+ bitOffset: number;
1001
+ /** Uppercase hexBinary */
1002
+ defaultData?: string;
1003
+ minData?: string;
1004
+ maxData?: string;
1005
+ /** Packed ETG.1004 notation value */
1006
+ unit?: number;
1007
+ /** @example "mV" */
1008
+ unitSymbol?: string;
1009
+ access: {
1010
+ mode: "ro" | "rw" | "wo";
1011
+ readRestrictions?: "PreOP" | "PreOP_SafeOP" | "PreOP_OP" | "SafeOP" | "SafeOP_OP" | "OP";
1012
+ writeRestrictions?: "PreOP" | "PreOP_SafeOP" | "PreOP_OP" | "SafeOP" | "SafeOP_OP" | "OP";
1013
+ };
1014
+ /** Mandatory, optional or conditional */
1015
+ category: "m" | "o" | "c";
1016
+ /** Empty when not mappable; `t` TxPDO, `r` RxPDO */
1017
+ pdoMapping: "" | "t" | "r" | "tr";
1018
+ safetyMapping?: "si" | "so" | "sio" | "sp";
1019
+ sdoAccess: "SubIndexAccess" | "CompleteAccess";
1020
+ backup: boolean;
1021
+ setting: boolean;
1022
+ /** SoE IDN */
1023
+ attribute?: number;
1024
+ /** ETG.1000.6 ObjAccess bitfield synthesised from the flags — bits 0-2 read in PreOP/SafeOP/OP, 3-5 write, 6 RxPDO-mappable, 7 TxPDO-mappable, 8 backup, 9 setting. Matches `DeviceParameter.access`. */
1025
+ objAccess: number;
1026
+ /** This row's description (HTML), decoded from `properties`. On subindex 0 it is the object's; on a RECORD member it is that member's; an ARRAY element has none. */
1027
+ description?: string;
1028
+ /** Enum labels, from `<EnumInfo>` and/or an `options` property */
1029
+ options?: {
1030
+ label: string;
1031
+ value: number;
1032
+ }[];
1033
+ /** Raw `<Property>` annotations as written, for whatever this row describes. This is the ESI's generic extension mechanism; `description` and `options` above are conveniences decoded from the two conventional names, so a vendor using other names still has its data here. **Subindex 0 carries the object's own annotation** (stored once, not repeated onto every subindex); other rows carry only what that entry itself declares. */
1034
+ properties?: EsiProperties;
1035
+ /** Which dictionary this entry came from. The module's *name* is not repeated here — resolve `moduleIdent` against the top-level `modules` list. */
1036
+ source: {
1037
+ kind: "device" | "module";
1038
+ moduleIdent?: number;
1039
+ /** Zero-based slot number */
1040
+ slot?: number;
1041
+ /** Slot offset applied to `rawIndex` */
1042
+ indexOffset?: number;
1043
+ };
1044
+ }
1045
+ /** Raw `<Property>` annotations as written, for whatever this row describes. This is the ESI's generic extension mechanism; `description` and `options` above are conveniences decoded from the two conventional names, so a vendor using other names still has its data here. **Subindex 0 carries the object's own annotation** (stored once, not repeated onto every subindex); other rows carry only what that entry itself declares. */
1046
+ export type EsiProperties = {
1047
+ name: string;
1048
+ value: string;
1049
+ }[];
1050
+ export interface EsiDeviceSummary {
1051
+ /** Zero-based position in the file */
1052
+ ordinal: number;
1053
+ /** @example "SOMANET Node" */
1054
+ type: string;
1055
+ name: string;
1056
+ productCode?: number;
1057
+ revisionNo?: number;
1058
+ /** @example 402 */
1059
+ profileNo?: number;
1060
+ groupType: string;
1061
+ /** Objects in the device's own dictionary, before any module merge */
1062
+ objectCount: number;
1063
+ rxPdoCount?: number;
1064
+ txPdoCount?: number;
1065
+ /** Every `ModuleIdent` the device's slots reference, in slot order */
1066
+ moduleIdents: number[];
1067
+ /** The parsed `<Slots>` block */
1068
+ slots?: object;
1069
+ /** This device's flat, slot-merged object dictionary */
1070
+ entries?: EsiEntry[];
1071
+ /** Problems found while assembling *this device* — a value whose byte length disagrees with its declared width, an unresolvable type, a module collision. Distinct from the top-level `warnings`, which are about the document; a different `modules` selection would produce a different list here. */
1072
+ warnings?: string[];
1073
+ }
1074
+ /** A parsed ESI. Every device carries its own assembled `entries` table. */
1075
+ export interface EsiParseResult {
1076
+ /** The `EtherCATInfo/@Version` attribute */
1077
+ version?: string;
1078
+ vendor: {
1079
+ /** @example 8914 */
1080
+ id: number;
1081
+ name: string;
1082
+ url?: string;
1083
+ };
1084
+ devices: EsiDeviceSummary[];
1085
+ modules: {
1086
+ moduleIdent: number;
1087
+ /** @example "CiA402 Dictionary" */
1088
+ type: string;
1089
+ name: string;
1090
+ objectCount?: number;
1091
+ }[];
1092
+ /** Recoverable problems in the document itself — a skipped malformed object, an unparsable value. A file with warnings still parses. Per-device assembly problems are reported on the device instead. */
1093
+ warnings?: string[];
1094
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synapticon/motion-master-client",
3
- "version": "6.0.0-alpha.61",
3
+ "version": "6.0.0-alpha.63",
4
4
  "description": "Isomorphic TypeScript client for Motion Master: the generated HTTP API client, the WebSocket connection, and helpers.",
5
5
  "license": "MIT",
6
6
  "repository": {