@pietrolubini/homebridge-ecoflow 1.2.1 → 1.3.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 (203) hide show
  1. package/.gitattributes +7 -0
  2. package/.prettierrc.json +1 -0
  3. package/README.md +153 -24
  4. package/config.schema.json +65 -2
  5. package/dist/accessories/batteries/batteryAccessoryBase.d.ts +26 -0
  6. package/dist/accessories/batteries/batteryAccessoryBase.js +126 -0
  7. package/dist/accessories/batteries/batteryAccessoryBase.js.map +1 -0
  8. package/dist/accessories/batteries/batteryAccessoryBase.spec.d.ts +1 -0
  9. package/dist/accessories/batteries/delta2Accessory.d.ts +2 -2
  10. package/dist/accessories/batteries/delta2Accessory.js +6 -2
  11. package/dist/accessories/batteries/delta2Accessory.js.map +1 -1
  12. package/dist/accessories/batteries/delta2maxAccessory.d.ts +2 -2
  13. package/dist/accessories/batteries/delta2maxAccessory.js +6 -2
  14. package/dist/accessories/batteries/delta2maxAccessory.js.map +1 -1
  15. package/dist/accessories/batteries/interfaces/httpApiBatteryContracts.d.ts +33 -0
  16. package/dist/accessories/batteries/interfaces/httpApiBatteryContracts.js +3 -0
  17. package/dist/accessories/batteries/interfaces/httpApiBatteryContracts.js.map +1 -0
  18. package/dist/accessories/batteries/interfaces/mqttApiBatteryContracts.d.ts +36 -0
  19. package/dist/accessories/batteries/interfaces/mqttApiBatteryContracts.js +18 -0
  20. package/dist/accessories/batteries/interfaces/mqttApiBatteryContracts.js.map +1 -0
  21. package/dist/accessories/batteries/services/outletAcService.d.ts +8 -0
  22. package/dist/accessories/batteries/services/outletAcService.js +24 -0
  23. package/dist/accessories/batteries/services/outletAcService.js.map +1 -0
  24. package/dist/accessories/batteries/services/outletAcService.spec.d.ts +1 -0
  25. package/dist/accessories/batteries/services/outletBatteryServiceBase.d.ts +5 -0
  26. package/dist/accessories/batteries/services/outletBatteryServiceBase.js +18 -0
  27. package/dist/accessories/batteries/services/outletBatteryServiceBase.js.map +1 -0
  28. package/dist/accessories/batteries/services/outletCarService.d.ts +6 -0
  29. package/dist/accessories/batteries/services/outletCarService.js +17 -0
  30. package/dist/accessories/batteries/services/outletCarService.js.map +1 -0
  31. package/dist/accessories/batteries/services/outletCarService.spec.d.ts +1 -0
  32. package/dist/accessories/batteries/services/outletUsbService.d.ts +6 -0
  33. package/dist/accessories/batteries/services/outletUsbService.js +15 -0
  34. package/dist/accessories/batteries/services/outletUsbService.js.map +1 -0
  35. package/dist/accessories/batteries/services/outletUsbService.spec.d.ts +1 -0
  36. package/dist/accessories/batteries/simulations/batterySimulator.d.ts +6 -0
  37. package/dist/accessories/batteries/simulations/batterySimulator.js +60 -0
  38. package/dist/accessories/batteries/simulations/batterySimulator.js.map +1 -0
  39. package/dist/accessories/ecoFlowAccessoryBase.d.ts +41 -0
  40. package/dist/accessories/ecoFlowAccessoryBase.js +114 -0
  41. package/dist/accessories/ecoFlowAccessoryBase.js.map +1 -0
  42. package/dist/accessories/ecoFlowAccessoryBase.spec.d.ts +1 -0
  43. package/dist/accessories/ecoFlowAccessoryWithQuotaBase.d.ts +15 -0
  44. package/dist/accessories/ecoFlowAccessoryWithQuotaBase.js +34 -0
  45. package/dist/accessories/ecoFlowAccessoryWithQuotaBase.js.map +1 -0
  46. package/dist/accessories/ecoFlowAccessoryWithQuotaBase.spec.d.ts +1 -0
  47. package/dist/accessories/powerstream/interfaces/httpApiPowerStreamContracts.d.ts +16 -0
  48. package/dist/accessories/powerstream/interfaces/httpApiPowerStreamContracts.js +3 -0
  49. package/dist/accessories/powerstream/interfaces/httpApiPowerStreamContracts.js.map +1 -0
  50. package/dist/accessories/powerstream/interfaces/mqttApiPowerStreamContracts.d.ts +41 -0
  51. package/dist/accessories/powerstream/interfaces/mqttApiPowerStreamContracts.js +21 -0
  52. package/dist/accessories/powerstream/interfaces/mqttApiPowerStreamContracts.js.map +1 -0
  53. package/dist/accessories/powerstream/powerStreamAccessory.d.ts +26 -0
  54. package/dist/accessories/powerstream/powerStreamAccessory.js +113 -0
  55. package/dist/accessories/powerstream/powerStreamAccessory.js.map +1 -0
  56. package/dist/accessories/powerstream/powerStreamAccessory.spec.d.ts +1 -0
  57. package/dist/accessories/powerstream/services/brightnessService.d.ts +7 -0
  58. package/dist/accessories/powerstream/services/brightnessService.js +27 -0
  59. package/dist/accessories/powerstream/services/brightnessService.js.map +1 -0
  60. package/dist/accessories/powerstream/services/brightnessService.spec.d.ts +1 -0
  61. package/dist/accessories/powerstream/services/outletInvService.d.ts +7 -0
  62. package/dist/accessories/powerstream/services/outletInvService.js +14 -0
  63. package/dist/accessories/powerstream/services/outletInvService.js.map +1 -0
  64. package/dist/accessories/powerstream/services/outletInvService.spec.d.ts +1 -0
  65. package/dist/accessories/powerstream/services/outletService.d.ts +8 -0
  66. package/dist/accessories/powerstream/services/outletService.js +14 -0
  67. package/dist/accessories/powerstream/services/outletService.js.map +1 -0
  68. package/dist/accessories/powerstream/services/outletService.spec.d.ts +1 -0
  69. package/dist/accessories/powerstream/services/powerDemandService.d.ts +7 -0
  70. package/dist/accessories/powerstream/services/powerDemandService.js +27 -0
  71. package/dist/accessories/powerstream/services/powerDemandService.js.map +1 -0
  72. package/dist/accessories/powerstream/services/powerDemandService.spec.d.ts +1 -0
  73. package/dist/accessories/powerstream/simulations/powerStreamSimulator.d.ts +6 -0
  74. package/dist/accessories/powerstream/simulations/powerStreamSimulator.js +39 -0
  75. package/dist/accessories/powerstream/simulations/powerStreamSimulator.js.map +1 -0
  76. package/dist/apis/containers/deviceInfo.d.ts +13 -0
  77. package/dist/apis/containers/deviceInfo.js +23 -0
  78. package/dist/apis/containers/deviceInfo.js.map +1 -0
  79. package/dist/apis/containers/deviceInfo.spec.d.ts +1 -0
  80. package/dist/apis/containers/mqttClientContainer.d.ts +17 -0
  81. package/dist/apis/containers/mqttClientContainer.js +45 -0
  82. package/dist/apis/containers/mqttClientContainer.js.map +1 -0
  83. package/dist/apis/containers/mqttClientContainer.spec.d.ts +1 -0
  84. package/dist/apis/containers/mqttDevice.d.ts +15 -0
  85. package/dist/apis/containers/mqttDevice.js +43 -0
  86. package/dist/apis/containers/mqttDevice.js.map +1 -0
  87. package/dist/apis/containers/mqttDevice.spec.d.ts +1 -0
  88. package/dist/apis/ecoFlowHttpApiManager.d.ts +13 -0
  89. package/dist/apis/{ecoFlowHttpApi.js → ecoFlowHttpApiManager.js} +55 -45
  90. package/dist/apis/ecoFlowHttpApiManager.js.map +1 -0
  91. package/dist/apis/ecoFlowHttpApiManager.spec.d.ts +1 -0
  92. package/dist/apis/ecoFlowMqttApiManager.d.ts +25 -0
  93. package/dist/apis/ecoFlowMqttApiManager.js +152 -0
  94. package/dist/apis/ecoFlowMqttApiManager.js.map +1 -0
  95. package/dist/apis/ecoFlowMqttApiManager.spec.d.ts +1 -0
  96. package/dist/apis/interfaces/httpApiContracts.d.ts +30 -0
  97. package/dist/apis/interfaces/httpApiContracts.js +9 -0
  98. package/dist/apis/interfaces/httpApiContracts.js.map +1 -0
  99. package/dist/apis/interfaces/mqttApiContracts.d.ts +26 -0
  100. package/dist/apis/interfaces/mqttApiContracts.js +9 -0
  101. package/dist/apis/interfaces/mqttApiContracts.js.map +1 -0
  102. package/dist/apis/simulations/mockMqttClient.d.ts +15 -0
  103. package/dist/apis/simulations/mockMqttClient.js +59 -0
  104. package/dist/apis/simulations/mockMqttClient.js.map +1 -0
  105. package/dist/apis/simulations/mockMqttClient.spec.d.ts +1 -0
  106. package/dist/apis/simulations/simulator.d.ts +13 -0
  107. package/dist/apis/simulations/simulator.js +26 -0
  108. package/dist/apis/simulations/simulator.js.map +1 -0
  109. package/dist/characteristics/{CustomCharacteristic.js → customCharacteristic.js} +18 -11
  110. package/dist/characteristics/customCharacteristic.js.map +1 -0
  111. package/dist/characteristics/customCharacteristic.spec.d.ts +1 -0
  112. package/dist/config.d.ts +28 -4
  113. package/dist/config.js +15 -6
  114. package/dist/config.js.map +1 -1
  115. package/dist/helpers/logger.js +5 -1
  116. package/dist/helpers/logger.js.map +1 -1
  117. package/dist/helpers/logger.spec.d.ts +1 -0
  118. package/dist/helpers/machineIdProvider.d.ts +4 -0
  119. package/dist/helpers/machineIdProvider.js +19 -0
  120. package/dist/helpers/machineIdProvider.js.map +1 -0
  121. package/dist/helpers/machineIdProvider.spec.d.ts +1 -0
  122. package/dist/helpers/tests/accessoryTestHelper.d.ts +5 -0
  123. package/dist/helpers/tests/serviceTestHelper.d.ts +6 -0
  124. package/dist/helpers/tests/sleep.d.ts +1 -0
  125. package/dist/homebridge-ui/public/index.d.ts +2 -0
  126. package/dist/homebridge-ui/public/index.html +6 -0
  127. package/dist/homebridge-ui/public/index.js +1 -0
  128. package/dist/homebridge-ui/public/index.spec.d.ts +1 -0
  129. package/dist/homebridge-ui/public/interfaces/contracts.d.ts +13 -0
  130. package/dist/homebridge-ui/public/interfaces/homebridge.d.ts +52 -0
  131. package/dist/homebridge-ui/public/renderers/componentRenderer.d.ts +6 -0
  132. package/dist/homebridge-ui/public/renderers/componentRenderer.spec.d.ts +1 -0
  133. package/dist/homebridge-ui/public/renderers/pluginConfigDevicesRenderer.d.ts +20 -0
  134. package/dist/homebridge-ui/public/renderers/pluginConfigDevicesRenderer.spec.d.ts +1 -0
  135. package/dist/homebridge-ui/public/renderers/pluginConfigNameRenderer.d.ts +5 -0
  136. package/dist/homebridge-ui/public/renderers/pluginConfigNameRenderer.spec.d.ts +1 -0
  137. package/dist/homebridge-ui/public/renderers/pluginConfigRenderer.d.ts +6 -0
  138. package/dist/homebridge-ui/public/renderers/pluginConfigRenderer.spec.d.ts +1 -0
  139. package/dist/homebridge-ui/public/renderers/pluginConfigRendererBase.d.ts +9 -0
  140. package/dist/index.js +7 -4
  141. package/dist/index.js.map +1 -1
  142. package/dist/index.spec.d.ts +1 -0
  143. package/dist/platform.d.ts +11 -8
  144. package/dist/platform.js +88 -32
  145. package/dist/platform.js.map +1 -1
  146. package/dist/platform.spec.d.ts +1 -0
  147. package/dist/services/accessoryInformationService.d.ts +5 -3
  148. package/dist/services/accessoryInformationService.js +15 -12
  149. package/dist/services/accessoryInformationService.js.map +1 -1
  150. package/dist/services/accessoryInformationService.spec.d.ts +1 -0
  151. package/dist/services/batteryStatusService.d.ts +6 -4
  152. package/dist/services/batteryStatusService.js +19 -17
  153. package/dist/services/batteryStatusService.js.map +1 -1
  154. package/dist/services/batteryStatusService.spec.d.ts +1 -0
  155. package/dist/services/fanServiceBase.d.ts +16 -0
  156. package/dist/services/fanServiceBase.js +42 -0
  157. package/dist/services/fanServiceBase.js.map +1 -0
  158. package/dist/services/fanServiceBase.spec.d.ts +1 -0
  159. package/dist/services/lightBulbServiceBase.d.ts +16 -0
  160. package/dist/services/lightBulbServiceBase.js +42 -0
  161. package/dist/services/lightBulbServiceBase.js.map +1 -0
  162. package/dist/services/lightBulbServiceBase.spec.d.ts +1 -0
  163. package/dist/services/outletServiceBase.d.ts +7 -15
  164. package/dist/services/outletServiceBase.js +20 -28
  165. package/dist/services/outletServiceBase.js.map +1 -1
  166. package/dist/services/outletServiceBase.spec.d.ts +1 -0
  167. package/dist/services/serviceBase.d.ts +10 -5
  168. package/dist/services/serviceBase.js +31 -8
  169. package/dist/services/serviceBase.js.map +1 -1
  170. package/dist/settings.js +5 -2
  171. package/dist/settings.js.map +1 -1
  172. package/docs/images/plugin_icon.png +0 -0
  173. package/jest.config.ts +46 -0
  174. package/junit.xml +843 -0
  175. package/package.json +42 -12
  176. package/tsconfig.build.json +5 -0
  177. package/tsconfig.spec.json +8 -0
  178. package/dist/accessories/batteries/batteryAccessory.d.ts +0 -59
  179. package/dist/accessories/batteries/batteryAccessory.js +0 -120
  180. package/dist/accessories/batteries/batteryAccessory.js.map +0 -1
  181. package/dist/accessories/ecoFlowAccessory.d.ts +0 -42
  182. package/dist/accessories/ecoFlowAccessory.js +0 -122
  183. package/dist/accessories/ecoFlowAccessory.js.map +0 -1
  184. package/dist/apis/ecoFlowHttpApi.d.ts +0 -47
  185. package/dist/apis/ecoFlowHttpApi.js.map +0 -1
  186. package/dist/apis/ecoFlowMqttApi.d.ts +0 -53
  187. package/dist/apis/ecoFlowMqttApi.js +0 -100
  188. package/dist/apis/ecoFlowMqttApi.js.map +0 -1
  189. package/dist/characteristics/CustomCharacteristic.js.map +0 -1
  190. package/dist/helpers/machineId.d.ts +0 -2
  191. package/dist/helpers/machineId.js +0 -15
  192. package/dist/helpers/machineId.js.map +0 -1
  193. package/dist/helpers/machineIdHelper.cjs +0 -5
  194. package/dist/services/outletAcService.d.ts +0 -8
  195. package/dist/services/outletAcService.js +0 -17
  196. package/dist/services/outletAcService.js.map +0 -1
  197. package/dist/services/outletCarService.d.ts +0 -6
  198. package/dist/services/outletCarService.js +0 -12
  199. package/dist/services/outletCarService.js.map +0 -1
  200. package/dist/services/outletUsbService.d.ts +0 -6
  201. package/dist/services/outletUsbService.js +0 -10
  202. package/dist/services/outletUsbService.js.map +0 -1
  203. /package/dist/characteristics/{CustomCharacteristic.d.ts → customCharacteristic.d.ts} +0 -0
