@enyo-energy/sunspec-sdk 0.0.73 → 0.0.75

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.
@@ -705,8 +705,6 @@ export class SunspecInverter extends BaseSunspecDevice {
705
705
  this.dataBus = this.energyApp.useDataBus();
706
706
  this.dataBusListenerId = this.dataBus.listenForMessages([
707
707
  EnyoDataBusMessageEnum.SetInverterFeedInLimitV1,
708
- EnyoDataBusMessageEnum.StartCalibrationV1,
709
- EnyoDataBusMessageEnum.StopCalibrationV1,
710
708
  ], (entry) => this.handleInverterCommand(entry));
711
709
  console.log(`Inverter ${this.applianceId}: started data bus listening (listener ${this.dataBusListenerId})`);
712
710
  }
@@ -731,12 +729,6 @@ export class SunspecInverter extends BaseSunspecDevice {
731
729
  case EnyoDataBusMessageEnum.SetInverterFeedInLimitV1:
732
730
  await this.handleSetFeedInLimit(entry);
733
731
  break;
734
- case EnyoDataBusMessageEnum.StartCalibrationV1:
735
- await this.handleStartCalibration(entry);
736
- break;
737
- case EnyoDataBusMessageEnum.StopCalibrationV1:
738
- await this.handleStopCalibration(entry);
739
- break;
740
732
  }
741
733
  }
