@synapticon/motion-master-client 6.0.0-alpha.68 → 6.0.0-alpha.70
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/dist/api-error.d.ts +25 -0
- package/dist/api-error.js +52 -0
- package/dist/generated/Api.d.ts +56 -4
- package/dist/generated/Api.js +82 -0
- package/dist/generated/data-contracts.d.ts +207 -16
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place that knows how a failed request from the generated client is shaped.
|
|
3
|
+
*
|
|
4
|
+
* `swagger-typescript-api`'s client does not throw an `Error`. On a non-2xx it throws its own
|
|
5
|
+
* `HttpResponse` object, having parsed the response body into that object's `error` property — and
|
|
6
|
+
* Motion Master's own error body is `{ "error": "<message>" }`. So the message a user should see
|
|
7
|
+
* sits at `err.error.error`, two levels down, and reading one level yields the string
|
|
8
|
+
* `"[object Object]"`.
|
|
9
|
+
*
|
|
10
|
+
* That is not a shape any caller should have to know, which is the whole reason this lives here: the
|
|
11
|
+
* wrapping belongs to the generated client, the generated client belongs to this package, so the
|
|
12
|
+
* unwrapping belongs here too rather than being rediscovered in every page that catches a request.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* The human-readable reason a request failed.
|
|
16
|
+
*
|
|
17
|
+
* Tries, in order: the server's own message (`{ error }`, at either nesting level), the HTTP status,
|
|
18
|
+
* a thrown `Error`'s message, and finally `fallback`. The server message comes first because it is
|
|
19
|
+
* the only one that says anything specific — Motion Master's node layer writes these, and they name
|
|
20
|
+
* the object, the state, or the grammar that was wrong.
|
|
21
|
+
*
|
|
22
|
+
* @param err Whatever was caught.
|
|
23
|
+
* @param fallback Returned when nothing usable can be found.
|
|
24
|
+
*/
|
|
25
|
+
export declare function apiErrorMessage(err: unknown, fallback?: string): string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place that knows how a failed request from the generated client is shaped.
|
|
3
|
+
*
|
|
4
|
+
* `swagger-typescript-api`'s client does not throw an `Error`. On a non-2xx it throws its own
|
|
5
|
+
* `HttpResponse` object, having parsed the response body into that object's `error` property — and
|
|
6
|
+
* Motion Master's own error body is `{ "error": "<message>" }`. So the message a user should see
|
|
7
|
+
* sits at `err.error.error`, two levels down, and reading one level yields the string
|
|
8
|
+
* `"[object Object]"`.
|
|
9
|
+
*
|
|
10
|
+
* That is not a shape any caller should have to know, which is the whole reason this lives here: the
|
|
11
|
+
* wrapping belongs to the generated client, the generated client belongs to this package, so the
|
|
12
|
+
* unwrapping belongs here too rather than being rediscovered in every page that catches a request.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* The human-readable reason a request failed.
|
|
16
|
+
*
|
|
17
|
+
* Tries, in order: the server's own message (`{ error }`, at either nesting level), the HTTP status,
|
|
18
|
+
* a thrown `Error`'s message, and finally `fallback`. The server message comes first because it is
|
|
19
|
+
* the only one that says anything specific — Motion Master's node layer writes these, and they name
|
|
20
|
+
* the object, the state, or the grammar that was wrong.
|
|
21
|
+
*
|
|
22
|
+
* @param err Whatever was caught.
|
|
23
|
+
* @param fallback Returned when nothing usable can be found.
|
|
24
|
+
*/
|
|
25
|
+
export function apiErrorMessage(err, fallback = 'Unknown error') {
|
|
26
|
+
if (typeof err === 'object' && err !== null) {
|
|
27
|
+
const candidate = err;
|
|
28
|
+
// The generated client's HttpResponse: the parsed body sits in `error`.
|
|
29
|
+
if (typeof candidate.error === 'object' && candidate.error !== null) {
|
|
30
|
+
const body = candidate.error;
|
|
31
|
+
if (typeof body.error === 'string' && body.error !== '') {
|
|
32
|
+
return body.error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// A body handed over directly, or an already-unwrapped one.
|
|
36
|
+
if (typeof candidate.error === 'string' && candidate.error !== '') {
|
|
37
|
+
return candidate.error;
|
|
38
|
+
}
|
|
39
|
+
// No body to read — a network failure, or a response with no JSON. The status is what is left,
|
|
40
|
+
// and it is still more use than a generic sentence.
|
|
41
|
+
if (typeof candidate.status === 'number') {
|
|
42
|
+
const statusText = typeof candidate.statusText === 'string' && candidate.statusText !== ''
|
|
43
|
+
? ` ${candidate.statusText}`
|
|
44
|
+
: '';
|
|
45
|
+
return `HTTP ${candidate.status}${statusText}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (err instanceof Error && err.message !== '') {
|
|
49
|
+
return err.message;
|
|
50
|
+
}
|
|
51
|
+
return fallback;
|
|
52
|
+
}
|
package/dist/generated/Api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AlStatusCode, BrakeState, Cia402Status, DcSyncStatus, DeviceDiagnostics, DeviceFile, DeviceParameter, EscRegister, EsiParseResult, FirmwarePackageName, FoeErrorCode, GameLoopHealth, HrdRecording, MailboxErrorCode, Monitoring, ObjectDataTypeInfo, OutputStageResult, ParameterCacheEntry, PdoMapping, PdoMappingRequest, ProcedureListing, ProcedureRequest, ProcedureSnapshot, ProcessDataWatchdog, ProcessImageObject, SdoAbortCode, SlaveConfig, SlaveInformationInterface, UserCacheListing } from "./data-contracts.js";
|
|
1
|
+
import { AlStatusCode, BrakeState, Cia402Status, DcSyncStatus, DeviceDiagnostics, DeviceFile, DeviceParameter, EscRegister, EsiParseResult, FirmwareCompatibility, FirmwarePackageName, FoeErrorCode, GameLoopHealth, HardwareDescription, HrdRecording, IntegroVariant, IntegroVariantOption, MailboxErrorCode, Monitoring, ObjectDataTypeInfo, OutputStageResult, ParameterCacheEntry, PdoMapping, PdoMappingRequest, ProcedureListing, ProcedureRequest, ProcedureSnapshot, 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
|
/**
|
|
@@ -798,9 +798,37 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
|
|
|
798
798
|
* @summary List the files stored on a device
|
|
799
799
|
* @request GET:/api/devices/{slavePosition}/files
|
|
800
800
|
*/
|
|
801
|
-
listDeviceFiles: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<
|
|
802
|
-
|
|
803
|
-
|
|
801
|
+
listDeviceFiles: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<DeviceFile[], void>>;
|
|
802
|
+
/**
|
|
803
|
+
* @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.
|
|
804
|
+
*
|
|
805
|
+
* @name GetDeviceHardwareDescription
|
|
806
|
+
* @summary Read what a device says it is
|
|
807
|
+
* @request GET:/api/devices/{slavePosition}/hardware-description
|
|
808
|
+
*/
|
|
809
|
+
getDeviceHardwareDescription: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<HardwareDescription, void>>;
|
|
810
|
+
/**
|
|
811
|
+
* @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.
|
|
812
|
+
*
|
|
813
|
+
* @name GetDeviceIntegroVariant
|
|
814
|
+
* @summary Read a device's Integro variant file
|
|
815
|
+
* @request GET:/api/devices/{slavePosition}/variant
|
|
816
|
+
*/
|
|
817
|
+
getDeviceIntegroVariant: (slavePosition: number, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<IntegroVariant, void>>;
|
|
818
|
+
/**
|
|
819
|
+
* @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.
|
|
820
|
+
*
|
|
821
|
+
* @name CheckDeviceFirmwareCompatibility
|
|
822
|
+
* @summary Check whether a firmware package belongs on a device
|
|
823
|
+
* @request GET:/api/devices/{slavePosition}/firmware-compatibility
|
|
824
|
+
*/
|
|
825
|
+
checkDeviceFirmwareCompatibility: (slavePosition: number, query: {
|
|
826
|
+
/**
|
|
827
|
+
* The package filename, with no directory part.
|
|
828
|
+
* @example "package_SOMANET-Circulo-7_8500-04-2332_motion-drive_v5.6.10.zip"
|
|
829
|
+
*/
|
|
830
|
+
filename: string;
|
|
831
|
+
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<FirmwareCompatibility, void>>;
|
|
804
832
|
/**
|
|
805
833
|
* @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 or a per-packet timeout of 700 ms is exceeded.
|
|
806
834
|
*
|
|
@@ -885,6 +913,30 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
|
|
|
885
913
|
*/
|
|
886
914
|
filename: string;
|
|
887
915
|
}, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<FirmwarePackageName, void>>;
|
|
916
|
+
/**
|
|
917
|
+
* @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.
|
|
918
|
+
*
|
|
919
|
+
* @name ParseHardwareDescription
|
|
920
|
+
* @summary Parse a .hardware_description file
|
|
921
|
+
* @request POST:/api/hardware-description/parse
|
|
922
|
+
*/
|
|
923
|
+
parseHardwareDescription: (data: string, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<HardwareDescription, void>>;
|
|
924
|
+
/**
|
|
925
|
+
* @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.
|
|
926
|
+
*
|
|
927
|
+
* @name ParseIntegroVariant
|
|
928
|
+
* @summary Parse a .variant file
|
|
929
|
+
* @request POST:/api/integro-variant/parse
|
|
930
|
+
*/
|
|
931
|
+
parseIntegroVariant: (data: File, params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<IntegroVariant, void>>;
|
|
932
|
+
/**
|
|
933
|
+
* @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.
|
|
934
|
+
*
|
|
935
|
+
* @name ListIntegroVariantOptions
|
|
936
|
+
* @summary The whole Integro variant option catalogue
|
|
937
|
+
* @request GET:/api/integro-variant/options
|
|
938
|
+
*/
|
|
939
|
+
listIntegroVariantOptions: (params?: RequestParams) => Promise<import("./http-client.js").HttpResponse<IntegroVariantOption[], any>>;
|
|
888
940
|
/**
|
|
889
941
|
* @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.
|
|
890
942
|
*
|
package/dist/generated/Api.js
CHANGED
|
@@ -605,6 +605,46 @@ export class Api extends HttpClient {
|
|
|
605
605
|
format: "json",
|
|
606
606
|
...params,
|
|
607
607
|
});
|
|
608
|
+
/**
|
|
609
|
+
* @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.
|
|
610
|
+
*
|
|
611
|
+
* @name GetDeviceHardwareDescription
|
|
612
|
+
* @summary Read what a device says it is
|
|
613
|
+
* @request GET:/api/devices/{slavePosition}/hardware-description
|
|
614
|
+
*/
|
|
615
|
+
getDeviceHardwareDescription = (slavePosition, params = {}) => this.request({
|
|
616
|
+
path: `/api/devices/${slavePosition}/hardware-description`,
|
|
617
|
+
method: "GET",
|
|
618
|
+
format: "json",
|
|
619
|
+
...params,
|
|
620
|
+
});
|
|
621
|
+
/**
|
|
622
|
+
* @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.
|
|
623
|
+
*
|
|
624
|
+
* @name GetDeviceIntegroVariant
|
|
625
|
+
* @summary Read a device's Integro variant file
|
|
626
|
+
* @request GET:/api/devices/{slavePosition}/variant
|
|
627
|
+
*/
|
|
628
|
+
getDeviceIntegroVariant = (slavePosition, params = {}) => this.request({
|
|
629
|
+
path: `/api/devices/${slavePosition}/variant`,
|
|
630
|
+
method: "GET",
|
|
631
|
+
format: "json",
|
|
632
|
+
...params,
|
|
633
|
+
});
|
|
634
|
+
/**
|
|
635
|
+
* @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.
|
|
636
|
+
*
|
|
637
|
+
* @name CheckDeviceFirmwareCompatibility
|
|
638
|
+
* @summary Check whether a firmware package belongs on a device
|
|
639
|
+
* @request GET:/api/devices/{slavePosition}/firmware-compatibility
|
|
640
|
+
*/
|
|
641
|
+
checkDeviceFirmwareCompatibility = (slavePosition, query, params = {}) => this.request({
|
|
642
|
+
path: `/api/devices/${slavePosition}/firmware-compatibility`,
|
|
643
|
+
method: "GET",
|
|
644
|
+
query: query,
|
|
645
|
+
format: "json",
|
|
646
|
+
...params,
|
|
647
|
+
});
|
|
608
648
|
/**
|
|
609
649
|
* @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 or a per-packet timeout of 700 ms is exceeded.
|
|
610
650
|
*
|
|
@@ -686,6 +726,48 @@ export class Api extends HttpClient {
|
|
|
686
726
|
format: "json",
|
|
687
727
|
...params,
|
|
688
728
|
});
|
|
729
|
+
/**
|
|
730
|
+
* @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.
|
|
731
|
+
*
|
|
732
|
+
* @name ParseHardwareDescription
|
|
733
|
+
* @summary Parse a .hardware_description file
|
|
734
|
+
* @request POST:/api/hardware-description/parse
|
|
735
|
+
*/
|
|
736
|
+
parseHardwareDescription = (data, params = {}) => this.request({
|
|
737
|
+
path: `/api/hardware-description/parse`,
|
|
738
|
+
method: "POST",
|
|
739
|
+
body: data,
|
|
740
|
+
type: ContentType.Text,
|
|
741
|
+
format: "json",
|
|
742
|
+
...params,
|
|
743
|
+
});
|
|
744
|
+
/**
|
|
745
|
+
* @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.
|
|
746
|
+
*
|
|
747
|
+
* @name ParseIntegroVariant
|
|
748
|
+
* @summary Parse a .variant file
|
|
749
|
+
* @request POST:/api/integro-variant/parse
|
|
750
|
+
*/
|
|
751
|
+
parseIntegroVariant = (data, params = {}) => this.request({
|
|
752
|
+
path: `/api/integro-variant/parse`,
|
|
753
|
+
method: "POST",
|
|
754
|
+
body: data,
|
|
755
|
+
format: "json",
|
|
756
|
+
...params,
|
|
757
|
+
});
|
|
758
|
+
/**
|
|
759
|
+
* @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.
|
|
760
|
+
*
|
|
761
|
+
* @name ListIntegroVariantOptions
|
|
762
|
+
* @summary The whole Integro variant option catalogue
|
|
763
|
+
* @request GET:/api/integro-variant/options
|
|
764
|
+
*/
|
|
765
|
+
listIntegroVariantOptions = (params = {}) => this.request({
|
|
766
|
+
path: `/api/integro-variant/options`,
|
|
767
|
+
method: "GET",
|
|
768
|
+
format: "json",
|
|
769
|
+
...params,
|
|
770
|
+
});
|
|
689
771
|
/**
|
|
690
772
|
* @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.
|
|
691
773
|
*
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
type UtilRequiredKeys<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
|
|
1
2
|
/** A CiA402 drive's control snapshot — its state machine, control words, and mode. */
|
|
2
3
|
export interface Cia402Status {
|
|
3
4
|
/**
|
|
@@ -583,40 +584,224 @@ export interface FirmwarePackageName {
|
|
|
583
584
|
*/
|
|
584
585
|
hardwareName: string;
|
|
585
586
|
/**
|
|
586
|
-
* The
|
|
587
|
+
* The hardware this package is built for, verbatim — the string a compatibility check compares.
|
|
587
588
|
* @example "8500-04-2332"
|
|
588
589
|
*/
|
|
589
|
-
|
|
590
|
+
fullFirmwareDescriptor: string;
|
|
590
591
|
/**
|
|
591
|
-
*
|
|
592
|
+
* Firmware or software name.
|
|
592
593
|
* @example "motion-drive"
|
|
593
594
|
*/
|
|
594
|
-
|
|
595
|
+
softwareName: string;
|
|
595
596
|
/**
|
|
596
|
-
*
|
|
597
|
+
* The firmware or software version, including the leading `v`. Not to be confused with `firmwareVersion`, which is the *hardware* revision inside the descriptor.
|
|
597
598
|
* @example "v5.6.10"
|
|
598
599
|
*/
|
|
599
|
-
|
|
600
|
+
softwareVersion: string;
|
|
600
601
|
/**
|
|
601
|
-
*
|
|
602
|
-
* @example 8500
|
|
602
|
+
* Firmware id from the descriptor — the hardware product.
|
|
603
|
+
* @example "8500"
|
|
603
604
|
*/
|
|
604
|
-
|
|
605
|
+
firmwareId?: string;
|
|
605
606
|
/**
|
|
606
|
-
*
|
|
607
|
-
* @example
|
|
607
|
+
* Hardware revision from the descriptor. A string, so a leading zero survives: `04` read as a number and printed back would be `4`, and `8500-4` matches no package.
|
|
608
|
+
* @example "04"
|
|
609
|
+
*/
|
|
610
|
+
firmwareVersion?: string;
|
|
611
|
+
/**
|
|
612
|
+
* Firmware encryption key id from the descriptor. A string because real packages carry non-numeric ones, e.g. `A`.
|
|
613
|
+
* @example "2332"
|
|
614
|
+
*/
|
|
615
|
+
keyId?: string;
|
|
616
|
+
/**
|
|
617
|
+
* Fieldbus protocol character from the descriptor, hexadecimal. `1` is EtherCAT.
|
|
618
|
+
* @example "1"
|
|
608
619
|
*/
|
|
609
|
-
|
|
620
|
+
fieldbusProtocol?: string;
|
|
610
621
|
/**
|
|
611
|
-
*
|
|
612
|
-
* @example
|
|
622
|
+
* `firmwareId` and `firmwareVersion` joined — the descriptor without the key or fieldbus. Useful for saying *how* a package missed: a matching build descriptor with a different key means right hardware, wrong encryption key.
|
|
623
|
+
* @example "8500-04"
|
|
613
624
|
*/
|
|
614
|
-
|
|
625
|
+
buildDescriptor?: string;
|
|
626
|
+
}
|
|
627
|
+
/** One item making up a device or assembly. Carries no function beyond recording what has a serial number, so every property can legitimately be empty. */
|
|
628
|
+
export interface HardwareComponent {
|
|
629
|
+
/** @example "Com EtherCAT" */
|
|
630
|
+
name: string;
|
|
631
|
+
/** @example "A.2" */
|
|
632
|
+
version: string;
|
|
633
|
+
/** @example "1000-02-0005739-1815" */
|
|
634
|
+
serialNumber: string;
|
|
635
|
+
}
|
|
636
|
+
/** A device or an assembly. The two are one shape — the specification lists their fields in a single table and they differ only in that `keyId` and `macAddress` are device-only. */
|
|
637
|
+
export interface HardwareProduct {
|
|
615
638
|
/**
|
|
616
|
-
*
|
|
639
|
+
* Human-readable description of the hardware.
|
|
640
|
+
* @example "SOMANET Servo Node 400 EtherCAT"
|
|
641
|
+
*/
|
|
642
|
+
name: string;
|
|
643
|
+
/**
|
|
644
|
+
* Names the product's picture. Empty when the file carries none.
|
|
645
|
+
* @example "9501-xx"
|
|
646
|
+
*/
|
|
647
|
+
imageId: string;
|
|
648
|
+
/**
|
|
649
|
+
* The `firmwareId` — identifies the hardware product.
|
|
650
|
+
* @example "9501"
|
|
651
|
+
*/
|
|
652
|
+
id: string;
|
|
653
|
+
/**
|
|
654
|
+
* The `firmwareVersion` — revision of that product.
|
|
655
|
+
* @example "01"
|
|
656
|
+
*/
|
|
657
|
+
version: string;
|
|
658
|
+
/**
|
|
659
|
+
* Firmware encryption key burned to OTP memory. Device only, and empty on hardware whose firmware predates encryption.
|
|
660
|
+
* @example "4622"
|
|
661
|
+
*/
|
|
662
|
+
keyId: string;
|
|
663
|
+
/** @example "9501-01-040595-4023" */
|
|
664
|
+
serialNumber: string;
|
|
665
|
+
/**
|
|
666
|
+
* MAC address of the Ethernet port. Device only.
|
|
667
|
+
* @example "01-23-45-67-89-AB"
|
|
668
|
+
*/
|
|
669
|
+
macAddress: string;
|
|
670
|
+
components: HardwareComponent[];
|
|
671
|
+
/**
|
|
672
|
+
* `id` and `version` joined by a dash.
|
|
673
|
+
* @example "9501-01"
|
|
674
|
+
*/
|
|
675
|
+
buildDescriptor: string;
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* A device's `.hardware_description` file — what the hardware says it is, and the source of the descriptor that decides which firmware belongs on it.
|
|
679
|
+
*
|
|
680
|
+
* `device` is never absent, and that is structural rather than a simplification: the file lives *on* the device, so a file without one cannot exist. `assembly` is present only when the device was packaged into a product — an ACTILINK is an assembly with a SOMANET Node device inside it — and when it is, it is what firmware is matched against first.
|
|
681
|
+
*/
|
|
682
|
+
export interface HardwareDescription {
|
|
683
|
+
/**
|
|
684
|
+
* Format version of the file itself, semver.
|
|
685
|
+
* @example "1.2.0"
|
|
686
|
+
*/
|
|
687
|
+
fileVersion: string;
|
|
688
|
+
/** A device or an assembly. The two are one shape — the specification lists their fields in a single table and they differ only in that `keyId` and `macAddress` are device-only. */
|
|
689
|
+
device: HardwareProduct;
|
|
690
|
+
/** A device or an assembly. The two are one shape — the specification lists their fields in a single table and they differ only in that `keyId` and `macAddress` are device-only. */
|
|
691
|
+
assembly?: HardwareProduct;
|
|
692
|
+
}
|
|
693
|
+
/** One entry of the Integro runtime-variant option catalogue. Nothing on the server acts on `socVariables` or `incompatibleOptionIds` — the drive enforces them — but they are what make a decoded file legible. */
|
|
694
|
+
export interface IntegroVariantOption {
|
|
695
|
+
/**
|
|
696
|
+
* The option code as it appears in the file.
|
|
697
|
+
* @example 1
|
|
698
|
+
*/
|
|
699
|
+
id: number;
|
|
700
|
+
/**
|
|
701
|
+
* What the option selects.
|
|
702
|
+
* @example "Fieldbus Protocol"
|
|
703
|
+
*/
|
|
704
|
+
category: string;
|
|
705
|
+
/**
|
|
706
|
+
* Which choice within that category.
|
|
707
|
+
* @example "EtherCAT"
|
|
708
|
+
*/
|
|
709
|
+
meaning: string;
|
|
710
|
+
/**
|
|
711
|
+
* The drive's own configuration values this option sets. Empty for an option the fieldbus firmware acts on rather than the SoC.
|
|
712
|
+
* @example ["adc_phase_current_sensor_gain"]
|
|
713
|
+
*/
|
|
714
|
+
socVariables: string[];
|
|
715
|
+
/**
|
|
716
|
+
* Options that cannot be selected alongside this one — the other members of a category that selects exactly one choice. Empty for an independent flag such as "disable DI1".
|
|
717
|
+
* @example [0,2,3,39]
|
|
718
|
+
*/
|
|
719
|
+
incompatibleOptionIds: number[];
|
|
720
|
+
/**
|
|
721
|
+
* Segments of the part number this option corresponds to. Empty for an option not distinguished in the part number.
|
|
722
|
+
* @example ["EC"]
|
|
723
|
+
*/
|
|
724
|
+
mpnSegmentCodes: string[];
|
|
725
|
+
}
|
|
726
|
+
/** One option code from a decoded file, expanded into its catalogue entry. Everything but `id` is absent for a code the catalogue does not name, so "we do not know what this is" is missing properties rather than the string `unknown`. */
|
|
727
|
+
export type IntegroVariantFileOption = UtilRequiredKeys<IntegroVariantOption, "id">;
|
|
728
|
+
/**
|
|
729
|
+
* A decoded `.variant` file: which features a SOMANET Integro was licensed with.
|
|
730
|
+
*
|
|
731
|
+
* Only Integro drives carry one. Its layout comes from the firmware that reads it rather than from a specification — there is none — and the one thing on it that matters beyond inspection is `fieldbusProtocol`, which the hardware description deliberately does not carry and a full firmware descriptor ends with.
|
|
732
|
+
*/
|
|
733
|
+
export interface IntegroVariant {
|
|
734
|
+
/**
|
|
735
|
+
* Format version; 1 in every file seen so far.
|
|
736
|
+
* @example 1
|
|
737
|
+
*/
|
|
738
|
+
fileVersion: number;
|
|
739
|
+
/** Lowercase hex. Opaque — verification needs the private key and happens on the drive — and reported only so a caller can see whether one is present. */
|
|
740
|
+
signature: string;
|
|
741
|
+
/**
|
|
742
|
+
* Lowercase hex netX chip id this file was issued for.
|
|
743
|
+
* @example "4e64646c70b286a000000000"
|
|
744
|
+
*/
|
|
745
|
+
chipId: string;
|
|
746
|
+
/** @example "9004-02-0000424-2445" */
|
|
747
|
+
serialNumber: string;
|
|
748
|
+
/** @example "40:49:8A:01:21:D6" */
|
|
749
|
+
macAddress: string;
|
|
750
|
+
/**
|
|
751
|
+
* Who the device was licensed to.
|
|
752
|
+
* @example 1
|
|
753
|
+
*/
|
|
754
|
+
customerId: number;
|
|
755
|
+
/**
|
|
756
|
+
* Raw mode value. `passive` (0x51) is the failure state as much as a mode: firmware falls back to it when the file is missing, its signature does not verify, or its chip id belongs to another device.
|
|
757
|
+
* @example 87
|
|
758
|
+
*/
|
|
759
|
+
operationMode: number;
|
|
760
|
+
/** @example "live" */
|
|
761
|
+
operationModeName: "passive" | "trial" | "production" | "live" | "unknown";
|
|
762
|
+
/**
|
|
763
|
+
* The fieldbus the device is licensed for, for the tail of a full firmware descriptor. **EtherCAT wins when several are selected** — real files do carry more than one. Absent when the file selects no fieldbus at all.
|
|
617
764
|
* @example 1
|
|
618
765
|
*/
|
|
619
766
|
fieldbusProtocol?: number;
|
|
767
|
+
/** The option codes, in the order the file lists them — which is not sorted, and is the only record of how the file was written. */
|
|
768
|
+
options: IntegroVariantFileOption[];
|
|
769
|
+
}
|
|
770
|
+
/** The full firmware descriptors one device accepts firmware under. Two rather than one because the specification says both are compatible and lists both for the user to choose from: the assembly's firmware "should have been customized for the assembly", so it is the one to prefer, while the device package is the generic build for the hardware inside it. */
|
|
771
|
+
export interface FullFirmwareDescriptors {
|
|
772
|
+
/**
|
|
773
|
+
* The device's own descriptor. Always present.
|
|
774
|
+
* @example "9010-02-2423-1"
|
|
775
|
+
*/
|
|
776
|
+
device: string;
|
|
777
|
+
/**
|
|
778
|
+
* The assembly's build descriptor with the **device's** key id — assemblies have no key of their own. Absent when the hardware description carries no assembly.
|
|
779
|
+
* @example "6000-01-2423-1"
|
|
780
|
+
*/
|
|
781
|
+
assembly?: string;
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Whether one firmware package belongs on one device.
|
|
785
|
+
*
|
|
786
|
+
* **The whole descriptor string is compared, never its decoded parts.** That is what makes the check correct for descriptors outside the numeric convention, and it is how the specification frames the operation — find compatible firmware by searching for the `fullFirmwareDescriptor` string.
|
|
787
|
+
*/
|
|
788
|
+
export interface FirmwareCompatibility {
|
|
789
|
+
/** @example true */
|
|
790
|
+
compatible: boolean;
|
|
791
|
+
/**
|
|
792
|
+
* Which of the device's descriptors matched. `device` is a match that still has something to say: it is the generic build rather than the one customised for the assembly.
|
|
793
|
+
* @example "assembly"
|
|
794
|
+
*/
|
|
795
|
+
match: "none" | "assembly" | "device";
|
|
796
|
+
/** A SOMANET firmware package filename broken into its fields. The four decoded-descriptor properties are absent — not null — when the full firmware descriptor is not the numeric kind, which the naming specification explicitly allows. */
|
|
797
|
+
packageName: FirmwarePackageName;
|
|
798
|
+
/** The full firmware descriptors one device accepts firmware under. Two rather than one because the specification says both are compatible and lists both for the user to choose from: the assembly's firmware "should have been customized for the assembly", so it is the one to prefer, while the device package is the generic build for the hardware inside it. */
|
|
799
|
+
deviceDescriptors: FullFirmwareDescriptors;
|
|
800
|
+
/**
|
|
801
|
+
* One sentence naming the descriptors involved, ready to show a user. Populated for a match as well as a mismatch.
|
|
802
|
+
* @example "This package is built for 6000-01-2423-1, which is this device's assembly."
|
|
803
|
+
*/
|
|
804
|
+
explanation: string;
|
|
620
805
|
}
|
|
621
806
|
/** One procedure paired with how its last run on this device went — an entry of `GET /api/devices/{slavePosition}/procedures`. The pairing is what lets a page render in a single request instead of one per procedure. */
|
|
622
807
|
export interface ProcedureListing {
|
|
@@ -1373,6 +1558,11 @@ export interface EsiEntry {
|
|
|
1373
1558
|
* @example 7
|
|
1374
1559
|
*/
|
|
1375
1560
|
dataType: number;
|
|
1561
|
+
/**
|
|
1562
|
+
* The C++ type this entry's value maps to, resolved from `dataType` **and** `bitSize`. The width is not decoration: a vendor's `ARRAY [0..24] OF BYTE` resolves to the ETG.1020 code for BYTE, so trusting the code alone would call a 25-byte object a `uint8_t` and every read of it would return its first byte. Where the declared width contradicts the code, this is `std::vector<uint8_t>`.
|
|
1563
|
+
* @example "int32_t"
|
|
1564
|
+
*/
|
|
1565
|
+
cxxType: string;
|
|
1376
1566
|
isSigned: boolean;
|
|
1377
1567
|
bitSize: number;
|
|
1378
1568
|
/** Offset within the object's complete-access image */
|
|
@@ -1471,3 +1661,4 @@ export interface EsiParseResult {
|
|
|
1471
1661
|
/** 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. */
|
|
1472
1662
|
warnings?: string[];
|
|
1473
1663
|
}
|
|
1664
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './generated/http-client.js';
|
|
2
2
|
export * from './generated/data-contracts.js';
|
|
3
3
|
export * from './generated/Api.js';
|
|
4
|
+
export * from './api-error.js';
|
|
4
5
|
export * from './constants.js';
|
|
5
6
|
export * from './web-socket-connection.js';
|
|
6
7
|
export * from './client.js';
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
export * from './generated/http-client.js';
|
|
6
6
|
export * from './generated/data-contracts.js';
|
|
7
7
|
export * from './generated/Api.js';
|
|
8
|
+
export * from './api-error.js';
|
|
8
9
|
export * from './constants.js';
|
|
9
10
|
export * from './web-socket-connection.js';
|
|
10
11
|
export * from './client.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synapticon/motion-master-client",
|
|
3
|
-
"version": "6.0.0-alpha.
|
|
3
|
+
"version": "6.0.0-alpha.70",
|
|
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": {
|