motion-master-client 0.0.363 → 0.0.367

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.
@@ -30,6 +30,7 @@ const circulo_1 = require("./circulo");
30
30
  const encoder_1 = require("./encoder");
31
31
  const pdo_1 = require("./pdo");
32
32
  const integro_1 = require("./integro");
33
+ const offset_detection_1 = require("./offset-detection");
33
34
  const { xmlToEsi } = require('ecatmod');
34
35
  /**
35
36
  * This class contains methods for making requests to Motion Master using the injected request/response socket.
@@ -1199,6 +1200,14 @@ class MotionMasterReqResClient {
1199
1200
  this.socket.send(message);
1200
1201
  return id;
1201
1202
  }
1203
+ /**
1204
+ * Get device SII.
1205
+ */
1206
+ getDeviceSii(props, requestTimeout, messageId) {
1207
+ const getDeviceSii = types_1.MotionMasterMessage.Request.GetDeviceSii.create(props);
1208
+ const id = this.sendRequest({ getDeviceSii }, messageId);
1209
+ return this.socket.message$.pipe((0, operators_2.transformMotionMasterMessageToStatus)('deviceSii', requestTimeout, id));
1210
+ }
1202
1211
  //
1203
1212
  // Helpers
1204
1213
  //
@@ -2747,7 +2756,24 @@ class MotionMasterReqResClient {
2747
2756
  * @todo Document this method and consider removing the void return type.
2748
2757
  */
2749
2758
  runPhaseResistanceMeasurement(deviceRef) {
2750
- return (0, rxjs_1.concat)(this.setModesOfOperation(deviceRef, cia402_1.ModesOfOperation.DIAGNOSTICS_MODE), this.transitionToCia402State(deviceRef, cia402_1.Cia402State.OPERATION_ENABLED), this.runPhaseResistanceMeasurementOsCommand(deviceRef));
2759
+ return (0, rxjs_1.concat)(this.setModesOfOperationAndTransitionToCia402State(deviceRef, cia402_1.ModesOfOperation.DIAGNOSTICS_MODE, cia402_1.Cia402State.OPERATION_ENABLED), this.runPhaseResistanceMeasurementOsCommand(deviceRef));
2760
+ }
2761
+ /**
2762
+ * Sets the device mode of operation and then transitions the device
2763
+ * to the specified CiA 402 state.
2764
+ *
2765
+ * The operations are executed sequentially:
2766
+ * 1. The mode of operation is written to the device.
2767
+ * 2. The device is transitioned to the requested CiA 402 state.
2768
+ *
2769
+ * @param deviceRef - Reference to the target device.
2770
+ * @param modesOfOperation - Desired CiA 402 mode of operation.
2771
+ * @param cia402State - Target CiA 402 state to transition to.
2772
+ *
2773
+ * @returns Observable that completes when both operations finish.
2774
+ */
2775
+ setModesOfOperationAndTransitionToCia402State(deviceRef, modesOfOperation, cia402State) {
2776
+ return (0, rxjs_1.concat)(this.setModesOfOperation(deviceRef, modesOfOperation), this.transitionToCia402State(deviceRef, cia402State));
2751
2777
  }
2752
2778
  /**
2753
2779
  * Installs the Integro Encoder Firmware by performing the following steps:
@@ -2772,7 +2798,7 @@ class MotionMasterReqResClient {
2772
2798
  /**
2773
2799
  * @link https://www.wrike.com/open.htm?id=1375749957
2774
2800
  *
2775
- * @todo: Verify if the device is an Actilink S device and check the corresponding variant file.
2801
+ * @todo: Verify if the device is an ACTILINK-S device and check the corresponding variant file.
2776
2802
  */
2777
2803
  isIntegroWithMultiturnEncoder(deviceRef) {
2778
2804
  var _a;
@@ -2808,10 +2834,10 @@ class MotionMasterReqResClient {
2808
2834
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
2809
2835
  // Create a default UI features configuration object.
2810
2836
  const uiFeaturesConfig = { setupWizard: 'default' };
2811
- // Check if the device is an Actilink S device.
2812
- // If the device is an Actilink S device, the setup wizard should be set to 'actilink'.
2837
+ // Check if the device is an ACTILINK-S device.
2838
+ // If the device is an ACTILINK-S device, the setup wizard should be set to 'actilink'.
2813
2839
  const hardwareDescription = yield (0, rxjs_1.lastValueFrom)(this.getHardwareDescription(deviceRef));
2814
- if ((hardwareDescription === null || hardwareDescription === void 0 ? void 0 : hardwareDescription.assembly) && (0, product_1.isSomanetProductIdInRange)((_a = hardwareDescription.assembly) === null || _a === void 0 ? void 0 : _a.id, 'Actilink S')) {
2840
+ if ((hardwareDescription === null || hardwareDescription === void 0 ? void 0 : hardwareDescription.assembly) && (0, product_1.isSomanetProductIdInRange)((_a = hardwareDescription.assembly) === null || _a === void 0 ? void 0 : _a.id, 'ACTILINK-S')) {
2815
2841
  uiFeaturesConfig.setupWizard = 'actilink';
2816
2842
  }
2817
2843
  // Read the parameters from the assembly configuration file.
@@ -4276,6 +4302,201 @@ class MotionMasterReqResClient {
4276
4302
  getUiConfigOrDefaultPdoMapping(deviceRef) {
4277
4303
  return this.getUiConfig(deviceRef).pipe((0, operators_1.map)((uiConfig) => { var _a; return (_a = uiConfig.pdoMapping) !== null && _a !== void 0 ? _a : device_parameter_1.uiConfigWithDefaultPdoMapping.pdoMapping; }));
4278
4304
  }
4305
+ /**
4306
+ * Runs the offset detection procedure for the given device and emits step-wise progress updates.
4307
+ *
4308
+ * The procedure executes a sequence of diagnostic steps sequentially and reports their state
4309
+ * (`idle`, `running`, `succeeded`, `failed`) via an observable stream.
4310
+ *
4311
+ * Behavior
4312
+ * - If `stepIds` is provided, only those steps are executed (in order).
4313
+ * - If `stepIds` is empty, all available offset detection steps are executed.
4314
+ * - Automatically inserts `motorPhaseOrderDetection` if required by
4315
+ * `commutationOffsetMeasurement`.
4316
+ * - Transitions the device into diagnostics mode and ensures it is in
4317
+ * `OPERATION ENABLED` state before executing steps.
4318
+ * - Restores the brake state and transitions the device to
4319
+ * `SWITCH_ON_DISABLED` after completion, error, or cancellation.
4320
+ *
4321
+ * Cancellation
4322
+ * - Unsubscribing from the returned observable cancels further step execution.
4323
+ * - Cancellation stops the sequence cooperatively (in-progress async operations may still complete).
4324
+ * - Cancellation is treated as an error internally.
4325
+ *
4326
+ * Error Handling
4327
+ * - Emits an error if the device is not in the required CIA402 state.
4328
+ * - Emits an error if any step fails.
4329
+ * - Emits an error if step dependencies are violated.
4330
+ * - Cleanup operations (brake restore and state transition) are always attempted in `finally`.
4331
+ *
4332
+ * @param deviceRef - Reference to the target device.
4333
+ * @param stepIds - Optional list of step IDs to execute. If omitted or empty, all steps are executed.
4334
+ * @returns An observable that emits the progress and final state of each offset detection step.
4335
+ *
4336
+ * @remarks
4337
+ * Each emission contains a cloned snapshot of all steps to allow safe external consumption
4338
+ * without mutation side effects.
4339
+ */
4340
+ runOffsetDetection(deviceRef, stepIds = []) {
4341
+ // Mapping of step IDs to their corresponding execution functions and result value keys
4342
+ const stepCommand = {
4343
+ openPhaseDetection: { execute: () => this.runOpenPhaseDetectionOsCommand(deviceRef), valueKey: 'phaseOpened' },
4344
+ phaseResistanceMeasurement: {
4345
+ execute: () => this.runPhaseResistanceMeasurementOsCommand(deviceRef),
4346
+ valueKey: 'phaseResistance',
4347
+ },
4348
+ phaseInductanceMeasurement: {
4349
+ execute: () => this.runPhaseInductanceMeasurementOsCommand(deviceRef),
4350
+ valueKey: 'phaseInductance',
4351
+ },
4352
+ polePairDetection: {
4353
+ execute: () => this.runPolePairDetectionOsCommand(deviceRef),
4354
+ valueKey: 'numberOfPolePairs',
4355
+ },
4356
+ motorPhaseOrderDetection: {
4357
+ execute: () => this.runMotorPhaseOrderDetectionOsCommand(deviceRef),
4358
+ valueKey: 'motorPhaseOrder',
4359
+ },
4360
+ commutationOffsetMeasurement: {
4361
+ execute: () => this.runCommutationOffsetMeasurementOsCommand(deviceRef),
4362
+ valueKey: 'commutationAngleOffset',
4363
+ },
4364
+ };
4365
+ return new rxjs_1.Observable((subscriber) => {
4366
+ let isCancelled = false;
4367
+ // Brake-related state restored in finally block
4368
+ let brakeReleaseStrategy = 0;
4369
+ let brakeStatusInit = 0;
4370
+ let brakePullTime = 0;
4371
+ // Throws if cancellation was requested
4372
+ const checkCancelled = () => {
4373
+ if (isCancelled) {
4374
+ throw new Error('Offset detection procedure was cancelled.');
4375
+ }
4376
+ };
4377
+ const runInternal = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
4378
+ // Determine active steps (either provided subset or all steps)
4379
+ let activeStepIds = stepIds.length > 0 ? [...stepIds] : offset_detection_1.offsetDetectionSteps.map((s) => s.id);
4380
+ // Ensure motor phase order detection is included if required by commutation step
4381
+ const needsMotorPhaseOrderDetection = activeStepIds.includes('commutationOffsetMeasurement');
4382
+ const hasMotorPhaseOrderDetection = activeStepIds.includes('motorPhaseOrderDetection');
4383
+ if (needsMotorPhaseOrderDetection && !hasMotorPhaseOrderDetection) {
4384
+ const idx = activeStepIds.indexOf('commutationOffsetMeasurement');
4385
+ activeStepIds.splice(idx, 0, 'motorPhaseOrderDetection');
4386
+ }
4387
+ // Initial step snapshot with all steps in 'idle' state
4388
+ const steps = structuredClone(offset_detection_1.offsetDetectionSteps);
4389
+ if (!isCancelled) {
4390
+ subscriber.next(steps);
4391
+ }
4392
+ try {
4393
+ // Read brake configuration from device
4394
+ [brakeReleaseStrategy, brakeStatusInit, brakePullTime] = (yield this.uploadMany([
4395
+ [deviceRef, 0x2004, 4],
4396
+ [deviceRef, 0x2004, 7],
4397
+ [deviceRef, 0x2004, 3],
4398
+ ]));
4399
+ checkCancelled();
4400
+ // Temporarily release brake if required
4401
+ if (brakeReleaseStrategy > 0) {
4402
+ yield this.download(deviceRef, 0x2004, 7, 2);
4403
+ yield (0, util_1.resolveAfter)(brakePullTime + 500);
4404
+ }
4405
+ checkCancelled();
4406
+ // Switch device into diagnostics mode and ensure OPERATION ENABLED state
4407
+ yield (0, rxjs_1.lastValueFrom)(this.setModesOfOperationAndTransitionToCia402State(deviceRef, cia402_1.ModesOfOperation.DIAGNOSTICS_MODE, cia402_1.Cia402State.OPERATION_ENABLED));
4408
+ // Execute each selected diagnostic step sequentially and emit progress updates
4409
+ for (const id of activeStepIds) {
4410
+ checkCancelled();
4411
+ // Verify device state before each step to ensure it is still in OPERATION ENABLED
4412
+ const cia402state = yield (0, rxjs_1.lastValueFrom)(this.getCia402State(deviceRef));
4413
+ if (cia402state !== cia402_1.Cia402State.OPERATION_ENABLED) {
4414
+ subscriber.error(new Error('Device is not in the expected state for running diagnostics. Please ensure the device is in OPERATION ENABLED state.'));
4415
+ return;
4416
+ }
4417
+ checkCancelled();
4418
+ const step = steps.find((s) => s.id === id);
4419
+ const command = stepCommand[id];
4420
+ // Validate configuration consistency
4421
+ if (!step || !command) {
4422
+ throw new Error(`Invalid diagnostic configuration for: "${id}"`);
4423
+ }
4424
+ // Mark step as running and emit progress
4425
+ step.status = 'running';
4426
+ subscriber.next(structuredClone(steps));
4427
+ // Execute diagnostic command
4428
+ const response = yield (0, rxjs_1.lastValueFrom)(command.execute());
4429
+ checkCancelled();
4430
+ if (response.request === 'succeeded') {
4431
+ // Mark success and store result value
4432
+ step.status = 'succeeded';
4433
+ step.value = response[command.valueKey];
4434
+ }
4435
+ else {
4436
+ // Mark failure and store error details
4437
+ step.status = 'failed';
4438
+ step.error = `${response.errorCode}: ${response.errorDescription} (${response.errorName})`;
4439
+ // Special validation: enforce dependency between steps
4440
+ const nextStepId = activeStepIds[activeStepIds.indexOf(id) + 1];
4441
+ if (id === 'motorPhaseOrderDetection' && nextStepId === 'commutationOffsetMeasurement') {
4442
+ subscriber.next(structuredClone(steps));
4443
+ subscriber.error(new Error('Commutation Offset Measurement cannot be performed until Motor Phase Order Detection has successfully completed.'));
4444
+ return;
4445
+ }
4446
+ }
4447
+ // Emit updated progress after each step
4448
+ if (!isCancelled) {
4449
+ subscriber.next(structuredClone(steps));
4450
+ }
4451
+ }
4452
+ // Complete observable if not cancelled
4453
+ if (!isCancelled) {
4454
+ subscriber.complete();
4455
+ }
4456
+ }
4457
+ catch (error) {
4458
+ // Emit error unless cancellation occurred
4459
+ if (!isCancelled) {
4460
+ // Mark all running steps as failed on error
4461
+ steps.forEach((s) => {
4462
+ if (s.status === 'running') {
4463
+ s.status = 'failed';
4464
+ }
4465
+ });
4466
+ // Emit final step states before error
4467
+ subscriber.next(structuredClone(steps));
4468
+ subscriber.error(error instanceof Error ? error : new Error(String(error)));
4469
+ }
4470
+ else {
4471
+ console.warn('Offset detection procedure was cancelled.');
4472
+ }
4473
+ }
4474
+ finally {
4475
+ // Always restore brake state if it was modified
4476
+ if (brakeReleaseStrategy > 0) {
4477
+ try {
4478
+ yield this.download(deviceRef, 0x2004, 7, brakeStatusInit);
4479
+ }
4480
+ catch (error) {
4481
+ console.error(`Failed to restore brake state (${brakeStatusInit}) after offset detection procedure: ${error instanceof Error ? error.message : String(error)}`);
4482
+ }
4483
+ }
4484
+ // Always attempt to return device to a safe state
4485
+ try {
4486
+ yield this.transitionToCia402State(deviceRef, cia402_1.Cia402State.SWITCH_ON_DISABLED);
4487
+ }
4488
+ catch (error) {
4489
+ console.error(`Failed to transition device to Switch on Disabled state after offset detection procedure: ${error instanceof Error ? error.message : String(error)}`);
4490
+ }
4491
+ }
4492
+ });
4493
+ runInternal();
4494
+ // Cancellation handler from observable unsubscribe
4495
+ return () => {
4496
+ isCancelled = true;
4497
+ };
4498
+ });
4499
+ }
4279
4500
  }
4280
4501
  exports.MotionMasterReqResClient = MotionMasterReqResClient;
4281
4502
  /**