@@ -1,95 +1,104 @@
1
- import * as crypto from 'crypto';
2
- import { LocationType } from '../config.js';
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.EcoFlowHttpApiManager = void 0;
27
+ const httpApiContracts_1 = require("@ecoflow/apis/interfaces/httpApiContracts");
28
+ const config_1 = require("@ecoflow/config");
29
+ const crypto = __importStar(require("crypto"));
3
30
  const ApiUrlUs = 'https://api-a.ecoflow.com';
4
31
  const ApiUrlEu = 'https://api-e.ecoflow.com';
5
32
  const QuotaPath = '/iot-open/sign/device/quota';
6
33
  const QuotaAllPath = '/iot-open/sign/device/quota/all';
7
34
  const CertificatePath = '/iot-open/sign/certification';
8
- export var HttpMethod;
9
- (function (HttpMethod) {
10
- HttpMethod["Get"] = "GET";
11
- HttpMethod["Post"] = "POST";
12
- })(HttpMethod || (HttpMethod = {}));
13
- export class EcoFlowHttpApi {
14
- config;
15
- log;
16
- apiUrl;
17
- constructor(config, log) {
18
- this.config = config;
19
- this.log = log;
20
- this.apiUrl = this.config.location === LocationType.US ? ApiUrlUs : ApiUrlEu;
21
- }
22
- async getQuotas(quotas) {
23
- this.log.debug('Get quotas:', quotas);
35
+ class EcoFlowHttpApiManager {
36
+ async getQuotas(quotas, deviceInfo) {
37
+ deviceInfo.log.debug('Get quotas:', quotas);
24
38
  const requestCmd = {
25
- sn: this.config.serialNumber,
39
+ sn: deviceInfo.config.serialNumber,
26
40
  params: {
27
41
  quotas,
28
42
  },
29
43
  };
30
- const response = await this.execute(QuotaPath, HttpMethod.Post, requestCmd);
44
+ const response = await this.execute(deviceInfo, QuotaPath, httpApiContracts_1.HttpMethod.Post, requestCmd);
31
45
  if (!response.failed) {
32
46
  const data = this.convertData(response.data);
33
- this.log.debug('Quotas:', data);
47
+ deviceInfo.log.debug(`Received quotas: ${JSON.stringify(data, null, 2)}`);
34
48
  return data;
35
49
  }
36
- return {};
50
+ return null;
37
51
  }
38
- async getAllQuotas() {
39
- this.log.debug('Get all quotas');
52
+ async getAllQuotas(deviceInfo) {
53
+ deviceInfo.log.debug('Get all quotas');
40
54
  const requestCmd = {
41
- sn: this.config.serialNumber,
55
+ sn: deviceInfo.config.serialNumber,
42
56
  };
43
- const response = await this.execute(QuotaAllPath, HttpMethod.Get, requestCmd);
57
+ const response = await this.execute(deviceInfo, QuotaAllPath, httpApiContracts_1.HttpMethod.Get, requestCmd);
44
58
  if (!response.failed) {
45
59
  const data = this.convertData(response.data);
46
- this.log.debug('All quotas:', data);
60
+ deviceInfo.log.debug(`Received all quotas: ${JSON.stringify(data, null, 2)}`);
47
61
  return data;
48
62
  }
49
63
  return null;
50
64
  }
51
- async acquireCertificate() {
52
- this.log.debug('Acquire certificate for MQTT connection');
53
- const response = await this.execute(CertificatePath, HttpMethod.Get);
65
+ async acquireCertificate(deviceInfo) {
66
+ deviceInfo.log.debug('Acquire certificate for MQTT connection');
67
+ const response = await this.execute(deviceInfo, CertificatePath, httpApiContracts_1.HttpMethod.Get);
54
68
  if (!response.failed) {
55
69
  return response.data;
56
70
  }
57
71
  return null;
58
72
  }
59
- async execute(relativeUrl, method, queryParameters = null, body = null) {
60
- const url = new URL(relativeUrl, this.apiUrl);
61
- const accessKey = this.config.accessKey;
73
+ async execute(deviceInfo, relativeUrl, method, queryParameters = null) {
74
+ const apiUrl = deviceInfo.config.location === config_1.LocationType.US ? ApiUrlUs : ApiUrlEu;
75
+ const url = new URL(relativeUrl, apiUrl);
76
+ const accessKey = deviceInfo.config.accessKey;
62
77
  const nonce = this.getNonce();
63
78
  const timestamp = Date.now();
64
79
  const queryParams = this.composeSignMessage(queryParameters);
65
- let params = queryParams ? `${queryParams}&` : '';
66
- const bodyParamsMessage = this.composeSignMessage(body);
67
- params = bodyParamsMessage ? `${params}${bodyParamsMessage}&` : params;
80
+ const params = queryParams ? `${queryParams}&` : '';
68
81
  const message = `${params}accessKey=${accessKey}&nonce=${nonce}&timestamp=${timestamp}`;
69
- const requestUrl = queryParams ? `${url}?${queryParams}` : url;
82
+ const requestUrl = queryParams ? `${url}?${queryParams}` : url.toString();
70
83
  const headers = {
71
84
  accessKey,
72
85
  nonce,
73
86
  timestamp: timestamp.toString(),
74
- sign: this.createHmacSha256(this.config.secretKey, message),
87
+ sign: this.createHmacSha256(deviceInfo.config.secretKey, message),
75
88
  };
76
89
  const options = { method };
77
- if (body) {
78
- options.body = JSON.stringify(body);
79
- headers['Content-Type'] = 'application/json';
80
- }
81
90
  options.headers = new Headers(headers);
82
91
  try {
83
92
  const response = await fetch(requestUrl, options);
84
93
  const result = (await response.json());
85
94
  if (result.code !== '0') {
86
95
  throw Error(`Request to "${requestUrl}" with options: "${this.stringifyOptions(options)}" is failed
87
- [${response.status}]: ${response.statusText}; result: ${JSON.stringify(result)}`);
96
+ [${response.status}]: ${response.statusText}; result: ${JSON.stringify(result)}`);
88
97
  }
89
98
  return result;
90
99
  }
91
100
  catch (e) {
92
- this.log.error('Request is failed:', e);
101
+ deviceInfo.log.error('Request is failed:', e);
93
102
  return {
94
103
  code: '500',
95
104
  message: e?.message,
@@ -161,4 +170,5 @@ export class EcoFlowHttpApi {
161
170
  return result;
162
171
  }
163
172
  }
164
- //# sourceMappingURL=ecoFlowHttpApi.js.map
173
+ exports.EcoFlowHttpApiManager = EcoFlowHttpApiManager;
174
+ //# sourceMappingURL=ecoFlowHttpApiManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecoFlowHttpApiManager.js","sourceRoot":"","sources":["../../src/apis/ecoFlowHttpApiManager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,gFAOmD;AACnD,4CAA+C;AAC/C,+CAAiC;AAEjC,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAC7C,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAC7C,MAAM,SAAS,GAAG,6BAA6B,CAAC;AAChD,MAAM,YAAY,GAAG,iCAAiC,CAAC;AACvD,MAAM,eAAe,GAAG,8BAA8B,CAAC;AAOvD,MAAa,qBAAqB;IACzB,KAAK,CAAC,SAAS,CAAQ,MAAgB,EAAE,UAAsB;QACpE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAwB;YACtC,EAAE,EAAE,UAAU,CAAC,MAAM,CAAC,YAAY;YAClC,MAAM,EAAE;gBACN,MAAM;aACP;SACF,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAA4B,UAAU,EAAE,SAAS,EAAE,6BAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACnH,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAQ,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAC1E,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,YAAY,CAAQ,UAAsB;QACrD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACvC,MAAM,UAAU,GAAkB;YAChC,EAAE,EAAE,UAAU,CAAC,MAAM,CAAC,YAAY;SACnC,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CACjC,UAAU,EACV,YAAY,EACZ,6BAAU,CAAC,GAAG,EACd,UAAU,CACX,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAQ,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,wBAAwB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9E,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAAC,UAAsB;QACpD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAChE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CACjC,UAAU,EACV,eAAe,EACf,6BAAU,CAAC,GAAG,CACf,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAES,KAAK,CAAC,OAAO,CACrB,UAAsB,EACtB,WAAmB,EACnB,MAAkB,EAClB,kBAAiC,IAAI;QAErC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,QAAQ,KAAK,qBAAY,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QACpF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,MAAM,OAAO,GAAG,GAAG,MAAM,aAAa,SAAS,UAAU,KAAK,cAAc,SAAS,EAAE,CAAC;QACxF,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAE1E,MAAM,OAAO,GAAgB;YAC3B,SAAS;YACT,KAAK;YACL,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE;YAC/B,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC;SAClE,CAAC;QACF,MAAM,OAAO,GAAgB,EAAE,MAAM,EAAE,CAAC;QACxC,OAAO,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAyB,CAAC;YAC/D,IAAI,MAAM,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;gBACxB,MAAM,KAAK,CACT,eAAe,UAAU,oBAAoB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;GAClF,QAAQ,CAAC,MAAM,MAAM,QAAQ,CAAC,UAAU,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CACvE,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC;YAC9C,OAAO;gBACL,IAAI,EAAE,KAAK;gBACX,OAAO,EAAG,CAAW,EAAE,OAAO;gBAC9B,MAAM,EAAE,IAAI;aACA,CAAC;QACjB,CAAC;IACH,CAAC;IAEO,QAAQ;QACd,MAAM,GAAG,GAAG,CAAC,CAAC;QACd,MAAM,GAAG,GAAG,MAAM,CAAC;QACnB,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QACvE,OAAO,YAAY,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClD,CAAC;IAEO,kBAAkB,CAAC,GAAgB,EAAE,SAAiB,EAAE;QAC9D,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,UAAU,GAAa,EAAE,CAAC;QAEhC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;aACb,IAAI,EAAE;aACN,OAAO,CAAC,GAAG,CAAC,EAAE;YACb,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YACvB,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAErD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;oBAC5B,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC,CAAC;gBACrD,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACvD,oCAAoC;gBACpC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;YAC9D,CAAC;iBAAM,CAAC;gBACN,0BAA0B;gBAC1B,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,IAAI,KAAK,EAAE,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC,CAAC,CAAC;QAEL,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAEO,gBAAgB,CAAC,GAAW,EAAE,OAAe;QACnD,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxE,CAAC;IAEO,gBAAgB,CAAC,OAAoB;QAC3C,MAAM,aAAa,GAEf,EAAE,CAAC;QACN,OAAO,CAAC,OAAmB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YAClD,aAAa,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,MAAM,UAAU,GAAG;YACjB,GAAG,OAAO;YACV,OAAO,EAAE,aAAa;SACvB,CAAC;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAEO,WAAW,CAAQ,IAAU;QACnC,MAAM,MAAM,GAAS,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,OAAO,GAAG,MAAM,CAAC;YAErB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;gBACxB,IAAI,KAAK,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9B,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;gBACzB,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC9B,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,MAAe,CAAC;IACzB,CAAC;CACF;AArKD,sDAqKC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ import { DeviceInfo } from '@ecoflow/apis/containers/deviceInfo';
2
+ import { EcoFlowHttpApiManager } from '@ecoflow/apis/ecoFlowHttpApiManager';
3
+ import { MqttSetMessage } from '@ecoflow/apis/interfaces/mqttApiContracts';
4
+ import { MachineIdProvider } from '@ecoflow/helpers/machineIdProvider';
5
+ import { Subscription } from 'rxjs';
6
+ export declare class EcoFlowMqttApiManager {
7
+ private readonly httpApiManager;
8
+ private readonly machineIdProvider;
9
+ private readonly mqttClientContainers;
10
+ constructor(httpApiManager: EcoFlowHttpApiManager, machineIdProvider: MachineIdProvider);
11
+ destroy(): Promise<void>;
12
+ subscribeOnQuotaTopic(deviceInfo: DeviceInfo): Promise<boolean>;
13
+ subscribeOnSetReplyTopic(deviceInfo: DeviceInfo): Promise<boolean>;
14
+ subscribeOnQuotaMessage<TMessage>(deviceInfo: DeviceInfo, callback: (message: TMessage) => void): Subscription | undefined;
15
+ subscribeOnSetReplyMessage<TMessage>(deviceInfo: DeviceInfo, callback: (message: TMessage) => void): Subscription | undefined;
16
+ sendSetCommand(deviceInfo: DeviceInfo, message: MqttSetMessage): Promise<void>;
17
+ private connect;
18
+ private connectMqttClient;
19
+ private subscribeOnTopic;
20
+ private subscribeOnMessage;
21
+ private processReceivedMessage;
22
+ private acquireCertificate;
23
+ private getMqttClientContainer;
24
+ private parseTopic;
25
+ }
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EcoFlowMqttApiManager = void 0;
7
+ const mqttClientContainer_1 = require("@ecoflow/apis/containers/mqttClientContainer");
8
+ const mqttApiContracts_1 = require("@ecoflow/apis/interfaces/mqttApiContracts");
9
+ const mockMqttClient_1 = require("@ecoflow/apis/simulations/mockMqttClient");
10
+ const mqtt_1 = __importDefault(require("mqtt"));
11
+ class EcoFlowMqttApiManager {
12
+ httpApiManager;
13
+ machineIdProvider;
14
+ mqttClientContainers = {};
15
+ constructor(httpApiManager, machineIdProvider) {
16
+ this.httpApiManager = httpApiManager;
17
+ this.machineIdProvider = machineIdProvider;
18
+ }
19
+ async destroy() {
20
+ for (const connectionKey in this.mqttClientContainers) {
21
+ const mqttClientContainer = this.mqttClientContainers[connectionKey];
22
+ await mqttClientContainer.client?.unsubscribeAsync('#');
23
+ const devices = mqttClientContainer.getAllDevices();
24
+ devices.forEach(device => device.log.debug('Unsubscribed from all topics'));
25
+ await mqttClientContainer.client?.endAsync();
26
+ devices.forEach(device => device.log.debug('Disconnected from EcoFlow MQTT Service'));
27
+ }
28
+ }
29
+ subscribeOnQuotaTopic(deviceInfo) {
30
+ return this.subscribeOnTopic(deviceInfo, mqttApiContracts_1.MqttTopicType.Quota);
31
+ }
32
+ subscribeOnSetReplyTopic(deviceInfo) {
33
+ return this.subscribeOnTopic(deviceInfo, mqttApiContracts_1.MqttTopicType.SetReply);
34
+ }
35
+ subscribeOnQuotaMessage(deviceInfo, callback) {
36
+ return this.subscribeOnMessage(deviceInfo, mqttApiContracts_1.MqttTopicType.Quota, callback);
37
+ }
38
+ subscribeOnSetReplyMessage(deviceInfo, callback) {
39
+ return this.subscribeOnMessage(deviceInfo, mqttApiContracts_1.MqttTopicType.SetReply, callback);
40
+ }
41
+ async sendSetCommand(deviceInfo, message) {
42
+ const client = await this.connect(deviceInfo);
43
+ if (client?.isConnected() && client.client) {
44
+ const topic = `/open/${client.certificateData.certificateAccount}/${deviceInfo.config.serialNumber}/set`;
45
+ try {
46
+ await client.client.publishAsync(topic, JSON.stringify(message));
47
+ deviceInfo.log.debug(`Published to topic '${topic}':`, message);
48
+ }
49
+ catch (err) {
50
+ deviceInfo.log.error(`Publishing to topic '${topic}' of message '${JSON.stringify(message)}' was failed:`, err);
51
+ }
52
+ }
53
+ }
54
+ async connect(deviceInfo) {
55
+ const mqttClientContainer = await this.acquireCertificate(deviceInfo);
56
+ if (mqttClientContainer && !mqttClientContainer.client) {
57
+ const machineId = await this.machineIdProvider.getMachineId(deviceInfo.log);
58
+ const clientId = `HOMEBRIDGE_${machineId.toUpperCase()}_${mqttClientContainer.certificateData.certificateAccount}`;
59
+ try {
60
+ const certificateData = mqttClientContainer.certificateData;
61
+ const client = await this.connectMqttClient(`${certificateData.protocol}://${certificateData.url}:${certificateData.port}`, {
62
+ username: `${certificateData.certificateAccount}`,
63
+ password: `${certificateData.certificatePassword}`,
64
+ clientId,
65
+ protocolVersion: 5,
66
+ }, deviceInfo);
67
+ deviceInfo.log.info('Connected to EcoFlow MQTT Service');
68
+ mqttClientContainer.client = client;
69
+ client.on('message', (topic, message) => {
70
+ const mqttMessage = JSON.parse(message.toString());
71
+ this.processReceivedMessage(mqttClientContainer, topic, mqttMessage);
72
+ });
73
+ }
74
+ catch (err) {
75
+ deviceInfo.log.error('Connection to EcoFlow MQTT Service was failed', err);
76
+ }
77
+ }
78
+ mqttClientContainer?.addDevice(deviceInfo.config, deviceInfo.log);
79
+ return mqttClientContainer;
80
+ }
81
+ async connectMqttClient(brokerUrl, options, deviceInfo) {
82
+ if (deviceInfo.config.simulate === true) {
83
+ return new mockMqttClient_1.MockMqttClient(deviceInfo, options);
84
+ }
85
+ return await mqtt_1.default.connectAsync(brokerUrl, options);
86
+ }
87
+ async subscribeOnTopic(deviceInfo, topicType) {
88
+ const client = await this.connect(deviceInfo);
89
+ if (client?.isConnected() && client.client) {
90
+ const topic = `/open/${client.certificateData.certificateAccount}/${deviceInfo.config.serialNumber}/${topicType}`;
91
+ try {
92
+ await client.client.subscribeAsync(topic);
93
+ deviceInfo.log.debug('Subscribed to topic:', topic);
94
+ return true;
95
+ }
96
+ catch (err) {
97
+ deviceInfo.log.error(`Subscribing to topic '${topic}' was failed:`, err);
98
+ }
99
+ }
100
+ return false;
101
+ }
102
+ subscribeOnMessage(deviceInfo, topicType, callback) {
103
+ return this.getMqttClientContainer(deviceInfo)
104
+ ?.getDevices(deviceInfo.config.serialNumber)
105
+ .find(device => device.config.name === deviceInfo.config.name)
106
+ ?.subscribeOnMessage(topicType, callback);
107
+ }
108
+ processReceivedMessage(container, topic, message) {
109
+ const { serialNumber, topicType } = this.parseTopic(topic);
110
+ const devices = container.getDevices(serialNumber);
111
+ devices.forEach(device => device.processReceivedMessage(topicType, message));
112
+ }
113
+ async acquireCertificate(deviceInfo) {
114
+ let mqttClientContainer = this.getMqttClientContainer(deviceInfo);
115
+ if (mqttClientContainer) {
116
+ return mqttClientContainer;
117
+ }
118
+ let certificateData = null;
119
+ if (deviceInfo.config.simulate === true) {
120
+ certificateData = {
121
+ certificateAccount: deviceInfo.config.accessKey,
122
+ certificatePassword: deviceInfo.config.secretKey,
123
+ port: '8883',
124
+ protocol: 'mqtts',
125
+ url: 'fake',
126
+ };
127
+ }
128
+ else {
129
+ certificateData = await this.httpApiManager.acquireCertificate(deviceInfo);
130
+ }
131
+ if (certificateData) {
132
+ mqttClientContainer = new mqttClientContainer_1.MqttClientContainer(certificateData);
133
+ this.mqttClientContainers[deviceInfo.connectionKey] = mqttClientContainer;
134
+ return mqttClientContainer;
135
+ }
136
+ return null;
137
+ }
138
+ getMqttClientContainer(deviceInfo) {
139
+ if (deviceInfo.connectionKey in this.mqttClientContainers) {
140
+ return this.mqttClientContainers[deviceInfo.connectionKey];
141
+ }
142
+ return null;
143
+ }
144
+ parseTopic(topic) {
145
+ const parts = topic.split('/');
146
+ const topicType = parts.pop();
147
+ const serialNumber = parts.pop();
148
+ return { serialNumber, topicType };
149
+ }
150
+ }
151
+ exports.EcoFlowMqttApiManager = EcoFlowMqttApiManager;
152
+ //# sourceMappingURL=ecoFlowMqttApiManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecoFlowMqttApiManager.js","sourceRoot":"","sources":["../../src/apis/ecoFlowMqttApiManager.ts"],"names":[],"mappings":";;;;;;AACA,sFAAmF;AAGnF,gFAAuG;AACvG,6EAA0E;AAG1E,gDAAwB;AAGxB,MAAa,qBAAqB;IAIb;IACA;IAJF,oBAAoB,GAA+C,EAAE,CAAC;IAEvF,YACmB,cAAqC,EACrC,iBAAoC;QADpC,mBAAc,GAAd,cAAc,CAAuB;QACrC,sBAAiB,GAAjB,iBAAiB,CAAmB;IACpD,CAAC;IAEG,KAAK,CAAC,OAAO;QAClB,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACtD,MAAM,mBAAmB,GAAG,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;YACrE,MAAM,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACxD,MAAM,OAAO,GAAG,mBAAmB,CAAC,aAAa,EAAE,CAAC;YACpD,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC;YAE5E,MAAM,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;YAC7C,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAEM,qBAAqB,CAAC,UAAsB;QACjD,OAAO,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,gCAAa,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IAEM,wBAAwB,CAAC,UAAsB;QACpD,OAAO,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,gCAAa,CAAC,QAAQ,CAAC,CAAC;IACnE,CAAC;IAEM,uBAAuB,CAC5B,UAAsB,EACtB,QAAqC;QAErC,OAAO,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,gCAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC5E,CAAC;IAEM,0BAA0B,CAC/B,UAAsB,EACtB,QAAqC;QAErC,OAAO,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,gCAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/E,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,UAAsB,EAAE,OAAuB;QACzE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,MAAM,EAAE,WAAW,EAAE,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,SAAS,MAAM,CAAC,eAAe,CAAC,kBAAkB,IAAI,UAAU,CAAC,MAAM,CAAC,YAAY,MAAM,CAAC;YACzG,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;gBACjE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,uBAAuB,KAAK,IAAI,EAAE,OAAO,CAAC,CAAC;YAClE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,wBAAwB,KAAK,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;YAClH,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,UAAsB;QAC1C,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACtE,IAAI,mBAAmB,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,CAAC;YACvD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAC5E,MAAM,QAAQ,GAAG,cAAc,SAAS,CAAC,WAAW,EAAE,IAAI,mBAAmB,CAAC,eAAe,CAAC,kBAAkB,EAAE,CAAC;YACnH,IAAI,CAAC;gBACH,MAAM,eAAe,GAAG,mBAAmB,CAAC,eAAe,CAAC;gBAC5D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,iBAAiB,CACzC,GAAG,eAAe,CAAC,QAAQ,MAAM,eAAe,CAAC,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,EAC9E;oBACE,QAAQ,EAAE,GAAG,eAAe,CAAC,kBAAkB,EAAE;oBACjD,QAAQ,EAAE,GAAG,eAAe,CAAC,mBAAmB,EAAE;oBAClD,QAAQ;oBACR,eAAe,EAAE,CAAC;iBACnB,EACD,UAAU,CACX,CAAC;gBACF,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;gBACzD,mBAAmB,CAAC,MAAM,GAAG,MAAM,CAAC;gBACpC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;oBACtC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;oBACnD,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;gBACvE,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,+CAA+C,EAAE,GAAG,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;QACD,mBAAmB,EAAE,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;QAClE,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC7B,SAAiB,EACjB,OAA4B,EAC5B,UAAsB;QAEtB,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YACxC,OAAO,IAAI,+BAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,MAAM,cAAI,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,UAAsB,EAAE,SAAwB;QAC7E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,MAAM,EAAE,WAAW,EAAE,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,SAAS,MAAM,CAAC,eAAe,CAAC,kBAAkB,IAAI,UAAU,CAAC,MAAM,CAAC,YAAY,IAAI,SAAS,EAAE,CAAC;YAClH,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;gBAC1C,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;gBACpD,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,yBAAyB,KAAK,eAAe,EAAE,GAAG,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,kBAAkB,CACxB,UAAsB,EACtB,SAAwB,EACxB,QAAqC;QAErC,OAAO,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC;YAC5C,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC;aAC3C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC;YAC9D,EAAE,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAEO,sBAAsB,CAAC,SAA8B,EAAE,KAAa,EAAE,OAAoB;QAChG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACnD,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/E,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,UAAsB;QACrD,IAAI,mBAAmB,GAAG,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;QAClE,IAAI,mBAAmB,EAAE,CAAC;YACxB,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QACD,IAAI,eAAe,GAAkC,IAAI,CAAC;QAC1D,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YACxC,eAAe,GAAG;gBAChB,kBAAkB,EAAE,UAAU,CAAC,MAAM,CAAC,SAAS;gBAC/C,mBAAmB,EAAE,UAAU,CAAC,MAAM,CAAC,SAAS;gBAChD,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,OAAO;gBACjB,GAAG,EAAE,MAAM;aACZ,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,eAAe,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,eAAe,EAAE,CAAC;YACpB,mBAAmB,GAAG,IAAI,yCAAmB,CAAC,eAAe,CAAC,CAAC;YAC/D,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,aAAa,CAAC,GAAG,mBAAmB,CAAC;YAC1E,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,sBAAsB,CAAC,UAAsB;QACnD,IAAI,UAAU,CAAC,aAAa,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC1D,OAAO,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,UAAU,CAAC,KAAa;QAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,EAAmB,CAAC;QAC/C,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QACjC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;IACrC,CAAC;CACF;AAvKD,sDAuKC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ export declare enum HttpMethod {
2
+ Get = "GET",
3
+ Post = "POST"
4
+ }
5
+ export interface CmdResponse {
6
+ code: string;
7
+ message: string;
8
+ failed: boolean;
9
+ }
10
+ export interface CmdResponseWithData<TData> extends CmdResponse {
11
+ code: string;
12
+ message: string;
13
+ data: TData;
14
+ }
15
+ export interface GetCmdRequest {
16
+ sn: string;
17
+ }
18
+ export interface GetQuotasCmdRequest extends GetCmdRequest {
19
+ params: GetQuotasCmdRequestParams;
20
+ }
21
+ export interface GetQuotasCmdRequestParams {
22
+ quotas: string[];
23
+ }
24
+ export interface AcquireCertificateData {
25
+ certificateAccount: string;
26
+ certificatePassword: string;
27
+ url: string;
28
+ port: string;
29
+ protocol: string;
30
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpMethod = void 0;
4
+ var HttpMethod;
5
+ (function (HttpMethod) {
6
+ HttpMethod["Get"] = "GET";
7
+ HttpMethod["Post"] = "POST";
8
+ })(HttpMethod || (exports.HttpMethod = HttpMethod = {}));
9
+ //# sourceMappingURL=httpApiContracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpApiContracts.js","sourceRoot":"","sources":["../../../src/apis/interfaces/httpApiContracts.ts"],"names":[],"mappings":";;;AAAA,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,yBAAW,CAAA;IACX,2BAAa,CAAA;AACf,CAAC,EAHW,UAAU,0BAAV,UAAU,QAGrB"}
@@ -0,0 +1,26 @@
1
+ export interface MqttMessage {
2
+ }
3
+ export interface MqttQuotaMessage extends MqttMessage {
4
+ }
5
+ export interface MqttQuotaMessageWithParams<TParams> extends MqttQuotaMessage {
6
+ params: TParams;
7
+ }
8
+ export interface MqttQuotaMessageWithParam<TParams> extends MqttQuotaMessage {
9
+ param: TParams;
10
+ }
11
+ export interface MqttSetMessage extends MqttMessage {
12
+ id: number;
13
+ version: string;
14
+ }
15
+ export interface MqttSetMessageWithParams<TParams> extends MqttSetMessage {
16
+ params: TParams;
17
+ }
18
+ export interface MqttSetReplyMessage extends MqttSetMessage {
19
+ data: {
20
+ ack: boolean;
21
+ };
22
+ }
23
+ export declare enum MqttTopicType {
24
+ Quota = "quota",
25
+ SetReply = "set_reply"
26
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MqttTopicType = void 0;
4
+ var MqttTopicType;
5
+ (function (MqttTopicType) {
6
+ MqttTopicType["Quota"] = "quota";
7
+ MqttTopicType["SetReply"] = "set_reply";
8
+ })(MqttTopicType || (exports.MqttTopicType = MqttTopicType = {}));
9
+ //# sourceMappingURL=mqttApiContracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mqttApiContracts.js","sourceRoot":"","sources":["../../../src/apis/interfaces/mqttApiContracts.ts"],"names":[],"mappings":";;;AA2BA,IAAY,aAGX;AAHD,WAAY,aAAa;IACvB,gCAAe,CAAA;IACf,uCAAsB,CAAA;AACxB,CAAC,EAHW,aAAa,6BAAb,aAAa,QAGxB"}
@@ -0,0 +1,15 @@
1
+ import { DeviceInfo } from '@ecoflow/apis/containers/deviceInfo';
2
+ import { IClientOptions, ISubscriptionGrant, MqttClient, Packet } from 'mqtt';
3
+ export declare class MockMqttClient extends MqttClient {
4
+ private readonly deviceInfo;
5
+ private emitQuotaTimeoutId;
6
+ private readonly subscriptionTopics;
7
+ private readonly simulator;
8
+ constructor(deviceInfo: DeviceInfo, options: IClientOptions);
9
+ connect(): this;
10
+ endAsync(): Promise<void>;
11
+ subscribeAsync(topic: string): Promise<ISubscriptionGrant[]>;
12
+ publishAsync(topic: string, message: string): Promise<Packet | undefined>;
13
+ private emitQuota;
14
+ private emitMessage;
15
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MockMqttClient = void 0;
4
+ const mqtt_1 = require("mqtt");
5
+ class MockMqttClient extends mqtt_1.MqttClient {
6
+ deviceInfo;
7
+ emitQuotaTimeoutId = null;
8
+ subscriptionTopics = [];
9
+ simulator;
10
+ constructor(deviceInfo, options) {
11
+ super(undefined, options);
12
+ this.deviceInfo = deviceInfo;
13
+ this.deviceInfo.log.warn('Simulating MQTT');
14
+ this.simulator = deviceInfo.config.simulator ? new deviceInfo.config.simulator() : null;
15
+ }
16
+ connect() {
17
+ this.connected = true;
18
+ return this;
19
+ }
20
+ async endAsync() {
21
+ if (this.emitQuotaTimeoutId !== null) {
22
+ clearTimeout(this.emitQuotaTimeoutId);
23
+ this.emitQuotaTimeoutId = null;
24
+ }
25
+ }
26
+ async subscribeAsync(topic) {
27
+ this.subscriptionTopics.push(topic);
28
+ if (topic.endsWith('quota')) {
29
+ this.emitQuotaTimeoutId = setInterval(() => {
30
+ this.emitQuota();
31
+ }, this.deviceInfo.config.simulateQuotaTimeoutMs ?? 10000);
32
+ }
33
+ return [];
34
+ }
35
+ async publishAsync(topic, message) {
36
+ if (this.simulator && topic.endsWith('set')) {
37
+ const replyTopic = `${topic}_reply`;
38
+ if (this.subscriptionTopics.includes(replyTopic)) {
39
+ const responseMessage = this.simulator.generateSetReply(message);
40
+ this.emitMessage(replyTopic, responseMessage);
41
+ }
42
+ }
43
+ return undefined;
44
+ }
45
+ emitQuota() {
46
+ if (this.simulator) {
47
+ this.subscriptionTopics
48
+ .filter(topic => topic.endsWith('quota'))
49
+ .forEach(topic => {
50
+ this.emitMessage(topic, this.simulator.generateQuota());
51
+ });
52
+ }
53
+ }
54
+ emitMessage(topic, message) {
55
+ this.emit('message', topic, Buffer.from(JSON.stringify(message)), undefined);
56
+ }
57
+ }
58
+ exports.MockMqttClient = MockMqttClient;
59
+ //# sourceMappingURL=mockMqttClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockMqttClient.js","sourceRoot":"","sources":["../../../src/apis/simulations/mockMqttClient.ts"],"names":[],"mappings":";;;AAEA,+BAA6G;AAE7G,MAAa,cAAe,SAAQ,iBAAU;IAMzB;IALX,kBAAkB,GAA0B,IAAI,CAAC;IACxC,kBAAkB,GAAa,EAAE,CAAC;IAClC,SAAS,CAAmB;IAE7C,YACmB,UAAsB,EACvC,OAAuB;QAEvB,KAAK,CAAC,SAAqC,EAAE,OAAO,CAAC,CAAC;QAHrC,eAAU,GAAV,UAAU,CAAY;QAIvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC5C,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1F,CAAC;IAEe,OAAO;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAEe,KAAK,CAAC,QAAQ;QAC5B,IAAI,IAAI,CAAC,kBAAkB,KAAK,IAAI,EAAE,CAAC;YACrC,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YACtC,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QACjC,CAAC;IACH,CAAC;IAEe,KAAK,CAAC,cAAc,CAAC,KAAa;QAChD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEpC,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE;gBACzC,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,sBAAsB,IAAI,KAAK,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAEe,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,OAAe;QAC/D,IAAI,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,MAAM,UAAU,GAAG,GAAG,KAAK,QAAQ,CAAC;YACpC,IAAI,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBACjD,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;gBACjE,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,SAAS;QACf,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC,kBAAkB;iBACpB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;iBACxC,OAAO,CAAC,KAAK,CAAC,EAAE;gBACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,SAAU,CAAC,aAAa,EAAE,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;QACP,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,KAAa,EAAE,OAAe;QAChD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,SAAsC,CAAC,CAAC;IAC5G,CAAC;CACF;AA9DD,wCA8DC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import { MqttSetMessage } from '@ecoflow/apis/interfaces/mqttApiContracts';
2
+ export declare abstract class Simulator {
3
+ abstract generateQuota(): object;
4
+ abstract generateSetReply(message: string): object;
5
+ protected getRandomNumber(min: number, max: number): number;
6
+ protected getRandomBoolean(): boolean;
7
+ }
8
+ export declare abstract class SimulatorTyped<TSetMessage extends MqttSetMessage> extends Simulator {
9
+ generateSetReply(message: string): object;
10
+ abstract generateSetReplyTyped(message: TSetMessage): object;
11
+ protected getRandomNumber(min: number, max: number): number;
12
+ protected getRandomBoolean(): boolean;
13
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SimulatorTyped = exports.Simulator = void 0;
4
+ class Simulator {
5
+ getRandomNumber(min, max) {
6
+ return Math.random() * (max - min) + min;
7
+ }
8
+ getRandomBoolean() {
9
+ return Math.random() < 0.5;
10
+ }
11
+ }
12
+ exports.Simulator = Simulator;
13
+ class SimulatorTyped extends Simulator {
14
+ generateSetReply(message) {
15
+ const msgObj = JSON.parse(message);
16
+ return this.generateSetReplyTyped(msgObj);
17
+ }
18
+ getRandomNumber(min, max) {
19
+ return Math.random() * (max - min) + min;
20
+ }
21
+ getRandomBoolean() {
22
+ return Math.random() < 0.5;
23
+ }
24
+ }
25
+ exports.SimulatorTyped = SimulatorTyped;
26
+ //# sourceMappingURL=simulator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulator.js","sourceRoot":"","sources":["../../../src/apis/simulations/simulator.ts"],"names":[],"mappings":";;;AAEA,MAAsB,SAAS;IAInB,eAAe,CAAC,GAAW,EAAE,GAAW;QAChD,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3C,CAAC;IAES,gBAAgB;QACxB,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC;IAC7B,CAAC;CACF;AAXD,8BAWC;AAED,MAAsB,cAAmD,SAAQ,SAAS;IACxE,gBAAgB,CAAC,OAAe;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;QAClD,OAAO,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAIS,eAAe,CAAC,GAAW,EAAE,GAAW;QAChD,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3C,CAAC;IAES,gBAAgB;QACxB,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC;IAC7B,CAAC;CACF;AAfD,wCAeC"}