742
734
  catch (error) {
@@ -782,51 +774,6 @@ export class SunspecInverter extends BaseSunspecDevice {
782
774
  await this.snapshotService.initialize();
783
775
  console.log(`Inverter ${this.applianceId}: snapshot service initialized`);
784
776
  }
785
- async handleStartCalibration(msg) {
786
- if (!this.isConnected() || !this.applianceId) {
787
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Rejected, 'Not connected');
788
- return;
789
- }
790
- if (!this.snapshotService) {
791
- await this.initSnapshotService();
792
- }
793
- if (!this.snapshotService) {
794
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Rejected, 'Snapshot service unavailable');
795
- return;
796
- }
797
- if (this.snapshotService.isCalibrating()) {
798
- console.log(`Inverter ${this.applianceId}: calibration already active — ack idempotently`);
799
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Accepted);
800
- return;
801
- }
802
- console.log(`Inverter ${this.applianceId}: handling StartCalibrationV1`);
803
- const controls = await this.sunspecClient.readInverterControls(this.unitId);
804
- if (!controls) {
805
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Rejected, 'Failed to read inverter controls for snapshot');
806
- return;
807
- }
808
- try {
809
- await this.snapshotService.startCalibration(controls);
810
- }
811
- catch (error) {
812
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Rejected, `Failed to persist snapshot: ${error}`);
813
- return;
814
- }
815
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Accepted);
816
- }
817
- async handleStopCalibration(msg) {
818
- if (!this.applianceId) {
819
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Rejected, 'Not initialized');
820
- return;
821
- }
822
- console.log(`Inverter ${this.applianceId}: handling StopCalibrationV1`);
823
- // SnapshotService.stopCalibration fires `restoreInverterSnapshot` internally with
824
- // reason="stop" before returning. Any restore failure is logged by the callback
825
- // (the persisted snapshot is already gone by then — see library notes) so we
826
- // always ack Accepted from here.
827
- await this.snapshotService?.stopCalibration();
828
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Accepted);
829
- }
830
777
  /**
831
778
  * `onRestore` callback for the inverter's {@link SnapshotService}. Writes only the
832
779
  * subset of writable inverter fields that other commands actually touched during the
@@ -1364,7 +1311,10 @@ export class SunspecBattery extends BaseSunspecDevice {
1364
1311
  console.error('Battery not connected');
1365
1312
  return false;
1366
1313
  }
1367
- console.log('Writing battery controls:', controls);
1314
+ // Redundant with the modbus client's own per-write debug trace. Keep at debug
1315
+ // so the high-level info logs (setStorageMode / enableGridCharging / etc.) stay
1316
+ // the only info-level signal per battery-control action.
1317
+ console.debug('Writing battery controls:', controls);
1368
1318
  return this.sunspecClient.writeBatteryControls(this.unitId, controls);
1369
1319
  }
1370
1320
  mapToEnyoStorageMode(storageMode) {
@@ -1462,8 +1412,6 @@ export class SunspecBattery extends BaseSunspecDevice {
1462
1412
  this.dataBus = this.energyApp.useDataBus();
1463
1413
  this.dataBusListenerId = this.dataBus.listenForMessages([
1464
1414
  EnyoDataBusMessageEnum.SetStorageScheduleV1,
1465
- EnyoDataBusMessageEnum.StartCalibrationV1,
1466
- EnyoDataBusMessageEnum.StopCalibrationV1,
1467
1415
  ], (entry) => this.handleStorageCommand(entry));
1468
1416
  if (!this.applianceId) {
1469
1417
  throw new Error("SunspecBattery.startDataBusListening: applianceId required — call connect() first.");
@@ -1502,12 +1450,6 @@ export class SunspecBattery extends BaseSunspecDevice {
1502
1450
  case EnyoDataBusMessageEnum.SetStorageScheduleV1:
1503
1451
  this.handleSetStorageScheduleAck(entry);
1504
1452
  break;
1505
- case EnyoDataBusMessageEnum.StartCalibrationV1:
1506
- await this.handleStartCalibration(entry);
1507
- break;
1508
- case EnyoDataBusMessageEnum.StopCalibrationV1:
1509
- await this.handleStopCalibration(entry);
1510
- break;
1511
1453
  }
1512
1454
  }
1513
1455
  catch (error) {
@@ -1547,51 +1489,6 @@ export class SunspecBattery extends BaseSunspecDevice {
1547
1489
  await this.snapshotService.initialize();
1548
1490
  console.log(`Battery ${this.applianceId}: snapshot service initialized`);
1549
1491
  }
1550
- async handleStartCalibration(msg) {
1551
- if (!this.isConnected() || !this.applianceId) {
1552
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Rejected, 'Not connected');
1553
- return;
1554
- }
1555
- if (!this.snapshotService) {
1556
- await this.initSnapshotService();
1557
- }
1558
- if (!this.snapshotService) {
1559
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Rejected, 'Snapshot service unavailable');
1560
- return;
1561
- }
1562
- if (this.snapshotService.isCalibrating()) {
1563
- console.log(`Battery ${this.applianceId}: calibration already active — ack idempotently`);
1564
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Accepted);
1565
- return;
1566
- }
1567
- console.log(`Battery ${this.applianceId}: handling StartCalibrationV1`);
1568
- const controls = await this.sunspecClient.readBatteryControls(this.unitId);
1569
- if (!controls) {
1570
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Rejected, 'Failed to read battery controls for snapshot');
1571
- return;
1572
- }
1573
- try {
1574
- await this.snapshotService.startCalibration(controls);
1575
- }
1576
- catch (error) {
1577
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Rejected, `Failed to persist snapshot: ${error}`);
1578
- return;
1579
- }
1580
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Accepted);
1581
- }
1582
- async handleStopCalibration(msg) {
1583
- if (!this.applianceId) {
1584
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Rejected, 'Not initialized');
1585
- return;
1586
- }
1587
- console.log(`Battery ${this.applianceId}: handling StopCalibrationV1`);
1588
- // SnapshotService.stopCalibration fires `restoreBatterySnapshot` internally
1589
- // with reason="stop" before returning. Failures from the restore callback are
1590
- // logged inside the callback (the persisted snapshot is already gone — see
1591
- // library notes) so we always ack Accepted here.
1592
- await this.snapshotService?.stopCalibration();
1593
- this.sendCommandAcknowledge(msg.id, msg.message, EnyoCommandAcknowledgeAnswerEnum.Accepted);
1594
- }
1595
1492
  /**
1596
1493
  * `onRestore` callback for the battery's {@link SnapshotService}. Writes only the
1597
1494
  * subset of writable battery fields touched during the calibration. Errors are
@@ -1696,13 +1593,11 @@ export class SunspecMeter extends BaseSunspecDevice {
1696
1593
  console.error(`Failed to update meter appliance: ${error}`);
1697
1594
  }
1698
1595
  }
1699
- this.startDataBusListening();
1700
1596
  }
1701
1597
  /**
1702
1598
  * Disconnect from the meter and update appliance state
1703
1599
  */
