@pietrolubini/homebridge-ecoflow 1.0.3 → 1.2.0

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.
Files changed (86) hide show
  1. package/.prettierrc.json +2 -1
  2. package/README.md +32 -0
  3. package/config.schema.json +18 -1
  4. package/dist/accessories/batteries/batteryAccessory.d.ts +59 -0
  5. package/dist/accessories/batteries/batteryAccessory.js +120 -0
  6. package/dist/accessories/batteries/batteryAccessory.js.map +1 -0
  7. package/dist/accessories/batteries/delta2Accessory.d.ts +3 -0
  8. package/dist/accessories/batteries/delta2Accessory.js +4 -0
  9. package/dist/accessories/batteries/delta2Accessory.js.map +1 -0
  10. package/dist/accessories/batteries/delta2maxAccessory.d.ts +3 -0
  11. package/dist/accessories/batteries/delta2maxAccessory.js +4 -0
  12. package/dist/accessories/batteries/delta2maxAccessory.js.map +1 -0
  13. package/dist/accessories/ecoFlowAccessory.d.ts +19 -11
  14. package/dist/accessories/ecoFlowAccessory.js +49 -8
  15. package/dist/accessories/ecoFlowAccessory.js.map +1 -1
  16. package/dist/apis/ecoFlowHttpApi.d.ts +46 -0
  17. package/dist/{accessories/apis → apis}/ecoFlowHttpApi.js +31 -6
  18. package/dist/apis/ecoFlowHttpApi.js.map +1 -0
  19. package/dist/apis/ecoFlowMqttApi.d.ts +53 -0
  20. package/dist/apis/ecoFlowMqttApi.js +100 -0
  21. package/dist/apis/ecoFlowMqttApi.js.map +1 -0
  22. package/dist/characteristics/CustomCharacteristic.d.ts +16 -0
  23. package/dist/characteristics/CustomCharacteristic.js +78 -0
  24. package/dist/characteristics/CustomCharacteristic.js.map +1 -0
  25. package/dist/config.d.ts +11 -1
  26. package/dist/config.js +7 -0
  27. package/dist/config.js.map +1 -1
  28. package/dist/helpers/logger.js +6 -6
  29. package/dist/helpers/logger.js.map +1 -1
  30. package/dist/index.js +1 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/platform.d.ts +7 -4
  33. package/dist/platform.js +29 -13
  34. package/dist/platform.js.map +1 -1
  35. package/dist/{accessories/services → services}/accessoryInformationService.d.ts +2 -1
  36. package/dist/services/accessoryInformationService.js +32 -0
  37. package/dist/services/accessoryInformationService.js.map +1 -0
  38. package/dist/{accessories/services/batteryService.d.ts → services/batteryStatusService.d.ts} +3 -2
  39. package/dist/services/batteryStatusService.js +32 -0
  40. package/dist/services/batteryStatusService.js.map +1 -0
  41. package/dist/services/outletAcService.d.ts +8 -0
  42. package/dist/services/outletAcService.js +17 -0
  43. package/dist/services/outletAcService.js.map +1 -0
  44. package/dist/{accessories/services → services}/outletCarService.d.ts +2 -2
  45. package/dist/{accessories/services → services}/outletCarService.js +4 -2
  46. package/dist/services/outletCarService.js.map +1 -0
  47. package/dist/services/outletServiceBase.d.ts +24 -0
  48. package/dist/services/outletServiceBase.js +62 -0
  49. package/dist/services/outletServiceBase.js.map +1 -0
  50. package/dist/{accessories/services → services}/outletUsbService.d.ts +2 -2
  51. package/dist/{accessories/services → services}/outletUsbService.js +2 -2
  52. package/dist/services/outletUsbService.js.map +1 -0
  53. package/dist/services/serviceBase.d.ts +24 -0
  54. package/dist/services/serviceBase.js +52 -0
  55. package/dist/services/serviceBase.js.map +1 -0
  56. package/docs/images/BatteryAdditionalCharacteristics.jpg +0 -0
  57. package/package.json +3 -1
  58. package/dist/accessories/apis/ecoFlowHttpApi.d.ts +0 -16
  59. package/dist/accessories/apis/ecoFlowHttpApi.js.map +0 -1
  60. package/dist/accessories/apis/ecoFlowMqttApi.d.ts +0 -23
  61. package/dist/accessories/apis/ecoFlowMqttApi.js +0 -94
  62. package/dist/accessories/apis/ecoFlowMqttApi.js.map +0 -1
  63. package/dist/accessories/apis/interfaces/ecoFlowHttpContacts.d.ts +0 -47
  64. package/dist/accessories/apis/interfaces/ecoFlowHttpContacts.js +0 -6
  65. package/dist/accessories/apis/interfaces/ecoFlowHttpContacts.js.map +0 -1
  66. package/dist/accessories/apis/interfaces/ecoFlowMqttContacts.d.ts +0 -68
  67. package/dist/accessories/apis/interfaces/ecoFlowMqttContacts.js +0 -9
  68. package/dist/accessories/apis/interfaces/ecoFlowMqttContacts.js.map +0 -1
  69. package/dist/accessories/delta2maxAccessory.d.ts +0 -24
  70. package/dist/accessories/delta2maxAccessory.js +0 -117
  71. package/dist/accessories/delta2maxAccessory.js.map +0 -1
  72. package/dist/accessories/services/accessoryInformationService.js +0 -24
  73. package/dist/accessories/services/accessoryInformationService.js.map +0 -1
  74. package/dist/accessories/services/batteryService.js +0 -29
  75. package/dist/accessories/services/batteryService.js.map +0 -1
  76. package/dist/accessories/services/outletAcService.d.ts +0 -6
  77. package/dist/accessories/services/outletAcService.js +0 -15
  78. package/dist/accessories/services/outletAcService.js.map +0 -1
  79. package/dist/accessories/services/outletCarService.js.map +0 -1
  80. package/dist/accessories/services/outletServiceBase.d.ts +0 -15
  81. package/dist/accessories/services/outletServiceBase.js +0 -44
  82. package/dist/accessories/services/outletServiceBase.js.map +0 -1
  83. package/dist/accessories/services/outletUsbService.js.map +0 -1
  84. package/dist/accessories/services/serviceBase.d.ts +0 -11
  85. package/dist/accessories/services/serviceBase.js +0 -17
  86. package/dist/accessories/services/serviceBase.js.map +0 -1
