motion-master-client 0.0.136 → 0.0.138
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/package.json +1 -1
- package/src/lib/firmware.d.ts +68 -36
- package/src/lib/firmware.js +136 -74
- package/src/lib/firmware.js.map +1 -1
package/package.json
CHANGED
package/src/lib/firmware.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { DeviceComponent, HardwareDescription, StackInfo } from "./hardware-description";
|
|
3
3
|
import { IntegroVariant } from "./integro-variant";
|
|
4
|
+
import { RangeOptions } from "semver";
|
|
4
5
|
export declare const firmwareIdRegExp: RegExp;
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const newFirmwarePackageFilenameRegExp: RegExp;
|
|
7
|
+
export declare const oldFirmwarePackageFilenameRegExp: RegExp;
|
|
7
8
|
/**
|
|
8
|
-
* New firmware package
|
|
9
|
+
* New firmware package filenames are described in section 4.3.3 of the "Hardware Description File Format".
|
|
9
10
|
* For more details, refer to the document at: {@link https://docs.google.com/document/d/1bafY-F8qFMLd0Las8fQFF6H9PTVYFjv01bhV7owqx8E}.
|
|
10
11
|
*
|
|
11
12
|
* @example
|
|
12
13
|
* "package_SOMANET-Servo-Node-400-EtherCAT_9501-01-4622-1_motion-drive_v4.1.0.zip"
|
|
13
14
|
*/
|
|
14
|
-
export interface
|
|
15
|
+
export interface NewFirmwarePackageFilename {
|
|
15
16
|
/**
|
|
16
17
|
* General format description: "package" refers to the zip bundles used to deliver firmware for SOMANET devices.
|
|
17
18
|
*/
|
|
@@ -44,12 +45,12 @@ export interface NewFirmwarePackageName {
|
|
|
44
45
|
fieldbusProtocol?: number;
|
|
45
46
|
}
|
|
46
47
|
/**
|
|
47
|
-
* Documentation for old firmware package
|
|
48
|
+
* Documentation for old firmware package filenames is not available.
|
|
48
49
|
*
|
|
49
50
|
* @example
|
|
50
51
|
* "package-motion-drive_ComEtherCAT-b_CoreC2X-a_Drive400-e_v4.2.1.zip"
|
|
51
52
|
*/
|
|
52
|
-
export interface
|
|
53
|
+
export interface OldFirmwarePackageFilename {
|
|
53
54
|
description: string;
|
|
54
55
|
components: DeviceComponent[];
|
|
55
56
|
firmwareVersion: string;
|
|
@@ -78,24 +79,24 @@ export interface FirmwareId {
|
|
|
78
79
|
*/
|
|
79
80
|
export declare function parseFirmwareId(fwid: string): FirmwareId;
|
|
80
81
|
/**
|
|
81
|
-
* The format for new firmware package
|
|
82
|
+
* The format for new firmware package filenames is detailed in the "Hardware Description File Format" document.
|
|
82
83
|
*/
|
|
83
|
-
export declare function
|
|
84
|
+
export declare function isNewFirmwarePackageFilename(filename: string): boolean;
|
|
84
85
|
/**
|
|
85
|
-
* Documentation for older firmware package
|
|
86
|
-
* These package
|
|
86
|
+
* Documentation for older firmware package filenames, such as "package-motion-drive_ComEtherCAT-b_CoreC2X-a_Drive400-e_v4.2.1.zip", is unavailable.
|
|
87
|
+
* These package filenames consist of three hardware components (modules): Com, Core, and Drive.
|
|
87
88
|
* Firmware packages with these older naming conventions are specifically built for legacy SOMANET Node devices.
|
|
88
89
|
*/
|
|
89
|
-
export declare function
|
|
90
|
+
export declare function isOldFirmwarePackageFilename(filename: string): boolean;
|
|
90
91
|
/**
|
|
91
|
-
* Parses a new firmware package
|
|
92
|
-
* Returns `undefined` if the
|
|
92
|
+
* Parses a new firmware package filename and returns an instance of {@link NewFirmwarePackageFilename}.
|
|
93
|
+
* Returns `undefined` if the filename does not match the new firmware package filename format.
|
|
93
94
|
*
|
|
94
|
-
* @throws {Error} Throws an error if the provided
|
|
95
|
+
* @throws {Error} Throws an error if the provided filename does not match the expected pattern.
|
|
95
96
|
*/
|
|
96
|
-
export declare function
|
|
97
|
+
export declare function parseNewFirmwarePackageFilename(filename: string): NewFirmwarePackageFilename;
|
|
97
98
|
/**
|
|
98
|
-
* Given an old firmware package
|
|
99
|
+
* Given an old firmware package filename in the format:
|
|
99
100
|
* "package-motion-drive_ComEtherCAT-b_CoreC2X-a_Drive400-e_v4.2.1.zip",
|
|
100
101
|
* this function extracts the hardware components and returns an array of objects.
|
|
101
102
|
* Each object includes the component name, version, and an empty serial number.
|
|
@@ -104,36 +105,36 @@ export declare function parseNewFirmwarePackageName(name: string): NewFirmwarePa
|
|
|
104
105
|
* which includes only hardware components but lacks a firmware ID. To check if two sets of components match and verify compatibility,
|
|
105
106
|
* use the {@link deviceComponentsMatch} function.
|
|
106
107
|
*
|
|
107
|
-
* @throws {Error} Throws an error if the provided
|
|
108
|
+
* @throws {Error} Throws an error if the provided filename does not match the expected pattern.
|
|
108
109
|
*/
|
|
109
|
-
export declare function
|
|
110
|
+
export declare function extractDeviceComponentsFromOldFirmwarePackageFilename(filename: string): DeviceComponent[];
|
|
110
111
|
/**
|
|
111
|
-
* Parses an old firmware package
|
|
112
|
-
* Returns `undefined` if the
|
|
112
|
+
* Parses an old firmware package filename and returns an instance of {@link OldFirmwarePackageFilename}.
|
|
113
|
+
* Returns `undefined` if the filename does not match the old firmware package filename format.
|
|
113
114
|
*
|
|
114
|
-
* @throws {Error} Throws an error if the provided
|
|
115
|
+
* @throws {Error} Throws an error if the provided filename does not match the expected pattern.
|
|
115
116
|
*/
|
|
116
|
-
export declare function
|
|
117
|
+
export declare function parseOldFirmwarePackageFilename(filename: string): OldFirmwarePackageFilename;
|
|
117
118
|
/**
|
|
118
119
|
* Type guard to determine if the provided value is a Stack Info object.
|
|
119
120
|
*/
|
|
120
121
|
export declare function isStackInfo(value: any): value is StackInfo;
|
|
121
122
|
/**
|
|
122
|
-
* Checks if a firmware package
|
|
123
|
+
* Checks if a firmware package filename is compatible with a device based on the provided FWID, Stack Info, or Hardware Description.
|
|
123
124
|
* This function is useful for determining whether a firmware package can be installed on a device.
|
|
124
125
|
*
|
|
125
|
-
* - If you provide Stack Info, use the old firmware package
|
|
126
|
-
* - If you provide FWID or Hardware Description, use the new firmware package
|
|
126
|
+
* - If you provide Stack Info, use the old firmware package filename.
|
|
127
|
+
* - If you provide FWID or Hardware Description, use the new firmware package filename.
|
|
127
128
|
*
|
|
128
|
-
* @param
|
|
129
|
+
* @param filename The firmware package filename (either old or new).
|
|
129
130
|
* @param id The identifier, which can be FWID, Stack Info, or Hardware Description.
|
|
130
131
|
* @param integroVariant The parsed Integro Variant file or its raw buffer.
|
|
131
|
-
* @returns `true` if the firmware package
|
|
132
|
-
* @throws {Error} Throws an error if an invalid combination is provided, such as FWID with an old firmware package
|
|
132
|
+
* @returns `true` if the firmware package filename is compatible with the device; otherwise, `false`.
|
|
133
|
+
* @throws {Error} Throws an error if an invalid combination is provided, such as FWID with an old firmware package filename.
|
|
133
134
|
*/
|
|
134
|
-
export declare function
|
|
135
|
+
export declare function isFirmwarePackageFilenameCompatibleWithDevice(filename: string, id: string | StackInfo | HardwareDescription, integroVariant?: Buffer | IntegroVariant): boolean;
|
|
135
136
|
/**
|
|
136
|
-
* Extracts the Firmware ID (FWID) from either the new firmware package
|
|
137
|
+
* Extracts the Firmware ID (FWID) from either the new firmware package filename or the provided Hardware Description.
|
|
137
138
|
* The optional Integro Variant is used if the Firmware ID includes the Fieldbus Protocol.
|
|
138
139
|
*
|
|
139
140
|
* Note: If additional options from the Integro Variant are incorporated into the FWID in the future, this code will need to be updated accordingly.
|
|
@@ -143,26 +144,57 @@ export declare function isFirmwarePackageNameCompatibleWithDevice(name: string,
|
|
|
143
144
|
* - If an assembly is present, the ID and version are taken from the assembly, while the key ID is still taken from the device.
|
|
144
145
|
* - In all cases, the key ID is sourced from the device.
|
|
145
146
|
*
|
|
146
|
-
* @param sub The new firmware package
|
|
147
|
+
* @param sub The new firmware package filename or hardware description.
|
|
147
148
|
* @param integroVariant The parsed Integro Variant file or its raw buffer.
|
|
148
|
-
* @throws {Error} If the provided
|
|
149
|
+
* @throws {Error} If the provided filename does not match the expected pattern.
|
|
149
150
|
* @returns The Firmware ID (FWID), e.g., "9501-01-4622-1".
|
|
150
151
|
*/
|
|
151
152
|
export declare function extractFirmwareId(sub: string | HardwareDescription, integroVariant?: Buffer | IntegroVariant): string;
|
|
152
153
|
/**
|
|
153
|
-
* Extracts the firmware version from the given firmware package
|
|
154
|
+
* Extracts the firmware version from the given firmware package filename, whether it's in the old or new format.
|
|
154
155
|
*
|
|
155
156
|
* @example
|
|
156
157
|
* "v4.1.0"
|
|
157
158
|
*
|
|
158
|
-
* @throws {Error} Throws an error if the provided
|
|
159
|
+
* @throws {Error} Throws an error if the provided filename does not match the expected pattern.
|
|
159
160
|
*/
|
|
160
|
-
export declare function
|
|
161
|
+
export declare function extractFirmwareVersionFromFirmwarePackageFilename(filename: string): string;
|
|
161
162
|
/**
|
|
162
163
|
* Older firmware versions for Circulo included a different build to support the Encoder Calibration feature in order to save memory.
|
|
163
164
|
* Newer firmware versions now include the Encoder Calibration feature, so a separate build is no longer necessary.
|
|
164
165
|
*
|
|
165
166
|
* @example
|
|
166
167
|
* "package_SOMANET-Servo-Node-Circulo-7-700_8502-01_motion-drive_v0.4.3-calibration.zip"
|
|
168
|
+
* "v0.4.3-calibration"
|
|
167
169
|
*/
|
|
168
|
-
export declare function
|
|
170
|
+
export declare function isCalibrationFirmware(version?: string): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Some older firmware versions included invalid build metadata.
|
|
173
|
+
* This function removes any invalid metadata from the provided version.
|
|
174
|
+
*/
|
|
175
|
+
export declare function removeInvalidBuildMetadataFromFirmwareVersion(version: string): string;
|
|
176
|
+
/**
|
|
177
|
+
* Checks if a firmware version satisfies the given range.
|
|
178
|
+
* If no options are specified, a custom one will be used.
|
|
179
|
+
* Older firmware versions sometimes included invalid build metadata, which could cause the function to fail.
|
|
180
|
+
* To prevent this, the function removes any invalid build metadata before performing the version check.
|
|
181
|
+
*/
|
|
182
|
+
export declare function firmwareVersionSatisfies(version: string, range: string, options?: RangeOptions): boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Determines if a firmware version falls within a specified range.
|
|
185
|
+
*
|
|
186
|
+
* @param version The firmware version to check.
|
|
187
|
+
* @param range A version range, following the syntax outlined in {@link https://github.com/npm/node-semver#ranges}.
|
|
188
|
+
* @param calibration If a string, it will be treated as a range. Otherwise, the function returns the boolean value of `calibration`.
|
|
189
|
+
*/
|
|
190
|
+
export declare function isFirmwareVersionInRange(version: string, range?: string | null, calibration?: boolean | string): boolean;
|
|
191
|
+
/**
|
|
192
|
+
* Checks if the provided firmware version includes the new encoder configuration objects (0x2110 and 0x2112).
|
|
193
|
+
* Firmware versions starting from v5.0.0-rc.5 and v0.4.0-calibration include these objects.
|
|
194
|
+
*
|
|
195
|
+
* Previously, firmware had separate objects for each type of encoder (sensor), resulting in more than 12 record objects,
|
|
196
|
+
* each with several subitems. This consumed unnecessary memory, prompting a refactor to introduce the new encoder configuration objects.
|
|
197
|
+
*
|
|
198
|
+
* The new configuration is referred to as "encoder configuration" (0x2110, 0x2112), while the older is called "sensor configuration".
|
|
199
|
+
*/
|
|
200
|
+
export declare function isEncoderConfigurationFirmware(version?: string): boolean;
|
package/src/lib/firmware.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.isEncoderConfigurationFirmware = exports.isFirmwareVersionInRange = exports.firmwareVersionSatisfies = exports.removeInvalidBuildMetadataFromFirmwareVersion = exports.isCalibrationFirmware = exports.extractFirmwareVersionFromFirmwarePackageFilename = exports.extractFirmwareId = exports.isFirmwarePackageFilenameCompatibleWithDevice = exports.isStackInfo = exports.parseOldFirmwarePackageFilename = exports.extractDeviceComponentsFromOldFirmwarePackageFilename = exports.parseNewFirmwarePackageFilename = exports.isOldFirmwarePackageFilename = exports.isNewFirmwarePackageFilename = exports.parseFirmwareId = exports.oldFirmwarePackageFilenameRegExp = exports.newFirmwarePackageFilenameRegExp = exports.firmwareIdRegExp = void 0;
|
|
4
4
|
const hardware_description_1 = require("./hardware-description");
|
|
5
5
|
const integro_variant_1 = require("./integro-variant");
|
|
6
|
-
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
6
|
+
const semver_1 = require("semver");
|
|
7
|
+
exports.firmwareIdRegExp = /^\d{4}-\d{2}(-\d{4})?(-\d+)*?$/;
|
|
8
|
+
exports.newFirmwarePackageFilenameRegExp = /^package_(.*).zip$/;
|
|
9
|
+
exports.oldFirmwarePackageFilenameRegExp = /^package-motion-drive_(.*).zip$/;
|
|
9
10
|
/**
|
|
10
11
|
* Parses the FWID string and returns an instance of the {@link FirmwareId} object.
|
|
11
12
|
*
|
|
@@ -20,42 +21,42 @@ function parseFirmwareId(fwid) {
|
|
|
20
21
|
}
|
|
21
22
|
exports.parseFirmwareId = parseFirmwareId;
|
|
22
23
|
/**
|
|
23
|
-
* The format for new firmware package
|
|
24
|
+
* The format for new firmware package filenames is detailed in the "Hardware Description File Format" document.
|
|
24
25
|
*/
|
|
25
|
-
function
|
|
26
|
-
return exports.
|
|
26
|
+
function isNewFirmwarePackageFilename(filename) {
|
|
27
|
+
return exports.newFirmwarePackageFilenameRegExp.test(filename);
|
|
27
28
|
}
|
|
28
|
-
exports.
|
|
29
|
+
exports.isNewFirmwarePackageFilename = isNewFirmwarePackageFilename;
|
|
29
30
|
/**
|
|
30
|
-
* Documentation for older firmware package
|
|
31
|
-
* These package
|
|
31
|
+
* Documentation for older firmware package filenames, such as "package-motion-drive_ComEtherCAT-b_CoreC2X-a_Drive400-e_v4.2.1.zip", is unavailable.
|
|
32
|
+
* These package filenames consist of three hardware components (modules): Com, Core, and Drive.
|
|
32
33
|
* Firmware packages with these older naming conventions are specifically built for legacy SOMANET Node devices.
|
|
33
34
|
*/
|
|
34
|
-
function
|
|
35
|
-
return exports.
|
|
35
|
+
function isOldFirmwarePackageFilename(filename) {
|
|
36
|
+
return exports.oldFirmwarePackageFilenameRegExp.test(filename);
|
|
36
37
|
}
|
|
37
|
-
exports.
|
|
38
|
+
exports.isOldFirmwarePackageFilename = isOldFirmwarePackageFilename;
|
|
38
39
|
/**
|
|
39
|
-
* Parses a new firmware package
|
|
40
|
-
* Returns `undefined` if the
|
|
40
|
+
* Parses a new firmware package filename and returns an instance of {@link NewFirmwarePackageFilename}.
|
|
41
|
+
* Returns `undefined` if the filename does not match the new firmware package filename format.
|
|
41
42
|
*
|
|
42
|
-
* @throws {Error} Throws an error if the provided
|
|
43
|
+
* @throws {Error} Throws an error if the provided filename does not match the expected pattern.
|
|
43
44
|
*/
|
|
44
|
-
function
|
|
45
|
-
if (!
|
|
46
|
-
throw new Error(`The provided
|
|
45
|
+
function parseNewFirmwarePackageFilename(filename) {
|
|
46
|
+
if (!isNewFirmwarePackageFilename(filename)) {
|
|
47
|
+
throw new Error(`The provided filename "${filename}" does not match the expected pattern.`);
|
|
47
48
|
}
|
|
48
|
-
const
|
|
49
|
-
const [description, hardwareName, firmwareId, firmwareName, firmwareVersion] =
|
|
49
|
+
const filenameNoExt = filename.replace(/\.[^/.]+$/, "");
|
|
50
|
+
const [description, hardwareName, firmwareId, firmwareName, firmwareVersion] = filenameNoExt.split('_');
|
|
50
51
|
return Object.assign({ description,
|
|
51
52
|
hardwareName,
|
|
52
53
|
firmwareId,
|
|
53
54
|
firmwareName,
|
|
54
55
|
firmwareVersion }, (parseFirmwareId(firmwareId)));
|
|
55
56
|
}
|
|
56
|
-
exports.
|
|
57
|
+
exports.parseNewFirmwarePackageFilename = parseNewFirmwarePackageFilename;
|
|
57
58
|
/**
|
|
58
|
-
* Given an old firmware package
|
|
59
|
+
* Given an old firmware package filename in the format:
|
|
59
60
|
* "package-motion-drive_ComEtherCAT-b_CoreC2X-a_Drive400-e_v4.2.1.zip",
|
|
60
61
|
* this function extracts the hardware components and returns an array of objects.
|
|
61
62
|
* Each object includes the component name, version, and an empty serial number.
|
|
@@ -64,14 +65,14 @@ exports.parseNewFirmwarePackageName = parseNewFirmwarePackageName;
|
|
|
64
65
|
* which includes only hardware components but lacks a firmware ID. To check if two sets of components match and verify compatibility,
|
|
65
66
|
* use the {@link deviceComponentsMatch} function.
|
|
66
67
|
*
|
|
67
|
-
* @throws {Error} Throws an error if the provided
|
|
68
|
+
* @throws {Error} Throws an error if the provided filename does not match the expected pattern.
|
|
68
69
|
*/
|
|
69
|
-
function
|
|
70
|
-
if (!
|
|
71
|
-
throw new Error(`The provided
|
|
70
|
+
function extractDeviceComponentsFromOldFirmwarePackageFilename(filename) {
|
|
71
|
+
if (!isOldFirmwarePackageFilename(filename)) {
|
|
72
|
+
throw new Error(`The provided filename "${filename}" does not match the expected pattern.`);
|
|
72
73
|
}
|
|
73
|
-
if (
|
|
74
|
-
return
|
|
74
|
+
if (filename.match(/_Com[^_]+_Core[^_]+_Drive/g)) {
|
|
75
|
+
return filename
|
|
75
76
|
.split('_')
|
|
76
77
|
.slice(1, 4)
|
|
77
78
|
.map((b) => {
|
|
@@ -85,27 +86,27 @@ function extractDeviceComponentsFromOldFirmwarePackageName(name) {
|
|
|
85
86
|
}
|
|
86
87
|
return [];
|
|
87
88
|
}
|
|
88
|
-
exports.
|
|
89
|
+
exports.extractDeviceComponentsFromOldFirmwarePackageFilename = extractDeviceComponentsFromOldFirmwarePackageFilename;
|
|
89
90
|
/**
|
|
90
|
-
* Parses an old firmware package
|
|
91
|
-
* Returns `undefined` if the
|
|
91
|
+
* Parses an old firmware package filename and returns an instance of {@link OldFirmwarePackageFilename}.
|
|
92
|
+
* Returns `undefined` if the filename does not match the old firmware package filename format.
|
|
92
93
|
*
|
|
93
|
-
* @throws {Error} Throws an error if the provided
|
|
94
|
+
* @throws {Error} Throws an error if the provided filename does not match the expected pattern.
|
|
94
95
|
*/
|
|
95
|
-
function
|
|
96
|
+
function parseOldFirmwarePackageFilename(filename) {
|
|
96
97
|
var _a, _b;
|
|
97
|
-
if (!
|
|
98
|
-
throw new Error(`The provided
|
|
98
|
+
if (!isOldFirmwarePackageFilename(filename)) {
|
|
99
|
+
throw new Error(`The provided filename "${filename}" does not match the expected pattern.`);
|
|
99
100
|
}
|
|
100
|
-
const parts =
|
|
101
|
-
const components =
|
|
101
|
+
const parts = filename.split('_');
|
|
102
|
+
const components = extractDeviceComponentsFromOldFirmwarePackageFilename(filename);
|
|
102
103
|
return {
|
|
103
104
|
description: parts[0],
|
|
104
105
|
components,
|
|
105
106
|
firmwareVersion: (_b = (_a = parts === null || parts === void 0 ? void 0 : parts.at(-1)) === null || _a === void 0 ? void 0 : _a.replace('.zip', '')) !== null && _b !== void 0 ? _b : '',
|
|
106
107
|
};
|
|
107
108
|
}
|
|
108
|
-
exports.
|
|
109
|
+
exports.parseOldFirmwarePackageFilename = parseOldFirmwarePackageFilename;
|
|
109
110
|
/**
|
|
110
111
|
* Type guard to determine if the provided value is a Stack Info object.
|
|
111
112
|
*/
|
|
@@ -114,42 +115,42 @@ function isStackInfo(value) {
|
|
|
114
115
|
}
|
|
115
116
|
exports.isStackInfo = isStackInfo;
|
|
116
117
|
/**
|
|
117
|
-
* Checks if a firmware package
|
|
118
|
+
* Checks if a firmware package filename is compatible with a device based on the provided FWID, Stack Info, or Hardware Description.
|
|
118
119
|
* This function is useful for determining whether a firmware package can be installed on a device.
|
|
119
120
|
*
|
|
120
|
-
* - If you provide Stack Info, use the old firmware package
|
|
121
|
-
* - If you provide FWID or Hardware Description, use the new firmware package
|
|
121
|
+
* - If you provide Stack Info, use the old firmware package filename.
|
|
122
|
+
* - If you provide FWID or Hardware Description, use the new firmware package filename.
|
|
122
123
|
*
|
|
123
|
-
* @param
|
|
124
|
+
* @param filename The firmware package filename (either old or new).
|
|
124
125
|
* @param id The identifier, which can be FWID, Stack Info, or Hardware Description.
|
|
125
126
|
* @param integroVariant The parsed Integro Variant file or its raw buffer.
|
|
126
|
-
* @returns `true` if the firmware package
|
|
127
|
-
* @throws {Error} Throws an error if an invalid combination is provided, such as FWID with an old firmware package
|
|
127
|
+
* @returns `true` if the firmware package filename is compatible with the device; otherwise, `false`.
|
|
128
|
+
* @throws {Error} Throws an error if an invalid combination is provided, such as FWID with an old firmware package filename.
|
|
128
129
|
*/
|
|
129
|
-
function
|
|
130
|
-
if (
|
|
131
|
-
throw new Error('The old firmware package
|
|
130
|
+
function isFirmwarePackageFilenameCompatibleWithDevice(filename, id, integroVariant) {
|
|
131
|
+
if (isOldFirmwarePackageFilename(filename) && !isStackInfo(id)) {
|
|
132
|
+
throw new Error('The old firmware package filename must be checked against the Stack Info to verify compatibility.');
|
|
132
133
|
}
|
|
133
|
-
if (
|
|
134
|
-
throw new Error('The new firmware package
|
|
134
|
+
if (isNewFirmwarePackageFilename(filename) && isStackInfo(id)) {
|
|
135
|
+
throw new Error('The new firmware package filename must be checked against the FWID or Hardware Description to verify compatibility.');
|
|
135
136
|
}
|
|
136
137
|
if (typeof id === 'string') {
|
|
137
|
-
return id === extractFirmwareId(
|
|
138
|
+
return id === extractFirmwareId(filename);
|
|
138
139
|
}
|
|
139
140
|
else if (isStackInfo(id)) {
|
|
140
|
-
const
|
|
141
|
+
const firmwarePackageFilenameDeviceComponents = extractDeviceComponentsFromOldFirmwarePackageFilename(filename);
|
|
141
142
|
const stackInfoDeviceComponents = (0, hardware_description_1.extractDeviceComponentsFromStackInfo)(id);
|
|
142
|
-
return (0, hardware_description_1.deviceComponentsMatch)(
|
|
143
|
+
return (0, hardware_description_1.deviceComponentsMatch)(firmwarePackageFilenameDeviceComponents, stackInfoDeviceComponents);
|
|
143
144
|
}
|
|
144
145
|
else {
|
|
145
|
-
const
|
|
146
|
+
const firmwarePackageFilenameFirmwareId = extractFirmwareId(filename);
|
|
146
147
|
const hardwareDescriptionFirmwareId = extractFirmwareId(id, integroVariant);
|
|
147
|
-
return
|
|
148
|
+
return firmwarePackageFilenameFirmwareId === hardwareDescriptionFirmwareId;
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
|
-
exports.
|
|
151
|
+
exports.isFirmwarePackageFilenameCompatibleWithDevice = isFirmwarePackageFilenameCompatibleWithDevice;
|
|
151
152
|
/**
|
|
152
|
-
* Extracts the Firmware ID (FWID) from either the new firmware package
|
|
153
|
+
* Extracts the Firmware ID (FWID) from either the new firmware package filename or the provided Hardware Description.
|
|
153
154
|
* The optional Integro Variant is used if the Firmware ID includes the Fieldbus Protocol.
|
|
154
155
|
*
|
|
155
156
|
* Note: If additional options from the Integro Variant are incorporated into the FWID in the future, this code will need to be updated accordingly.
|
|
@@ -159,19 +160,19 @@ exports.isFirmwarePackageNameCompatibleWithDevice = isFirmwarePackageNameCompati
|
|
|
159
160
|
* - If an assembly is present, the ID and version are taken from the assembly, while the key ID is still taken from the device.
|
|
160
161
|
* - In all cases, the key ID is sourced from the device.
|
|
161
162
|
*
|
|
162
|
-
* @param sub The new firmware package
|
|
163
|
+
* @param sub The new firmware package filename or hardware description.
|
|
163
164
|
* @param integroVariant The parsed Integro Variant file or its raw buffer.
|
|
164
|
-
* @throws {Error} If the provided
|
|
165
|
+
* @throws {Error} If the provided filename does not match the expected pattern.
|
|
165
166
|
* @returns The Firmware ID (FWID), e.g., "9501-01-4622-1".
|
|
166
167
|
*/
|
|
167
168
|
function extractFirmwareId(sub, integroVariant) {
|
|
168
169
|
if (typeof sub === 'string') {
|
|
169
|
-
if (
|
|
170
|
-
const obj =
|
|
170
|
+
if (isNewFirmwarePackageFilename(sub)) {
|
|
171
|
+
const obj = parseNewFirmwarePackageFilename(sub);
|
|
171
172
|
return obj === null || obj === void 0 ? void 0 : obj.firmwareId;
|
|
172
173
|
}
|
|
173
174
|
else {
|
|
174
|
-
throw new Error(`The provided
|
|
175
|
+
throw new Error(`The provided filename "${sub}" does not match the expected pattern.`);
|
|
175
176
|
}
|
|
176
177
|
}
|
|
177
178
|
else {
|
|
@@ -193,37 +194,98 @@ function extractFirmwareId(sub, integroVariant) {
|
|
|
193
194
|
}
|
|
194
195
|
exports.extractFirmwareId = extractFirmwareId;
|
|
195
196
|
/**
|
|
196
|
-
* Extracts the firmware version from the given firmware package
|
|
197
|
+
* Extracts the firmware version from the given firmware package filename, whether it's in the old or new format.
|
|
197
198
|
*
|
|
198
199
|
* @example
|
|
199
200
|
* "v4.1.0"
|
|
200
201
|
*
|
|
201
|
-
* @throws {Error} Throws an error if the provided
|
|
202
|
+
* @throws {Error} Throws an error if the provided filename does not match the expected pattern.
|
|
202
203
|
*/
|
|
203
|
-
function
|
|
204
|
-
if (
|
|
205
|
-
const parsed =
|
|
204
|
+
function extractFirmwareVersionFromFirmwarePackageFilename(filename) {
|
|
205
|
+
if (isNewFirmwarePackageFilename(filename)) {
|
|
206
|
+
const parsed = parseNewFirmwarePackageFilename(filename);
|
|
206
207
|
return parsed.firmwareVersion;
|
|
207
208
|
}
|
|
208
|
-
else if (
|
|
209
|
-
const parsed =
|
|
209
|
+
else if (isOldFirmwarePackageFilename(filename)) {
|
|
210
|
+
const parsed = parseOldFirmwarePackageFilename(filename);
|
|
210
211
|
return parsed.firmwareVersion;
|
|
211
212
|
}
|
|
212
213
|
else {
|
|
213
|
-
throw new Error(`The provided
|
|
214
|
+
throw new Error(`The provided filename "${filename}" does not match the expected pattern.`);
|
|
214
215
|
}
|
|
215
216
|
}
|
|
216
|
-
exports.
|
|
217
|
+
exports.extractFirmwareVersionFromFirmwarePackageFilename = extractFirmwareVersionFromFirmwarePackageFilename;
|
|
217
218
|
/**
|
|
218
219
|
* Older firmware versions for Circulo included a different build to support the Encoder Calibration feature in order to save memory.
|
|
219
220
|
* Newer firmware versions now include the Encoder Calibration feature, so a separate build is no longer necessary.
|
|
220
221
|
*
|
|
221
222
|
* @example
|
|
222
223
|
* "package_SOMANET-Servo-Node-Circulo-7-700_8502-01_motion-drive_v0.4.3-calibration.zip"
|
|
224
|
+
* "v0.4.3-calibration"
|
|
223
225
|
*/
|
|
224
|
-
function
|
|
226
|
+
function isCalibrationFirmware(version) {
|
|
225
227
|
var _a;
|
|
226
|
-
return (_a = version.includes('calibration')) !== null && _a !== void 0 ? _a : false;
|
|
228
|
+
return (_a = version === null || version === void 0 ? void 0 : version.includes('calibration')) !== null && _a !== void 0 ? _a : false;
|
|
227
229
|
}
|
|
228
|
-
exports.
|
|
230
|
+
exports.isCalibrationFirmware = isCalibrationFirmware;
|
|
231
|
+
/**
|
|
232
|
+
* Some older firmware versions included invalid build metadata.
|
|
233
|
+
* This function removes any invalid metadata from the provided version.
|
|
234
|
+
*/
|
|
235
|
+
function removeInvalidBuildMetadataFromFirmwareVersion(version) {
|
|
236
|
+
return version.replace(/-\d+-[A-Za-z0-9]+$/, '');
|
|
237
|
+
}
|
|
238
|
+
exports.removeInvalidBuildMetadataFromFirmwareVersion = removeInvalidBuildMetadataFromFirmwareVersion;
|
|
239
|
+
/**
|
|
240
|
+
* Checks if a firmware version satisfies the given range.
|
|
241
|
+
* If no options are specified, a custom one will be used.
|
|
242
|
+
* Older firmware versions sometimes included invalid build metadata, which could cause the function to fail.
|
|
243
|
+
* To prevent this, the function removes any invalid build metadata before performing the version check.
|
|
244
|
+
*/
|
|
245
|
+
function firmwareVersionSatisfies(version, range, options = { includePrerelease: true, loose: true }) {
|
|
246
|
+
version = removeInvalidBuildMetadataFromFirmwareVersion(version);
|
|
247
|
+
return (0, semver_1.satisfies)(version, range, options);
|
|
248
|
+
}
|
|
249
|
+
exports.firmwareVersionSatisfies = firmwareVersionSatisfies;
|
|
250
|
+
/**
|
|
251
|
+
* Determines if a firmware version falls within a specified range.
|
|
252
|
+
*
|
|
253
|
+
* @param version The firmware version to check.
|
|
254
|
+
* @param range A version range, following the syntax outlined in {@link https://github.com/npm/node-semver#ranges}.
|
|
255
|
+
* @param calibration If a string, it will be treated as a range. Otherwise, the function returns the boolean value of `calibration`.
|
|
256
|
+
*/
|
|
257
|
+
function isFirmwareVersionInRange(version, range, calibration) {
|
|
258
|
+
let result = false;
|
|
259
|
+
if (isCalibrationFirmware(version)) {
|
|
260
|
+
result = typeof calibration === 'string'
|
|
261
|
+
? firmwareVersionSatisfies(version, calibration)
|
|
262
|
+
: calibration !== null && calibration !== void 0 ? calibration : false;
|
|
263
|
+
}
|
|
264
|
+
else if (range) {
|
|
265
|
+
result = firmwareVersionSatisfies(version, range);
|
|
266
|
+
}
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
exports.isFirmwareVersionInRange = isFirmwareVersionInRange;
|
|
270
|
+
/**
|
|
271
|
+
* Checks if the provided firmware version includes the new encoder configuration objects (0x2110 and 0x2112).
|
|
272
|
+
* Firmware versions starting from v5.0.0-rc.5 and v0.4.0-calibration include these objects.
|
|
273
|
+
*
|
|
274
|
+
* Previously, firmware had separate objects for each type of encoder (sensor), resulting in more than 12 record objects,
|
|
275
|
+
* each with several subitems. This consumed unnecessary memory, prompting a refactor to introduce the new encoder configuration objects.
|
|
276
|
+
*
|
|
277
|
+
* The new configuration is referred to as "encoder configuration" (0x2110, 0x2112), while the older is called "sensor configuration".
|
|
278
|
+
*/
|
|
279
|
+
function isEncoderConfigurationFirmware(version) {
|
|
280
|
+
if (!version) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
if (isCalibrationFirmware(version)) {
|
|
284
|
+
return firmwareVersionSatisfies(version, '>=v0.4.0-calibration');
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
return firmwareVersionSatisfies(version, '>=v5.0.0-rc.5');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
exports.isEncoderConfigurationFirmware = isEncoderConfigurationFirmware;
|
|
229
291
|
//# sourceMappingURL=firmware.js.map
|
package/src/lib/firmware.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firmware.js","sourceRoot":"","sources":["../../../../../libs/motion-master-client/src/lib/firmware.ts"],"names":[],"mappings":";;;AAAA,iEAAsJ;AACtJ,uDAA8E;
|
|
1
|
+
{"version":3,"file":"firmware.js","sourceRoot":"","sources":["../../../../../libs/motion-master-client/src/lib/firmware.ts"],"names":[],"mappings":"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"}
|