1704
1600
  async disconnect() {
1705
- this.stopDataBusListening();
1706
1601
  if (this.applianceId) {
1707
1602
  try {
1708
1603
  await this.applianceManager.updateApplianceState(this.applianceId, EnyoApplianceConnectionType.Connector, EnyoApplianceStateEnum.Offline);
@@ -1714,35 +1609,6 @@ export class SunspecMeter extends BaseSunspecDevice {
1714
1609
  // Close just this meter's unit; other devices on the same network device stay open.
1715
1610
  await this.sunspecClient.disconnectUnit(this.unitId);
1716
1611
  }
1717
- /**
1718
- * Meter does not implement calibration; it only subscribes to Start/StopCalibrationV1 to
1719
- * answer NotSupported (per the data-bus contract that every command must be acknowledged).
1720
- */
1721
- startDataBusListening() {
1722
- if (this.dataBusListenerId) {
1723
- return;
1724
- }
1725
- this.dataBus = this.energyApp.useDataBus();
1726
- this.dataBusListenerId = this.dataBus.listenForMessages([
1727
- EnyoDataBusMessageEnum.StartCalibrationV1,
1728
- EnyoDataBusMessageEnum.StopCalibrationV1,
1729
- ], (entry) => this.handleMeterCommand(entry));
1730
- console.log(`Meter ${this.applianceId}: started data bus listening (listener ${this.dataBusListenerId})`);
1731
- }
1732
- stopDataBusListening() {
1733
- if (this.dataBusListenerId && this.dataBus) {
1734
- this.dataBus.unsubscribe(this.dataBusListenerId);
1735
- console.log(`Meter ${this.applianceId}: stopped data bus listening (listener ${this.dataBusListenerId})`);
1736
- }
1737
- this.dataBusListenerId = undefined;
1738
- this.dataBus = undefined;
1739
- }
1740
- handleMeterCommand(entry) {
1741
- if (entry.applianceId !== this.applianceId) {
1742
- return;
1743
- }
1744
- this.sendCommandAcknowledge(entry.id, entry.message, EnyoCommandAcknowledgeAnswerEnum.NotSupported, 'Meter does not support calibration');
1745
- }
1746
1612
  /**
1747
1613
  * Update meter data and return data bus messages
1748
1614
  */
@@ -481,7 +481,10 @@ export class SunspecModbusClient {
481
481
  }
482
482
  catch (error) {
483
483
  console.debug(`No SunSpec device at unit ${unitId}: ${error}`);
484
- console.log(`Discovery complete for unit ${unitId}. Found 0 models: []`);
484
+ // Discovery summary at line 594 below is the info-level outcome.
485
+ // This 0-models branch is the same outcome as a normal "no device found",
486
+ // covered already by the debug above. Keep at debug.
487
+ console.debug(`Discovery complete for unit ${unitId}. Found 0 models: []`);
485
488
  return models;
486
489
  }
487
490
  currentAddress = addressInfo.nextAddress;
@@ -490,14 +493,14 @@ export class SunspecModbusClient {
490
493
  const buffer = await instance.readHoldingRegisters(currentAddress, 2);
491
494
  const modelData = [buffer.readUInt16BE(0), buffer.readUInt16BE(2)];
492
495
  if (!modelData || modelData.length < 2) {
493
- console.log(`No data at address ${currentAddress}, ending discovery`);
496
+ console.debug(`No data at address ${currentAddress}, ending discovery`);
494
497
  break;
495
498
  }
496
499
  const modelId = modelData[0];
497
500
  const modelLength = modelData[1];
498
501
  // Check for end marker
499
502
  if (modelId === 0xFFFF || modelId === 65535) {
500
- console.log(`Found end marker at address ${currentAddress}`);
503
+ console.debug(`Found end marker at address ${currentAddress}`);
501
504
  break;
502
505
  }
503
506
  // Store discovered model
@@ -507,7 +510,9 @@ export class SunspecModbusClient {
507
510
  length: modelLength
508
511
  };
509
512
  models.set(modelId, model);
510
- console.log(`Discovered Model ${modelId} at address ${currentAddress} with length ${modelLength} (unit ${unitId})`);
513
+ // Per-model discovery step. The end-of-discovery summary below is the
514
+ // info-level outcome; the per-model walk is debug-only.
515
+ console.debug(`Discovered Model ${modelId} at address ${currentAddress} with length ${modelLength} (unit ${unitId})`);
511
516
  // Jump to next model: current address + 2 (header) + model length
512
517
  currentAddress = currentAddress + 2 + modelLength;
513
518
  }
@@ -696,7 +701,9 @@ export class SunspecModbusClient {
696
701
  // Write to holding registers
697
702
  await instance.writeMultipleRegisters(address, registerValues);
698
703
  this.connectionHealth.recordSuccess();
699
- console.log(`Successfully wrote value ${value} to register ${address} (unit ${unitId})`);
704
+ // Per-register write success fires for every parameter inside higher-level
705
+ // writers (writeBatteryControls / writeInverterControls). Demoted to debug.
706
+ console.debug(`Successfully wrote value ${value} to register ${address} (unit ${unitId})`);
700
707
  return true;
701
708
  }
702
709
  catch (error) {
@@ -1594,7 +1601,10 @@ export class SunspecModbusClient {
1594
1601
  data.dischargePower = Math.abs((data.outWRte / 100) * data.wChaMax);
1595
1602
  console.debug(`Calculated Discharge Power (inWRte: ${data.outWRte}, wChaMax: ${data.wChaMax}): ${data.dischargePower?.toFixed(2)} W`);
1596
1603
  }
1597
- console.debug('[Model 124] Battery Data:', data);
1604
+ // Single-line JSON debug dump Node's default formatter would split
1605
+ // the object across many lines; stringify keeps the whole snapshot
1606
+ // on one log entry so it stays grep-able and round-trippable.
1607
+ console.debug(`[Battery] unit=${unitId} model=124 data=${JSON.stringify(data)}`);
1598
1608
  return data;
1599
1609
  }
1600
1610
  else if (model.id === 802) {
@@ -1631,17 +1641,18 @@ export class SunspecModbusClient {
1631
1641
  chargePower,
1632
1642
  dischargePower,
1633
1643
  };
1634
- console.debug('[Model 802] Battery Data:', result);
1644
+ console.debug(`[Battery] unit=${unitId} model=802 data=${JSON.stringify(result)}`);
1635
1645
  return result;
1636
1646
  }
1637
1647
  else {
1638
- // Handle other battery models (803) if needed
1639
- console.debug(`Battery Model ${model.id} reading not yet implemented`);
1640
- return {
1648
+ // Handle other battery models (803) if needed.
1649
+ const stub = {
1641
1650
  blockNumber: model.id,
1642
1651
  blockAddress: model.address,
1643
- blockLength: model.length
1652
+ blockLength: model.length,
1644
1653
  };
1654
+ console.debug(`[Battery] unit=${unitId} model=${model.id} (not yet implemented) data=${JSON.stringify(stub)}`);
1655
+ return stub;
1645
1656
  }
1646
1657
  }
1647
1658
  catch (error) {
@@ -1659,17 +1670,21 @@ export class SunspecModbusClient {
1659
1670
  return false;
1660
1671
  }
1661
1672
  const baseAddr = model.address;
1662
- console.log(`Writing Battery Controls to Model 124 at base address: ${baseAddr} (unit ${unitId})`);
1673
+ // Per-register write trace is high-volume (every schedule entry transition fires
1674
+ // a writeBatteryControls). Demoted to debug; consumers that need the trail can
1675
+ // raise their log level. High-level callers (setStorageMode, enableGridCharging,
1676
+ // setFeedInLimit, etc.) still emit one info-level line per action.
1677
+ console.debug(`Writing Battery Controls to Model 124 at base address: ${baseAddr} (unit ${unitId})`);
1663
1678
  try {
1664
- // Write storage control mode (Register 5)
1665
- if (controls.storCtlMod !== undefined) {
1666
- await this.writeRegisterValue(unitId, baseAddr + 5, controls.storCtlMod, 'uint16');
1667
- console.log(`Set storage control mode to 0x${controls.storCtlMod.toString(16)}`);
1668
- }
1679
+ // Write order: source pin and parameter writes land BEFORE the
1680
+ // control mode so the device only "starts acting" once every
1681
+ // value that governs the action is fresh. The reverse order
1682
+ // leaks a Modbus RTT-sized window where storCtlMod sees stale
1683
+ // chaGriSet / wChaMax / inWRte / outWRte.
1669
1684
  // Write charge source setting (Register 17)
1670
1685
  if (controls.chaGriSet !== undefined) {
1671
1686
  await this.writeRegisterValue(unitId, baseAddr + 17, controls.chaGriSet, 'uint16');
1672
- console.log(`Set charge source to ${controls.chaGriSet === SunspecChargeSource.GRID ? 'GRID' : 'PV'}`);
1687
+ console.debug(`Set charge source to ${controls.chaGriSet === SunspecChargeSource.GRID ? 'GRID' : 'PV'}`);
1673
1688
  }
1674
1689
  // Write maximum charge power (Register 2) - needs scale factor
1675
1690
  if (controls.wChaMax !== undefined) {
@@ -1677,7 +1692,7 @@ export class SunspecModbusClient {
1677
1692
  const scaleFactor = await this.readRegisterValue(unitId, scaleFactorAddr, 1, 'int16');
1678
1693
  const scaledValue = Math.round(controls.wChaMax / Math.pow(10, scaleFactor));
1679
1694
  await this.writeRegisterValue(unitId, baseAddr + 2, scaledValue, 'uint16');
1680
- console.log(`Set max charge power to ${controls.wChaMax}W (scaled: ${scaledValue})`);
1695
+ console.debug(`Set max charge power to ${controls.wChaMax}W (scaled: ${scaledValue})`);
1681
1696
  }
1682
1697
  // Write charge rate (Register 13) - needs scale factor
1683
1698
  if (controls.inWRte !== undefined) {
@@ -1685,7 +1700,7 @@ export class SunspecModbusClient {
1685
1700
  const scaleFactor = await this.readRegisterValue(unitId, scaleFactorAddr, 1, 'int16');
1686
1701
  const scaledValue = Math.round(controls.inWRte / Math.pow(10, scaleFactor));
1687
1702
  await this.writeRegisterValue(unitId, baseAddr + 13, scaledValue, 'int16');
1688
- console.log(`Set charge rate to ${controls.inWRte}% (scaled: ${scaledValue})`);
1703
+ console.debug(`Set charge rate to ${controls.inWRte}% (scaled: ${scaledValue})`);
1689
1704
  }
1690
1705
  // Write discharge rate (Register 12) - needs scale factor
1691
1706
  if (controls.outWRte !== undefined) {
@@ -1693,7 +1708,7 @@ export class SunspecModbusClient {
1693
1708
  const scaleFactor = await this.readRegisterValue(unitId, scaleFactorAddr, 1, 'int16');
1694
1709
  const scaledValue = Math.round(controls.outWRte / Math.pow(10, scaleFactor));
1695
1710
  await this.writeRegisterValue(unitId, baseAddr + 12, scaledValue, 'int16');
1696
- console.log(`Set discharge rate to ${controls.outWRte}% (scaled: ${scaledValue})`);
1711
+ console.debug(`Set discharge rate to ${controls.outWRte}% (scaled: ${scaledValue})`);
1697
1712
  }
1698
1713
  // Write minimum reserve percentage (Register 7) - needs scale factor
1699
1714
  if (controls.minRsvPct !== undefined) {
@@ -1701,9 +1716,16 @@ export class SunspecModbusClient {
1701
1716
  const scaleFactor = await this.readRegisterValue(unitId, scaleFactorAddr, 1, 'int16');
1702
1717
  const scaledValue = Math.round(controls.minRsvPct / Math.pow(10, scaleFactor));
1703
1718
  await this.writeRegisterValue(unitId, baseAddr + 7, scaledValue, 'uint16');
1704
- console.log(`Set minimum reserve to ${controls.minRsvPct}% (scaled: ${scaledValue})`);
1719
+ console.debug(`Set minimum reserve to ${controls.minRsvPct}% (scaled: ${scaledValue})`);
1720
+ }
1721
+ // Storage control mode (Register 5) — written LAST so all
1722
+ // governing parameters are already in place when the device
1723
+ // transitions into the new mode.
1724
+ if (controls.storCtlMod !== undefined) {
1725
+ await this.writeRegisterValue(unitId, baseAddr + 5, controls.storCtlMod, 'uint16');
1726
+ console.debug(`Set storage control mode to 0x${controls.storCtlMod.toString(16)}`);
1705
1727
  }
1706
- console.log('Battery controls written successfully');
1728
+ console.debug('Battery controls written successfully');
1707
1729
  return true;
1708
1730
  }
1709
1731
  catch (error) {
@@ -1754,10 +1776,12 @@ export class SunspecModbusClient {
1754
1776
  async readBatteryControls(unitId) {
1755
1777
  const model = this.findModel(unitId, SunspecModelId.Battery);
1756
1778
  if (!model) {
1757
- console.log(`Battery model 124 not found on unit ${unitId}`);
1779
+ // Fires per readBatteryControls attempt — noisy on non-battery units
1780
+ // that go through the same code path. Demoted to debug.
1781
+ console.debug(`Battery model 124 not found on unit ${unitId}`);
1758
1782
  return null;
1759
1783
  }
1760
- console.log(`Reading Battery Controls from Model 124 at base address: ${model.address} (unit ${unitId})`);
1784
+ console.debug(`Reading Battery Controls from Model 124 at base address: ${model.address} (unit ${unitId})`);
1761
1785
  try {
1762
1786
  // Read entire model block in a single Modbus call
1763
1787
  const buffer = await this.readModelBlock(unitId, model);
@@ -1972,7 +1996,7 @@ export class SunspecModbusClient {
1972
1996
  console.debug(`Common block model not found on unit ${unitId}`);
1973
1997
  return null;
1974
1998
  }
1975
- console.log(`Reading Common Block - Model address: ${model.address} (unit ${unitId})`);
1999
+ console.debug(`Reading Common Block - Model address: ${model.address} (unit ${unitId})`);
1976
2000
  try {
1977
2001
  // Read entire model block in a single Modbus call
1978
2002
  const buffer = await this.readModelBlock(unitId, model);
@@ -2132,7 +2156,8 @@ export class SunspecModbusClient {
2132
2156
  async readInverterControls(unitId) {
2133
2157
  const model = this.findModel(unitId, SunspecModelId.Controls);
2134
2158
  if (!model) {
2135
- console.log(`Controls model 123 not found on unit ${unitId}`);
2159
+ // Same trace-only rationale as the Model 124 not-found message above.
2160
+ console.debug(`Controls model 123 not found on unit ${unitId}`);
2136
2161
  return null;
2137
2162
  }
2138
2163
  try {
@@ -2241,17 +2266,17 @@ export class SunspecModbusClient {
2241
2266
  const scaleFactor = sfBuffer.readInt16BE(0);
2242
2267
  const scaledValue = Math.round(settings.WMax / Math.pow(10, scaleFactor));
2243
2268
  // Writing registers needs to be implemented in EnergyAppModbusInstance
2244
- // For now, log the write operation
2245
- console.log(`Would write value ${scaledValue} to register ${baseAddr}`);
2269
+ // For now, log the (would-be) write operation. Dry-run trace only — debug.
2270
+ console.debug(`Would write value ${scaledValue} to register ${baseAddr}`);
2246
2271
  }
2247
2272
  if (settings.VRef !== undefined) {
2248
2273
  const sfBuffer = await instance.readHoldingRegisters(baseAddr + 23, 1);
2249
2274
  const scaleFactor = sfBuffer.readInt16BE(0);
2250
2275
  const scaledValue = Math.round(settings.VRef / Math.pow(10, scaleFactor));
2251
- console.log(`Would write value ${scaledValue} to register ${baseAddr + 1}`);
2276
+ console.debug(`Would write value ${scaledValue} to register ${baseAddr + 1}`);
2252
2277
  }
2253
2278
  // Add more write operations for other settings as needed
2254
- console.log('Inverter settings written successfully');
2279
+ console.debug('Inverter settings written successfully');
2255
2280
  return true;
2256
2281
  }
2257
2282
  catch (error) {
@@ -2270,36 +2295,37 @@ export class SunspecModbusClient {
2270
2295
  }
2271
2296
  const baseAddr = model.address;
2272
2297
  try {
2273
- // Connection control (Register 2)
2298
+ // Per-field inverter-control writes are debug-only; the high-level callers
2299
+ // (`setFeedInLimit`, etc.) still log the action and outcome at info level.
2274
2300
  if (controls.Conn !== undefined) {
2275
2301
  await this.writeRegisterValue(unitId, baseAddr + 2, controls.Conn, 'uint16');
2276
- console.log(`Set connection control to ${controls.Conn}`);
2302
+ console.debug(`Set connection control to ${controls.Conn}`);
2277
2303
  }
2278
2304
  // Power limit control (Register 3) - needs scale factor
2279
2305
  if (controls.WMaxLimPct !== undefined) {
2280
2306
  const scaleFactor = await this.readRegisterValue(unitId, baseAddr + 21, 1, 'int16');
2281
2307
  const scaledValue = Math.round(controls.WMaxLimPct / Math.pow(10, scaleFactor));
2282
2308
  await this.writeRegisterValue(unitId, baseAddr + 3, scaledValue, 'uint16');
2283
- console.log(`Set power limit to ${controls.WMaxLimPct}% (scaled: ${scaledValue})`);
2309
+ console.debug(`Set power limit to ${controls.WMaxLimPct}% (scaled: ${scaledValue})`);
2284
2310
  }
2285
2311
  // Throttle enable/disable (Register 7)
2286
2312
  if (controls.WMaxLim_Ena !== undefined) {
2287
2313
  await this.writeRegisterValue(unitId, baseAddr + 7, controls.WMaxLim_Ena, 'uint16');
2288
- console.log(`Set throttle enable to ${controls.WMaxLim_Ena}`);
2314
+ console.debug(`Set throttle enable to ${controls.WMaxLim_Ena}`);
2289
2315
  }
2290
2316
  // Power factor control (Register 8) - needs scale factor
2291
2317
  if (controls.OutPFSet !== undefined) {
2292
2318
  const scaleFactor = await this.readRegisterValue(unitId, baseAddr + 22, 1, 'int16');
2293
2319
  const scaledValue = Math.round(controls.OutPFSet / Math.pow(10, scaleFactor));
2294
2320
  await this.writeRegisterValue(unitId, baseAddr + 8, scaledValue, 'int16');
2295
- console.log(`Set power factor to ${controls.OutPFSet} (scaled: ${scaledValue})`);
2321
+ console.debug(`Set power factor to ${controls.OutPFSet} (scaled: ${scaledValue})`);
2296
2322
  }
2297
2323
  // Power factor enable/disable (Register 12)
2298
2324
  if (controls.OutPFSet_Ena !== undefined) {
2299
2325
  await this.writeRegisterValue(unitId, baseAddr + 12, controls.OutPFSet_Ena, 'uint16');
2300
- console.log(`Set PF enable to ${controls.OutPFSet_Ena}`);
2326
+ console.debug(`Set PF enable to ${controls.OutPFSet_Ena}`);
2301
2327
  }
2302
- console.log('Inverter controls written successfully');
2328
+ console.debug('Inverter controls written successfully');
2303
2329
  return true;
2304
2330
  }
2305
2331
  catch (error) {
package/dist/version.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Current version of the enyo Energy App SDK.
7
7
  */
8
- export declare const SDK_VERSION = "0.0.73";
8
+ export declare const SDK_VERSION = "0.0.75";
9
9
  /**
10
10
  * Gets the current SDK version.
11
11
  * @returns The semantic version string of the SDK
package/dist/version.js CHANGED
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Current version of the enyo Energy App SDK.
7
7
  */
8
- export const SDK_VERSION = '0.0.73';
8
+ export const SDK_VERSION = '0.0.75';
9
9
  /**
10
10
  * Gets the current SDK version.
11
11
  * @returns The semantic version string of the SDK
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enyo-energy/sunspec-sdk",
3
- "version": "0.0.73",
3
+ "version": "0.0.75",
4
4
  "description": "enyo Energy Sunspec SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@enyo-energy/appliance-calibration": "0.0.2",
44
- "@enyo-energy/energy-app-sdk": "0.0.143"
44
+ "@enyo-energy/energy-app-sdk": "0.0.144"
45
45
  },
46
46
  "volta": {
47
47
  "node": "22.17.0"