package/.prettierrc.json CHANGED
@@ -7,5 +7,6 @@
7
7
  "arrowParens": "avoid",
8
8
  "trailingComma": "es5",
9
9
  "bracketSameLine": true,
10
- "printWidth": 120
10
+ "printWidth": 120,
11
+ "plugins": ["prettier-plugin-organize-imports"]
11
12
  }
package/README.md CHANGED
@@ -22,6 +22,7 @@ The goal is to add HomeKit support to EcoFlow devices and make them fully contro
22
22
 
23
23
  ## Supported device types
24
24
 
25
+ - Delta 2
25
26
  - Delta 2 Max
26
27
 
27
28
  For a full list of devices that could be potentially added check [here](https://developer-eu.ecoflow.com/us/document/introduction)
@@ -63,6 +64,37 @@ Example configuration:
63
64
  }
64
65
  ```
65
66
 
67
+ ### Battery-specific Configuration
68
+
69
+ If `devices`.`model` is one of [`Delta 2`, `Delta 2 Max`] it is possible to set turn on/off additional characteristics:
70
+
71
+ - Input Consumption, W
72
+ - Output Consumption, W
73
+ - Battery Level, %
74
+
75
+ ```js
76
+ {
77
+ ...
78
+ "devices": [
79
+ {
80
+ ...,
81
+ "model": "Delta 2 Max",
82
+ "battery": {
83
+ "additionalCharacteristics": [
84
+ "Battery Level, %",
85
+ "Input Consumption, W",
86
+ "Output Consumption, W"
87
+ ]
88
+ }
89
+ }
90
+ ],
91
+ }
92
+ ```
93
+
94
+ The characteristics could be used as conditions in HomeKit Automation that uses Shortcuts:
95
+
96
+ <img src="docs/images/BatteryAdditionalCharacteristics.jpg" alt="Battery Additional Characteristics" width="300">
97
+
66
98
  ### AccessKey and SecretKey
67
99
 
68
100
  For the plugin to work EcoFlow account's `AccessKey` and `SecretKey` is required. To retrieve them
@@ -28,7 +28,7 @@
28
28
  "title": "Model",
29
29
  "type": "string",
30
30
  "required": true,
31
- "enum": ["Delta 2 Max"]
31
+ "enum": ["Delta 2", "Delta 2 Max"]
32
32
  },
33
33
  "serialNumber": {
34
34
  "title": "Serial Number",
@@ -47,6 +47,23 @@
47
47
  "type": "string",
48
48
  "required": true,
49
49
  "description": "Secret Key from \"EcoFlow IoT Developer Platform\" (https://developer-eu.ecoflow.com)"
50
+ },
51
+ "battery": {
52
+ "title": "Battery Settings",
53
+ "type": "object",
54
+ "properties": {
55
+ "additionalCharacteristics": {
56
+ "title": "Additional characteristics",
57
+ "description": "List of additional characteristics for battery",
58
+ "type": "array",
59
+ "uniqueItems": true,
60
+ "items": {
61
+ "title": "Characteristic",
62
+ "type": "string",
63
+ "enum": ["Battery Level, %", "Input Consumption, W", "Output Consumption, W"]
64
+ }
65
+ }
66
+ }
50
67
  }
51
68
  }
52
69
  }
@@ -0,0 +1,59 @@
1
+ import { Logging, PlatformAccessory } from 'homebridge';
2
+ import { MqttQuotaMessage } from '../../apis/ecoFlowMqttApi.js';
3
+ import { DeviceConfig } from '../../config.js';
4
+ import { EcoFlowHomebridgePlatform } from '../../platform.js';
5
+ import { ServiceBase } from '../../services/serviceBase.js';
6
+ import { EcoFlowAccessoryWithQuota } from '../ecoFlowAccessory.js';
7
+ export declare abstract class BatteryAccessory extends EcoFlowAccessoryWithQuota<BatteryAllQuotaData> {
8
+ private readonly batteryService;
9
+ private readonly outletUsbService;
10
+ private readonly outletAcService;
11
+ private readonly outletCarService;
12
+ constructor(platform: EcoFlowHomebridgePlatform, accessory: PlatformAccessory, config: DeviceConfig, log: Logging);
13
+ protected getServices(): ServiceBase[];
14
+ protected processQuotaMessage(message: MqttQuotaMessage): void;
15
+ protected updateInitialValues(initialData: BatteryAllQuotaData): void;
16
+ private updateBmsInitialValues;
17
+ private updateInvInitialValues;
18
+ private updatePdInitialValues;
19
+ private updateBmsValues;
20
+ private updateInvValues;
21
+ private updatePdValues;
22
+ private getUsbWatts;
23
+ }
24
+ interface BmsStatus {
25
+ f32ShowSoc: number;
26
+ }
27
+ interface InvStatusAc {
28
+ outputWatts?: number;
29
+ cfgAcEnabled?: boolean;
30
+ cfgAcXboost?: boolean;
31
+ cfgAcOutFreq?: number;
32
+ cfgAcOutVol?: number;
33
+ }
34
+ interface InvStatus extends InvStatusAc {
35
+ inputWatts: number;
36
+ }
37
+ interface PdStatusCar {
38
+ carState?: boolean;
39
+ carWatts?: number;
40
+ }
41
+ interface PdStatusUsb {
42
+ dcOutState?: boolean;
43
+ usb1Watts?: number;
44
+ usb2Watts?: number;
45
+ qcUsb1Watts?: number;
46
+ qcUsb2Watts?: number;
47
+ typec1Watts?: number;
48
+ typec2Watts?: number;
49
+ }
50
+ interface PdStatus extends PdStatusUsb, PdStatusCar {
51
+ carState?: boolean;
52
+ carWatts?: number;
53
+ }
54
+ export interface BatteryAllQuotaData {
55
+ bms_bmsStatus: BmsStatus;
56
+ inv: InvStatus;
57
+ pd: PdStatus;
58
+ }
59
+ export {};
@@ -0,0 +1,120 @@
1
+ import { MqttMessageType } from '../../apis/ecoFlowMqttApi.js';
2
+ import { BatteryStatusService } from '../../services/batteryStatusService.js';
3
+ import { OutletAcService } from '../../services/outletAcService.js';
4
+ import { OutletCarService } from '../../services/outletCarService.js';
5
+ import { OutletUsbService } from '../../services/outletUsbService.js';
6
+ import { EcoFlowAccessoryWithQuota } from '../ecoFlowAccessory.js';
7
+ export class BatteryAccessory extends EcoFlowAccessoryWithQuota {
8
+ batteryService;
9
+ outletUsbService;
10
+ outletAcService;
11
+ outletCarService;
12
+ constructor(platform, accessory, config, log) {
13
+ super(platform, accessory, config, log);
14
+ this.batteryService = new BatteryStatusService(this);
15
+ this.outletUsbService = new OutletUsbService(this);
16
+ this.outletAcService = new OutletAcService(this);
17
+ this.outletCarService = new OutletCarService(this);
18
+ }
19
+ getServices() {
20
+ return [this.batteryService, this.outletUsbService, this.outletAcService, this.outletCarService];
21
+ }
22
+ processQuotaMessage(message) {
23
+ if (message.typeCode === MqttMessageType.BMS) {
24
+ const bmsStatus = message.params;
25
+ this.log.debug('BMS:', bmsStatus);
26
+ Object.assign(this.quota.bms_bmsStatus, bmsStatus);
27
+ this.updateBmsValues(bmsStatus);
28
+ }
29
+ else if (message.typeCode === MqttMessageType.INV) {
30
+ const invStatus = message.params;
31
+ this.log.debug('INV:', invStatus);
32
+ Object.assign(this.quota.inv, invStatus);
33
+ this.updateInvValues(invStatus);
34
+ }
35
+ else if (message.typeCode === MqttMessageType.PD) {
36
+ const pdStatus = message.params;
37
+ this.log.debug('PD:', pdStatus);
38
+ Object.assign(this.quota.pd, pdStatus);
39
+ this.updatePdValues(pdStatus);
40
+ }
41
+ }
42
+ updateInitialValues(initialData) {
43
+ this.updateBmsInitialValues(initialData.bms_bmsStatus);
44
+ this.updateInvInitialValues(initialData.inv);
45
+ this.updatePdInitialValues(initialData.pd);
46
+ }
47
+ updateBmsInitialValues(params) {
48
+ const message = {
49
+ typeCode: MqttMessageType.BMS,
50
+ params,
51
+ };
52
+ this.processQuotaMessage(message);
53
+ }
54
+ updateInvInitialValues(params) {
55
+ const message = {
56
+ typeCode: MqttMessageType.INV,
57
+ params,
58
+ };
59
+ this.processQuotaMessage(message);
60
+ }
61
+ updatePdInitialValues(params) {
62
+ const message = {
63
+ typeCode: MqttMessageType.PD,
64
+ params,
65
+ };
66
+ this.processQuotaMessage(message);
67
+ }
68
+ updateBmsValues(params) {
69
+ if (params.f32ShowSoc !== undefined) {
70
+ this.batteryService.updateStatusLowBattery(params.f32ShowSoc);
71
+ this.batteryService.updateBatteryLevel(params.f32ShowSoc);
72
+ this.outletAcService.updateBatteryLevel(params.f32ShowSoc);
73
+ this.outletUsbService.updateBatteryLevel(params.f32ShowSoc);
74
+ this.outletCarService.updateBatteryLevel(params.f32ShowSoc);
75
+ }
76
+ }
77
+ updateInvValues(params) {
78
+ if (params.inputWatts !== undefined) {
79
+ this.batteryService.updateChargingState(params.inputWatts);
80
+ this.outletAcService.updateInputConsumption(params.inputWatts);
81
+ this.outletUsbService.updateInputConsumption(params.inputWatts);
82
+ this.outletCarService.updateInputConsumption(params.inputWatts);
83
+ }
84
+ if (params.cfgAcEnabled !== undefined) {
85
+ this.outletAcService.updateState(params.cfgAcEnabled);
86
+ }
87
+ if (params.outputWatts !== undefined) {
88
+ this.outletAcService.updateOutputConsumption(params.outputWatts);
89
+ }
90
+ }
91
+ updatePdValues(params) {
92
+ if (params.carState !== undefined) {
93
+ this.outletCarService.updateState(params.carState);
94
+ }
95
+ if (params.carWatts !== undefined) {
96
+ this.outletCarService.updateOutputConsumption(params.carWatts);
97
+ }
98
+ if (params.dcOutState !== undefined) {
99
+ this.outletUsbService.updateState(params.dcOutState);
100
+ }
101
+ if (params.usb1Watts !== undefined ||
102
+ params.usb2Watts !== undefined ||
103
+ params.qcUsb1Watts !== undefined ||
104
+ params.qcUsb2Watts !== undefined ||
105
+ params.typec1Watts !== undefined ||
106
+ params.typec2Watts !== undefined) {
107
+ const usbWatts = this.getUsbWatts(params.usb1Watts, params.usb2Watts, params.qcUsb1Watts, params.qcUsb2Watts, params.typec1Watts, params.typec2Watts);
108
+ this.outletUsbService.updateOutputConsumption(usbWatts);
109
+ }
110
+ }
111
+ getUsbWatts(usb1Watts, usb2Watts, qcUsb1Watts, qcUsb2Watts, typec1Watts, typec2Watts) {
112
+ return ((usb1Watts ?? 0) +
113
+ (usb2Watts ?? 0) +
114
+ (qcUsb1Watts ?? 0) +
115
+ (qcUsb2Watts ?? 0) +
116
+ (typec1Watts ?? 0) +
117
+ (typec2Watts ?? 0));
118
+ }
119
+ }
120
+ //# sourceMappingURL=batteryAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batteryAccessory.js","sourceRoot":"","sources":["../../../src/accessories/batteries/batteryAccessory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { BatteryAccessory } from './batteryAccessory.js';
2
+ export declare class Delta2Accessory extends BatteryAccessory {
3
+ }
@@ -0,0 +1,4 @@
1
+ import { BatteryAccessory } from './batteryAccessory.js';
2
+ export class Delta2Accessory extends BatteryAccessory {
3
+ }
4
+ //# sourceMappingURL=delta2Accessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delta2Accessory.js","sourceRoot":"","sources":["../../../src/accessories/batteries/delta2Accessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,OAAO,eAAgB,SAAQ,gBAAgB;CAAG"}
@@ -0,0 +1,3 @@
1
+ import { BatteryAccessory } from './batteryAccessory.js';
2
+ export declare class Delta2MaxAccessory extends BatteryAccessory {
3
+ }
@@ -0,0 +1,4 @@
1
+ import { BatteryAccessory } from './batteryAccessory.js';
2
+ export class Delta2MaxAccessory extends BatteryAccessory {
3
+ }
4
+ //# sourceMappingURL=delta2maxAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delta2maxAccessory.js","sourceRoot":"","sources":["../../../src/accessories/batteries/delta2maxAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,OAAO,kBAAmB,SAAQ,gBAAgB;CAAG"}
@@ -1,34 +1,42 @@
1
1
  import { Logging, PlatformAccessory } from 'homebridge';
2
- import { EcoFlowHomebridgePlatform } from '../platform.js';
3
- import { DeviceConfig } from '../config.js';
4
- import { ServiceBase } from './services/serviceBase.js';
5
- import { EcoFlowMqttApi } from './apis/ecoFlowMqttApi.js';
6
- import { EcoFlowHttpApi } from './apis/ecoFlowHttpApi.js';
7
- import { CmdResponseData } from './apis/interfaces/ecoFlowHttpContacts.js';
8
2
  import { Subscription } from 'rxjs';
3
+ import { EcoFlowHttpApi } from '../apis/ecoFlowHttpApi.js';
4
+ import { EcoFlowMqttApi, MqttQuotaMessage, MqttSetMessage, MqttSetReplyMessage } from '../apis/ecoFlowMqttApi.js';
5
+ import { DeviceConfig } from '../config.js';
6
+ import { EcoFlowHomebridgePlatform } from '../platform.js';
7
+ import { ServiceBase } from '../services/serviceBase.js';
9
8
  export declare abstract class EcoFlowAccessory {
10
9
  readonly platform: EcoFlowHomebridgePlatform;
11
10
  readonly accessory: PlatformAccessory;
12
11
  readonly config: DeviceConfig;
13
12
  readonly log: Logging;
14
- readonly mqttApi: EcoFlowMqttApi;
13
+ protected readonly mqttApi: EcoFlowMqttApi;
15
14
  protected readonly httpApi: EcoFlowHttpApi;
16
15
  private services;
17
16
  private reconnectMqttTimeoutId;
18
17
  private isMqttConnected;
19
18
  private subscriptions;
19
+ readonly setReplies: Record<string, {
20
+ requestMessage: MqttSetMessage;
21
+ revert: () => void;
22
+ }>;
20
23
  constructor(platform: EcoFlowHomebridgePlatform, accessory: PlatformAccessory, config: DeviceConfig, log: Logging);
21
24
  initialize(): Promise<void>;
22
25
  destroy(): void;
26
+ sendSetCommand<TParams>(moduleType: number, operateType: string, params: TParams, revert: () => void): Promise<void>;
23
27
  protected abstract getServices(): ServiceBase[];
24
- protected abstract subscribeOnParameterUpdates(): Subscription[];
28
+ protected subscribeOnParameterUpdates(): Subscription[];
29
+ protected abstract processQuotaMessage(message: MqttQuotaMessage): void;
30
+ protected processSetReplyMessage(message: MqttSetReplyMessage): void;
31
+ private getMqttSetMessageKey;
25
32
  private initializeServices;
26
33
  private cleanupServices;
27
34
  private connectMqtt;
28
35
  private initMqtt;
29
36
  }
30
- export declare abstract class EcoFlowAccessoryWithQuota<TGetQuotasCmdResponseData extends CmdResponseData> extends EcoFlowAccessory {
31
- private initialData;
37
+ export declare abstract class EcoFlowAccessoryWithQuota<TAllQuotaData> extends EcoFlowAccessory {
38
+ private _quota;
32
39
  initialize(): Promise<void>;
33
- protected abstract updateInitialValues(initialData: TGetQuotasCmdResponseData): void;
40
+ get quota(): TAllQuotaData;
41
+ protected abstract updateInitialValues(quota: TAllQuotaData): void;
34
42
  }
@@ -1,6 +1,6 @@
1
- import { EcoFlowMqttApi } from './apis/ecoFlowMqttApi.js';
2
- import { AccessoryInformationService } from './services/accessoryInformationService.js';
3
- import { EcoFlowHttpApi } from './apis/ecoFlowHttpApi.js';
1
+ import { EcoFlowHttpApi } from '../apis/ecoFlowHttpApi.js';
2
+ import { EcoFlowMqttApi, } from '../apis/ecoFlowMqttApi.js';
3
+ import { AccessoryInformationService } from '../services/accessoryInformationService.js';
4
4
  export class EcoFlowAccessory {
5
5
  platform;
6
6
  accessory;
@@ -12,6 +12,7 @@ export class EcoFlowAccessory {
12
12
  reconnectMqttTimeoutId = null;
13
13
  isMqttConnected = false;
14
14
  subscriptions = [];
15
+ setReplies = {};
15
16
  constructor(platform, accessory, config, log) {
16
17
  this.platform = platform;
17
18
  this.accessory = accessory;
@@ -34,6 +35,38 @@ export class EcoFlowAccessory {
34
35
  }
35
36
  this.subscriptions.forEach(subscription => subscription.unsubscribe());
36
37
  }
38
+ async sendSetCommand(moduleType, operateType, params, revert) {
39
+ const requestMessage = {
40
+ id: Math.floor(Math.random() * 1000000),
41
+ version: '1.0',
42
+ moduleType,
43
+ operateType,
44
+ params,
45
+ };
46
+ this.setReplies[this.getMqttSetMessageKey(requestMessage)] = { requestMessage, revert };
47
+ await this.mqttApi.sendSetCommand(this.config.serialNumber, requestMessage);
48
+ }
49
+ subscribeOnParameterUpdates() {
50
+ return [
51
+ this.mqttApi.quota$.subscribe(message => this.processQuotaMessage(message)),
52
+ this.mqttApi.setReply$.subscribe(message => this.processSetReplyMessage(message)),
53
+ ];
54
+ }
55
+ processSetReplyMessage(message) {
56
+ const messageKey = this.getMqttSetMessageKey(message);
57
+ const command = this.setReplies[messageKey];
58
+ delete this.setReplies[messageKey];
59
+ if (message.data.ack) {
60
+ this.log.warn('Failed to set a value. Reverts value back for:', command.requestMessage.operateType);
61
+ command.revert();
62
+ }
63
+ else {
64
+ this.log.debug('Setting of a value was successful for:', command.requestMessage.operateType);
65
+ }
66
+ }
67
+ getMqttSetMessageKey(message) {
68
+ return `${message.operateType}_${message.id}`;
69
+ }
37
70
  initializeServices() {
38
71
  this.services.forEach(service => {
39
72
  service.initialize();
@@ -48,6 +81,9 @@ export class EcoFlowAccessory {
48
81
  this.log.info('Removing obsolete service from accessory:', service.displayName);
49
82
  this.accessory.removeService(service);
50
83
  });
84
+ this.services
85
+ .filter(service => this.accessory.services.includes(service.service))
86
+ .forEach(service => service.cleanupCharacteristics());
51
87
  }
52
88
  async connectMqtt() {
53
89
  await this.initMqtt();
@@ -59,17 +95,22 @@ export class EcoFlowAccessory {
59
95
  }, 60 * 1000);
60
96
  }
61
97
  async initMqtt() {
62
- this.isMqttConnected = await this.mqttApi.subscribe('/open/<certificateAccount>/<sn>/quota', this.config.serialNumber);
98
+ this.isMqttConnected =
99
+ (await this.mqttApi.subscribeOnQuota(this.config.serialNumber)) &&
100
+ (await this.mqttApi.subscribeOnSetReply(this.config.serialNumber));
63
101
  }
64
102
  }
65
103
  export class EcoFlowAccessoryWithQuota extends EcoFlowAccessory {
66
- initialData = null;
104
+ _quota = null;
67
105
  async initialize() {
68
- if (!this.initialData) {
69
- this.initialData = await this.httpApi.getAllQuotas();
106
+ if (!this._quota) {
107
+ this._quota = await this.httpApi.getAllQuotas();
70
108
  }
71
109
  await super.initialize();
72
- this.updateInitialValues(this.initialData);
110
+ this.updateInitialValues(this._quota);
111
+ }
112
+ get quota() {
113
+ return this._quota;
73
114
  }
74
115
  }
75
116
  //# sourceMappingURL=ecoFlowAccessory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ecoFlowAccessory.js","sourceRoot":"","sources":["../../src/accessories/ecoFlowAccessory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ecoFlowAccessory.js","sourceRoot":"","sources":["../../src/accessories/ecoFlowAccessory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { Logging } from 'homebridge';
2
+ import { DeviceConfig } from '../config.js';
3
+ export declare enum HttpMethod {
4
+ Get = "GET",
5
+ Post = "POST"
6
+ }
7
+ export interface CmdResponse {
8
+ code: string;
9
+ message: string;
10
+ failed: boolean;
11
+ }
12
+ export interface CmdResponseWithData<TData> extends CmdResponse {
13
+ code: string;
14
+ message: string;
15
+ data: TData;
16
+ }
17
+ export interface GetCmdRequest {
18
+ sn: string;
19
+ }
20
+ export interface GetQuotasCmdRequest extends GetCmdRequest {
21
+ params: GetQuotasCmdRequestParams;
22
+ }
23
+ export interface GetQuotasCmdRequestParams {
24
+ quotas: string[];
25
+ }
26
+ export interface AcquireCertificateData {
27
+ certificateAccount: string;
28
+ certificatePassword: string;
29
+ url: string;
30
+ port: string;
31
+ protocol: string;
32
+ }
33
+ export declare class EcoFlowHttpApi {
34
+ private readonly config;
35
+ private readonly log;
36
+ constructor(config: DeviceConfig, log: Logging);
37
+ getQuotas<TData>(quotas: string[]): Promise<TData>;
38
+ getAllQuotas<TData>(): Promise<TData>;
39
+ acquireCertificate(): Promise<AcquireCertificateData | null>;
40
+ protected execute<TResponse extends CmdResponse>(relativeUrl: string, method: HttpMethod, queryParameters?: object | null, body?: object | null): Promise<TResponse>;
41
+ private getNonce;
42
+ private composeSignMessage;
43
+ private createHmacSha256;
44
+ private stringifyOptions;
45
+ private convertData;
46
+ }
@@ -1,9 +1,13 @@
1
1
  import * as crypto from 'crypto';
2
- import { HttpMethod, } from './interfaces/ecoFlowHttpContacts.js';
3
2
  const ApiUrl = 'https://api-e.ecoflow.com';
4
3
  const QuotaPath = '/iot-open/sign/device/quota';
5
4
  const QuotaAllPath = '/iot-open/sign/device/quota/all';
6
5
  const CertificatePath = '/iot-open/sign/certification';
6
+ export var HttpMethod;
7
+ (function (HttpMethod) {
8
+ HttpMethod["Get"] = "GET";
9
+ HttpMethod["Post"] = "POST";
10
+ })(HttpMethod || (HttpMethod = {}));
7
11
  export class EcoFlowHttpApi {
8
12
  config;
9
13
  log;
@@ -21,7 +25,7 @@ export class EcoFlowHttpApi {
21
25
  };
22
26
  const response = await this.execute(QuotaPath, HttpMethod.Post, requestCmd);
23
27
  if (!response.failed) {
24
- const data = response.data;
28
+ const data = this.convertData(response.data);
25
29
  this.log.debug('Quotas:', data);
26
30
  return data;
27
31
  }
@@ -34,7 +38,7 @@ export class EcoFlowHttpApi {
34
38
  };
35
39
  const response = await this.execute(QuotaAllPath, HttpMethod.Get, requestCmd);
36
40
  if (!response.failed) {
37
- const data = response.data;
41
+ const data = this.convertData(response.data);
38
42
  this.log.debug('All quotas:', data);
39
43
  return data;
40
44
  }
@@ -44,7 +48,6 @@ export class EcoFlowHttpApi {
44
48
  this.log.debug('Acquire certificate for MQTT connection');
45
49
  const response = await this.execute(CertificatePath, HttpMethod.Get);
46
50
  if (!response.failed) {
47
- this.log.debug('Certificate data:', response.data);
48
51
  return response.data;
49
52
  }
50
53
  return null;
@@ -76,13 +79,18 @@ export class EcoFlowHttpApi {
76
79
  const response = await fetch(requestUrl, options);
77
80
  const result = (await response.json());
78
81
  if (result.code !== '0') {
79
- throw Error(`Request to "${requestUrl}" with options: "${this.stringifyOptions(options)}" is failed [${response.status}]: ${response.statusText}; result: ${JSON.stringify(result)}`);
82
+ throw Error(`Request to "${requestUrl}" with options: "${this.stringifyOptions(options)}" is failed
83
+ [${response.status}]: ${response.statusText}; result: ${JSON.stringify(result)}`);
80
84
  }
81
85
  return result;
82
86
  }
83
87
  catch (e) {
84
88
  this.log.error('Request is failed:', e);
85
- return { code: '500', message: e?.message, failed: true };
89
+ return {
90
+ code: '500',
91
+ message: e?.message,
92
+ failed: true,
93
+ };
86
94
  }
87
95
  }
88
96
  getNonce() {
@@ -131,5 +139,22 @@ export class EcoFlowHttpApi {
131
139
  };
132
140
  return JSON.stringify(newOptions);
133
141
  }
142
+ convertData(data) {
143
+ const result = {};
144
+ Object.keys(data).forEach(key => {
145
+ const keys = key.split('.');
146
+ let current = result;
147
+ keys.forEach((k, index) => {
148
+ if (index === keys.length - 1) {
149
+ current[k] = data[key];
150
+ }
151
+ else {
152
+ current[k] = current[k] || {};
153
+ current = current[k];
154
+ }
155
+ });
156
+ });
157
+ return result;
158
+ }
134
159
  }
135
160
  //# sourceMappingURL=ecoFlowHttpApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecoFlowHttpApi.js","sourceRoot":"","sources":["../../src/apis/ecoFlowHttpApi.ts"],"names":[],"mappings":"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"}