iobroker.tapo 0.3.3 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,6 +32,10 @@ tapo.0.id.remote auf true/false setzen steuert den jeweiligen Befehl. Der Befehl
32
32
  <https://forum.iobroker.net/topic/57336/test-adapter-tp-link-tapo/>
33
33
 
34
34
  ## Changelog
35
+ ### 0.3.4 (2024-11-10)
36
+
37
+ - update Tapo local lib
38
+
35
39
  ### 0.3.3 (2024-06-17)
36
40
 
37
41
  - ignore ssl legacy error
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/energyUsage.ts"],
4
- "sourcesContent": ["export class EnergyUsage{\n current_power!: number;\n}"],
4
+ "sourcesContent": ["export class EnergyUsage{\n current_power!: number;\n}"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,YAAW;AAExB;",
6
6
  "names": []
7
7
  }
@@ -27,7 +27,7 @@ __export(l510e_exports, {
27
27
  default: () => L510E
28
28
  });
29
29
  module.exports = __toCommonJS(l510e_exports);
30
- var import_p100 = __toESM(require("./p100"));
30
+ var import_p100 = __toESM(require("./p100.js"));
31
31
  class L510E extends import_p100.default {
32
32
  constructor(log, ipAddress, email, password, timeout) {
33
33
  super(log, ipAddress, email, password, timeout);
@@ -38,8 +38,8 @@ class L510E extends import_p100.default {
38
38
  this.timeout = timeout;
39
39
  this.log.debug("Constructing L510E on host: " + ipAddress);
40
40
  }
41
- async getDeviceInfo() {
42
- return super.getDeviceInfo().then(() => {
41
+ async getDeviceInfo(force) {
42
+ return super.getDeviceInfo(force).then(() => {
43
43
  return this.getSysInfo();
44
44
  });
45
45
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/l510e.ts"],
4
- "sourcesContent": ["import P100 from \"./p100\";\nimport { LightSysinfo } from \"./types\";\n\nexport default class L510E extends P100 {\n private _lightSysInfo!: LightSysinfo;\n\n constructor(\n public readonly log: any,\n public readonly ipAddress: string,\n public readonly email: string,\n public readonly password: string,\n public readonly timeout: number,\n ) {\n super(log, ipAddress, email, password, timeout);\n this.log.debug(\"Constructing L510E on host: \" + ipAddress);\n }\n\n async getDeviceInfo(): Promise<LightSysinfo> {\n return super.getDeviceInfo().then(() => {\n return this.getSysInfo();\n });\n }\n\n async setBrightness(brightness: number): Promise<boolean> {\n const payload =\n \"{\" +\n '\"method\": \"set_device_info\",' +\n '\"params\": {' +\n '\"brightness\": ' +\n brightness +\n \"},\" +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n\n return this.sendRequest(payload);\n }\n\n protected setSysInfo(sysInfo: LightSysinfo) {\n this._lightSysInfo = sysInfo;\n this._lightSysInfo.last_update = Date.now();\n }\n\n public getSysInfo(): LightSysinfo {\n return this._lightSysInfo;\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAGjB,MAAO,cAA4B,YAAAA,QAAK;AAAA,EAGtC,YACkB,KACA,WACA,OACA,UACA,SAChB;AACA,UAAM,KAAK,WAAW,OAAO,UAAU,OAAO;AAN9B;AACA;AACA;AACA;AACA;AAGhB,SAAK,IAAI,MAAM,iCAAiC,SAAS;AAAA,EAC3D;AAAA,EAEA,MAAM,gBAAuC;AAC3C,WAAO,MAAM,cAAc,EAAE,KAAK,MAAM;AACtC,aAAO,KAAK,WAAW;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,YAAsC;AACxD,UAAM,UACJ,2DAIA,aACA,0BAEA,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAE5B;AAEF,WAAO,KAAK,YAAY,OAAO;AAAA,EACjC;AAAA,EAEU,WAAW,SAAuB;AAC1C,SAAK,gBAAgB;AACrB,SAAK,cAAc,cAAc,KAAK,IAAI;AAAA,EAC5C;AAAA,EAEO,aAA2B;AAChC,WAAO,KAAK;AAAA,EACd;AACF;",
4
+ "sourcesContent": ["import { LightSysinfo } from \"./types.js\";\nimport P100 from \"./p100.js\";\n\nexport default class L510E extends P100 {\n private _lightSysInfo!: LightSysinfo;\n\n constructor(\n public readonly log: any,\n public readonly ipAddress: string,\n public readonly email: string,\n public readonly password: string,\n public readonly timeout: number,\n ) {\n super(log, ipAddress, email, password, timeout);\n this.log.debug(\"Constructing L510E on host: \" + ipAddress);\n }\n\n async getDeviceInfo(force?: boolean): Promise<LightSysinfo> {\n return super.getDeviceInfo(force).then(() => {\n return this.getSysInfo();\n });\n }\n\n async setBrightness(brightness: number): Promise<boolean> {\n const payload =\n \"{\" +\n '\"method\": \"set_device_info\",' +\n '\"params\": {' +\n '\"brightness\": ' +\n brightness +\n \"},\" +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n\n return this.sendRequest(payload);\n }\n\n protected setSysInfo(sysInfo: LightSysinfo) {\n this._lightSysInfo = sysInfo;\n this._lightSysInfo.last_update = Date.now();\n }\n\n public getSysInfo(): LightSysinfo {\n return this._lightSysInfo;\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAiB;AAEjB,MAAO,cAA4B,YAAAA,QAAK;AAAA,EAGtC,YACkB,KACA,WACA,OACA,UACA,SAChB;AACA,UAAM,KAAK,WAAW,OAAO,UAAU,OAAO;AAN9B;AACA;AACA;AACA;AACA;AAGhB,SAAK,IAAI,MAAM,iCAAiC,SAAS;AAAA,EAC3D;AAAA,EAEA,MAAM,cAAc,OAAwC;AAC1D,WAAO,MAAM,cAAc,KAAK,EAAE,KAAK,MAAM;AAC3C,aAAO,KAAK,WAAW;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,YAAsC;AACxD,UAAM,UACJ,2DAIA,aACA,0BAEA,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAE5B;AAEF,WAAO,KAAK,YAAY,OAAO;AAAA,EACjC;AAAA,EAEU,WAAW,SAAuB;AAC1C,SAAK,gBAAgB;AACrB,SAAK,cAAc,cAAc,KAAK,IAAI;AAAA,EAC5C;AAAA,EAEO,aAA2B;AAChC,WAAO,KAAK;AAAA,EACd;AACF;",
6
6
  "names": ["P100"]
7
7
  }
@@ -38,8 +38,8 @@ class L520E extends import_l510e.default {
38
38
  this.timeout = timeout;
39
39
  this.log.debug("Constructing L510E on host: " + ipAddress);
40
40
  }
41
- async getDeviceInfo() {
42
- return super.getDeviceInfo().then(() => {
41
+ async getDeviceInfo(force) {
42
+ return super.getDeviceInfo(force).then(() => {
43
43
  return this.getSysInfo();
44
44
  });
45
45
  }
@@ -48,9 +48,7 @@ class L520E extends import_l510e.default {
48
48
  this.log.debug("Color Temp Tapo :" + transformedColorTemp);
49
49
  const roundedValue = transformedColorTemp > 6500 ? 6500 : transformedColorTemp < 2500 ? 2500 : transformedColorTemp;
50
50
  const payload = '{"method": "set_device_info","params": {"hue": 0,"saturation": 0,"color_temp": ' + roundedValue + '},"requestTimeMils": ' + Math.round(Date.now() * 1e3) + "};";
51
- return this.handleRequest(payload).then(() => {
52
- return true;
53
- });
51
+ return this.sendRequest(payload);
54
52
  }
55
53
  transformColorTemp(value) {
56
54
  return Math.floor(1e6 / value);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/l520e.ts"],
4
- "sourcesContent": ["import L510E from \"./l510e\";\nimport { ColorTempLightSysinfo } from \"./types\";\n\nexport default class L520E extends L510E {\n private _colorTempSysInfo!: ColorTempLightSysinfo;\n\n constructor(\n public readonly log: any,\n public readonly ipAddress: string,\n public readonly email: string,\n public readonly password: string,\n public readonly timeout: number,\n ) {\n super(log, ipAddress, email, password, timeout);\n this.log.debug(\"Constructing L510E on host: \" + ipAddress);\n }\n\n async getDeviceInfo(): Promise<ColorTempLightSysinfo> {\n return super.getDeviceInfo().then(() => {\n return this.getSysInfo();\n });\n }\n\n async setColorTemp(color_temp: number): Promise<true> {\n const transformedColorTemp = this.transformColorTemp(color_temp);\n this.log.debug(\"Color Temp Tapo :\" + transformedColorTemp);\n\n const roundedValue = transformedColorTemp > 6500 ? 6500 : transformedColorTemp < 2500 ? 2500 : transformedColorTemp;\n\n const payload =\n \"{\" +\n '\"method\": \"set_device_info\",' +\n '\"params\": {' +\n '\"hue\": 0,' +\n '\"saturation\": 0,' +\n '\"color_temp\": ' +\n roundedValue +\n \"},\" +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n\n return this.handleRequest(payload).then(() => {\n return true;\n });\n }\n\n private transformColorTemp(value: number) {\n return Math.floor(1000000 / value);\n }\n\n async getColorTemp(): Promise<number> {\n return super.getDeviceInfo().then(() => {\n return this.calculateColorTemp(this.getSysInfo().color_temp);\n });\n }\n\n calculateColorTemp(tapo_color_temp: number) {\n const newValue = this.transformColorTemp(tapo_color_temp);\n return newValue > 400 ? 400 : newValue < 154 ? 154 : newValue;\n }\n\n protected setSysInfo(sysInfo: ColorTempLightSysinfo) {\n this._colorTempSysInfo = sysInfo;\n this._colorTempSysInfo.last_update = Date.now();\n }\n\n public getSysInfo(): ColorTempLightSysinfo {\n return this._colorTempSysInfo;\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAGlB,MAAO,cAA4B,aAAAA,QAAM;AAAA,EAGvC,YACkB,KACA,WACA,OACA,UACA,SAChB;AACA,UAAM,KAAK,WAAW,OAAO,UAAU,OAAO;AAN9B;AACA;AACA;AACA;AACA;AAGhB,SAAK,IAAI,MAAM,iCAAiC,SAAS;AAAA,EAC3D;AAAA,EAEA,MAAM,gBAAgD;AACpD,WAAO,MAAM,cAAc,EAAE,KAAK,MAAM;AACtC,aAAO,KAAK,WAAW;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAAa,YAAmC;AACpD,UAAM,uBAAuB,KAAK,mBAAmB,UAAU;AAC/D,SAAK,IAAI,MAAM,sBAAsB,oBAAoB;AAEzD,UAAM,eAAe,uBAAuB,OAAO,OAAO,uBAAuB,OAAO,OAAO;AAE/F,UAAM,UACJ,oFAMA,eACA,0BAEA,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAE5B;AAEF,WAAO,KAAK,cAAc,OAAO,EAAE,KAAK,MAAM;AAC5C,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEQ,mBAAmB,OAAe;AACxC,WAAO,KAAK,MAAM,MAAU,KAAK;AAAA,EACnC;AAAA,EAEA,MAAM,eAAgC;AACpC,WAAO,MAAM,cAAc,EAAE,KAAK,MAAM;AACtC,aAAO,KAAK,mBAAmB,KAAK,WAAW,EAAE,UAAU;AAAA,IAC7D,CAAC;AAAA,EACH;AAAA,EAEA,mBAAmB,iBAAyB;AAC1C,UAAM,WAAW,KAAK,mBAAmB,eAAe;AACxD,WAAO,WAAW,MAAM,MAAM,WAAW,MAAM,MAAM;AAAA,EACvD;AAAA,EAEU,WAAW,SAAgC;AACnD,SAAK,oBAAoB;AACzB,SAAK,kBAAkB,cAAc,KAAK,IAAI;AAAA,EAChD;AAAA,EAEO,aAAoC;AACzC,WAAO,KAAK;AAAA,EACd;AACF;",
4
+ "sourcesContent": ["import L510E from \"./l510e\";\nimport { ColorTempLightSysinfo } from \"./types\";\n\nexport default class L520E extends L510E {\n\n private _colorTempSysInfo!:ColorTempLightSysinfo;\n\n constructor(\n public readonly log: any,\n public readonly ipAddress: string,\n public readonly email: string,\n public readonly password: string,\n public readonly timeout: number,\n ) {\n super(log, ipAddress, email, password, timeout);\n this.log.debug('Constructing L510E on host: ' + ipAddress);\n }\n\n async getDeviceInfo(force?:boolean): Promise<ColorTempLightSysinfo>{\n return super.getDeviceInfo(force).then(() => {\n return this.getSysInfo();\n });\n }\n\n async setColorTemp(color_temp:number):Promise<boolean>{\n const transformedColorTemp = this.transformColorTemp(color_temp);\n this.log.debug('Color Temp Tapo :' + transformedColorTemp);\n\n const roundedValue = transformedColorTemp > 6500 ? 6500 : transformedColorTemp < 2500 ? \n 2500 : transformedColorTemp;\n\n const payload = '{'+\n '\"method\": \"set_device_info\",'+\n '\"params\": {'+\n '\"hue\": 0,' +\n '\"saturation\": 0,' +\n '\"color_temp\": ' + roundedValue +\n '},'+\n '\"requestTimeMils\": ' + Math.round(Date.now() * 1000) + ''+\n '};';\n\n return this.sendRequest(payload);\n }\n\n private transformColorTemp(value: number):number{\n return Math.floor(1000000 / value);\n }\n\n async getColorTemp(): Promise<number>{\n return super.getDeviceInfo().then(() => {\n return this.calculateColorTemp(this.getSysInfo().color_temp);\n });\n }\n\n calculateColorTemp(tapo_color_temp:number):number{\n const newValue = this.transformColorTemp(tapo_color_temp);\n return newValue > 400 ? 400 : (newValue < 154 ? 154 : newValue);\n }\n\n protected setSysInfo(sysInfo:ColorTempLightSysinfo){\n this._colorTempSysInfo = sysInfo;\n this._colorTempSysInfo.last_update = Date.now();\n }\n\n public getSysInfo():ColorTempLightSysinfo{\n return this._colorTempSysInfo;\n }\n}"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAGlB,MAAO,cAA4B,aAAAA,QAAM;AAAA,EAIvC,YACkB,KACA,WACA,OACA,UACA,SAChB;AACA,UAAM,KAAK,WAAW,OAAO,UAAU,OAAO;AAN9B;AACA;AACA;AACA;AACA;AAGhB,SAAK,IAAI,MAAM,iCAAiC,SAAS;AAAA,EAC3D;AAAA,EAEA,MAAM,cAAc,OAA+C;AACjE,WAAO,MAAM,cAAc,KAAK,EAAE,KAAK,MAAM;AAC3C,aAAO,KAAK,WAAW;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAAa,YAAmC;AACpD,UAAM,uBAAuB,KAAK,mBAAmB,UAAU;AAC/D,SAAK,IAAI,MAAM,sBAAsB,oBAAoB;AAEzD,UAAM,eAAe,uBAAuB,OAAO,OAAO,uBAAuB,OAC/E,OAAO;AAET,UAAM,UAAU,oFAKiB,eACnB,0BACwB,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IACpD;AAEd,WAAO,KAAK,YAAY,OAAO;AAAA,EACjC;AAAA,EAEQ,mBAAmB,OAAqB;AAC9C,WAAO,KAAK,MAAM,MAAU,KAAK;AAAA,EACnC;AAAA,EAEA,MAAM,eAA+B;AACnC,WAAO,MAAM,cAAc,EAAE,KAAK,MAAM;AACtC,aAAO,KAAK,mBAAmB,KAAK,WAAW,EAAE,UAAU;AAAA,IAC7D,CAAC;AAAA,EACH;AAAA,EAEA,mBAAmB,iBAA8B;AAC/C,UAAM,WAAW,KAAK,mBAAmB,eAAe;AACxD,WAAO,WAAW,MAAM,MAAO,WAAW,MAAM,MAAM;AAAA,EACxD;AAAA,EAEU,WAAW,SAA8B;AACjD,SAAK,oBAAoB;AACzB,SAAK,kBAAkB,cAAc,KAAK,IAAI;AAAA,EAChD;AAAA,EAEO,aAAkC;AACvC,WAAO,KAAK;AAAA,EACd;AACF;",
6
6
  "names": ["L510E"]
7
7
  }
@@ -42,8 +42,8 @@ class L530 extends import_l520e.default {
42
42
  current: 0
43
43
  };
44
44
  }
45
- async getDeviceInfo() {
46
- return super.getDeviceInfo().then(() => {
45
+ async getDeviceInfo(force) {
46
+ return super.getDeviceInfo(force).then(() => {
47
47
  return this.getSysInfo();
48
48
  });
49
49
  }
@@ -54,6 +54,7 @@ class L530 extends import_l520e.default {
54
54
  if (!saturation) {
55
55
  saturation = 0;
56
56
  }
57
+ this.log.debug("Setting color: " + hue + ", " + saturation);
57
58
  const payload = '{"method": "set_device_info","params": {"hue": ' + Math.round(hue) + ',"color_temp": 0,"saturation": ' + Math.round(saturation) + '},"requestTimeMils": ' + Math.round(Date.now() * 1e3) + "};";
58
59
  return this.sendRequest(payload);
59
60
  }
@@ -66,33 +67,72 @@ class L530 extends import_l520e.default {
66
67
  }
67
68
  async getEnergyUsage() {
68
69
  const payload = '{"method": "get_device_usage","requestTimeMils": ' + Math.round(Date.now() * 1e3) + "};";
69
- return this.handleRequest(payload).then((response) => {
70
- if (response && response.result) {
71
- this._consumption = {
72
- total: response.result.power_usage.today / 1e3,
73
- current: this._consumption ? response.result.power_usage.today - this._consumption.current : 0
74
- };
75
- } else {
76
- this._consumption = {
77
- total: 0,
78
- current: 0
79
- };
80
- }
81
- return response.result;
82
- }).catch((error) => {
83
- if (error && error.message.indexOf("9999") > 0) {
84
- return this.reconnect().then(() => {
85
- return this.handleRequest(payload).then(() => {
86
- return true;
70
+ this.log.debug("getEnergyUsage called");
71
+ if (this.is_klap) {
72
+ this.log.debug("getEnergyUsage is klap");
73
+ return this.handleKlapRequest(payload).then((response) => {
74
+ this.log.debug("Consumption: " + JSON.stringify(response));
75
+ if (response && response.result) {
76
+ this._consumption = {
77
+ total: response.result.power_usage.today / 1e3,
78
+ current: this._consumption ? response.result.power_usage.today / this.toHours(response.result.time_usage.today) : 0
79
+ };
80
+ } else {
81
+ this._consumption = {
82
+ total: 0,
83
+ current: 0
84
+ };
85
+ }
86
+ return response.result;
87
+ }).catch((error) => {
88
+ if (error.message && error.message.indexOf("9999") > 0) {
89
+ return this.reconnect().then(() => {
90
+ return this.handleKlapRequest(payload).then(() => {
91
+ return true;
92
+ });
87
93
  });
88
- });
89
- }
90
- return false;
91
- });
94
+ }
95
+ return false;
96
+ });
97
+ } else {
98
+ return this.handleRequest(payload).then((response) => {
99
+ this.log.debug("Consumption: " + response);
100
+ if (response && response.result) {
101
+ this._consumption = {
102
+ total: response.result.power_usage.today / 1e3,
103
+ current: this._consumption ? response.result.power_usage.today / this.toHours(response.result.time_usage.today) : 0
104
+ };
105
+ } else {
106
+ this._consumption = {
107
+ total: 0,
108
+ current: 0
109
+ };
110
+ }
111
+ return response.result;
112
+ }).catch((error) => {
113
+ if (error.message && error.message.indexOf("9999") > 0) {
114
+ return this.reconnect().then(() => {
115
+ return this.handleRequest(payload).then(() => {
116
+ return true;
117
+ });
118
+ });
119
+ }
120
+ return false;
121
+ });
122
+ }
92
123
  }
93
124
  getPowerConsumption() {
125
+ if (!this.getSysInfo().device_on) {
126
+ return {
127
+ total: this._consumption.total,
128
+ current: 0
129
+ };
130
+ }
94
131
  return this._consumption;
95
132
  }
133
+ toHours(minutes) {
134
+ return minutes / 60;
135
+ }
96
136
  }
97
137
  // Annotate the CommonJS export names for ESM import in node:
98
138
  0 && (module.exports = {});
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/l530.ts"],
4
- "sourcesContent": ["import L520E from \"./l520e\";\nimport { PowerUsage } from \"./powerUsage\";\nimport { ColorLightSysinfo, ConsumptionInfo } from \"./types\";\n\nexport default class L530 extends L520E {\n private _colorLightSysInfo!: ColorLightSysinfo;\n private _consumption!: ConsumptionInfo;\n\n constructor(\n public readonly log: any,\n public readonly ipAddress: string,\n public readonly email: string,\n public readonly password: string,\n public readonly timeout: number,\n ) {\n super(log, ipAddress, email, password, timeout);\n this.log.debug(\"Constructing L530 on host: \" + ipAddress);\n this._consumption = {\n total: 0,\n current: 0,\n };\n }\n\n async getDeviceInfo(): Promise<ColorLightSysinfo> {\n return super.getDeviceInfo().then(() => {\n return this.getSysInfo();\n });\n }\n\n async setColor(hue: number, saturation: number): Promise<boolean> {\n if (!hue) {\n hue = 0;\n }\n if (!saturation) {\n saturation = 0;\n }\n const payload =\n \"{\" +\n '\"method\": \"set_device_info\",' +\n '\"params\": {' +\n '\"hue\": ' +\n Math.round(hue) +\n \",\" +\n '\"color_temp\": 0,' +\n '\"saturation\": ' +\n Math.round(saturation) +\n \"},\" +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n\n return this.sendRequest(payload);\n }\n\n protected setSysInfo(sysInfo: ColorLightSysinfo) {\n this._colorLightSysInfo = sysInfo;\n this._colorLightSysInfo.last_update = Date.now();\n }\n\n public getSysInfo(): ColorLightSysinfo {\n return this._colorLightSysInfo;\n }\n\n async getEnergyUsage(): Promise<PowerUsage> {\n const payload = \"{\" + '\"method\": \"get_device_usage\",' + '\"requestTimeMils\": ' + Math.round(Date.now() * 1000) + \"\" + \"};\";\n return this.handleRequest(payload)\n .then((response) => {\n if (response && response.result) {\n this._consumption = {\n total: response.result.power_usage.today / 1000,\n current: this._consumption ? response.result.power_usage.today - this._consumption.current : 0,\n };\n } else {\n this._consumption = {\n total: 0,\n current: 0,\n };\n }\n\n return response.result;\n })\n .catch((error) => {\n if (error && error.message.indexOf(\"9999\") > 0) {\n return this.reconnect().then(() => {\n return this.handleRequest(payload).then(() => {\n return true;\n });\n });\n }\n return false;\n });\n }\n\n public getPowerConsumption(): ConsumptionInfo {\n return this._consumption;\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAIlB,MAAO,aAA2B,aAAAA,QAAM;AAAA,EAItC,YACkB,KACA,WACA,OACA,UACA,SAChB;AACA,UAAM,KAAK,WAAW,OAAO,UAAU,OAAO;AAN9B;AACA;AACA;AACA;AACA;AAGhB,SAAK,IAAI,MAAM,gCAAgC,SAAS;AACxD,SAAK,eAAe;AAAA,MAClB,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,MAAM,gBAA4C;AAChD,WAAO,MAAM,cAAc,EAAE,KAAK,MAAM;AACtC,aAAO,KAAK,WAAW;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,SAAS,KAAa,YAAsC;AAChE,QAAI,CAAC,KAAK;AACR,YAAM;AAAA,IACR;AACA,QAAI,CAAC,YAAY;AACf,mBAAa;AAAA,IACf;AACA,UAAM,UACJ,oDAIA,KAAK,MAAM,GAAG,IACd,oCAGA,KAAK,MAAM,UAAU,IACrB,0BAEA,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAE5B;AAEF,WAAO,KAAK,YAAY,OAAO;AAAA,EACjC;AAAA,EAEU,WAAW,SAA4B;AAC/C,SAAK,qBAAqB;AAC1B,SAAK,mBAAmB,cAAc,KAAK,IAAI;AAAA,EACjD;AAAA,EAEO,aAAgC;AACrC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,iBAAsC;AAC1C,UAAM,UAAU,sDAAgE,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAAS;AACrH,WAAO,KAAK,cAAc,OAAO,EAC9B,KAAK,CAAC,aAAa;AAClB,UAAI,YAAY,SAAS,QAAQ;AAC/B,aAAK,eAAe;AAAA,UAClB,OAAO,SAAS,OAAO,YAAY,QAAQ;AAAA,UAC3C,SAAS,KAAK,eAAe,SAAS,OAAO,YAAY,QAAQ,KAAK,aAAa,UAAU;AAAA,QAC/F;AAAA,MACF,OAAO;AACL,aAAK,eAAe;AAAA,UAClB,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF;AAEA,aAAO,SAAS;AAAA,IAClB,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,UAAI,SAAS,MAAM,QAAQ,QAAQ,MAAM,IAAI,GAAG;AAC9C,eAAO,KAAK,UAAU,EAAE,KAAK,MAAM;AACjC,iBAAO,KAAK,cAAc,OAAO,EAAE,KAAK,MAAM;AAC5C,mBAAO;AAAA,UACT,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACL;AAAA,EAEO,sBAAuC;AAC5C,WAAO,KAAK;AAAA,EACd;AACF;",
4
+ "sourcesContent": ["import L520E from \"./l520e\";\nimport { PowerUsage } from \"./powerUsage\";\nimport { ColorLightSysinfo, ConsumptionInfo } from \"./types\";\n\nexport default class L530 extends L520E {\n\n private _colorLightSysInfo!:ColorLightSysinfo;\n private _consumption!:ConsumptionInfo;\n\n constructor(\n public readonly log: any,\n public readonly ipAddress: string,\n public readonly email: string,\n public readonly password: string,\n public readonly timeout: number,\n ) {\n super(log, ipAddress, email, password, timeout);\n this.log.debug('Constructing L530 on host: ' + ipAddress);\n this._consumption = {\n total: 0,\n current: 0,\n };\n }\n\n async getDeviceInfo(force?:boolean): Promise<ColorLightSysinfo>{\n return super.getDeviceInfo(force).then(() => {\n return this.getSysInfo();\n });\n }\n\n async setColor(hue:number, saturation:number):Promise<boolean>{\n if(!hue){\n hue = 0;\n }\n if(!saturation){\n saturation = 0;\n }\n this.log.debug('Setting color: ' + hue + ', ' + saturation);\n const payload = '{'+\n '\"method\": \"set_device_info\",'+\n '\"params\": {'+\n '\"hue\": ' + Math.round(hue) + ','+\n '\"color_temp\": 0,' +\n '\"saturation\": ' + Math.round(saturation) +\n '},'+\n '\"requestTimeMils\": ' + Math.round(Date.now() * 1000) + ''+\n '};';\n\n return this.sendRequest(payload);\n }\n\n protected setSysInfo(sysInfo:ColorLightSysinfo){\n this._colorLightSysInfo = sysInfo;\n this._colorLightSysInfo.last_update = Date.now();\n }\n\n public getSysInfo():ColorLightSysinfo{\n return this._colorLightSysInfo;\n }\n\n async getEnergyUsage():Promise<PowerUsage>{ \n const payload = '{'+\n '\"method\": \"get_device_usage\",'+\n '\"requestTimeMils\": ' + Math.round(Date.now() * 1000) + ''+\n '};';\n this.log.debug('getEnergyUsage called');\n\n if(this.is_klap){\n this.log.debug('getEnergyUsage is klap');\n\n return this.handleKlapRequest(payload).then((response)=>{\n this.log.debug('Consumption: ' + JSON.stringify(response));\n if(response && response.result){\n this._consumption = {\n total: response.result.power_usage.today / 1000,\n current: this._consumption ? response.result.power_usage.today / this.toHours(response.result.time_usage.today) : 0,\n };\n } else{\n this._consumption = {\n total: 0,\n current: 0,\n };\n }\n \n return response.result;\n }).catch((error)=>{\n if(error.message && error.message.indexOf('9999') > 0){\n return this.reconnect().then(()=>{\n return this.handleKlapRequest(payload).then(()=>{\n return true;\n });\n });\n }\n return false;\n });\n }else{\n return this.handleRequest(payload).then((response)=>{\n this.log.debug('Consumption: ' + response);\n if(response && response.result){\n this._consumption = {\n total: response.result.power_usage.today / 1000,\n current: this._consumption ? response.result.power_usage.today / this.toHours(response.result.time_usage.today) : 0,\n };\n } else{\n this._consumption = {\n total: 0,\n current: 0,\n };\n }\n \n return response.result;\n }).catch((error)=>{\n if(error.message && error.message.indexOf('9999') > 0){\n return this.reconnect().then(()=>{\n return this.handleRequest(payload).then(()=>{\n return true;\n });\n });\n }\n return false;\n });\n }\n \n }\n\n public getPowerConsumption():ConsumptionInfo{\n if(!this.getSysInfo().device_on){\n return {\n total: this._consumption.total,\n current: 0,\n };\n }\n return this._consumption;\n }\n\n private toHours(minutes: number):number{\n return minutes/60;\n }\n}"],
5
+ "mappings": "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",
6
6
  "names": ["L520E"]
7
7
  }
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,29 +17,37 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
18
24
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
25
  var newTpLinkCipher_exports = {};
20
26
  __export(newTpLinkCipher_exports, {
21
27
  default: () => NewTpLinkCipher
22
28
  });
23
29
  module.exports = __toCommonJS(newTpLinkCipher_exports);
30
+ var import_crypto = __toESM(require("crypto"));
24
31
  class NewTpLinkCipher {
25
- constructor(localSeed, remoteSeed, authHash) {
26
- this.crypto = require("crypto");
27
- this.calculateKey(localSeed, remoteSeed, authHash);
28
- this.calculateIvSeq(localSeed, remoteSeed, authHash);
29
- this.calculateSig(localSeed, remoteSeed, authHash);
32
+ constructor(localSeed, remoteSeed, authHash, log) {
33
+ this.log = log;
34
+ this._crypto = import_crypto.default;
35
+ if (authHash) {
36
+ this.calculateKey(localSeed, remoteSeed, authHash);
37
+ this.calculateIvSeq(localSeed, remoteSeed, authHash);
38
+ this.calculateSig(localSeed, remoteSeed, authHash);
39
+ }
30
40
  }
31
41
  encrypt(data) {
32
42
  this.seq += 1;
33
43
  if (typeof data === "string") {
34
44
  data = Buffer.from(data, "utf8");
35
45
  }
36
- const cipher = this.crypto.createCipheriv("aes-128-cbc", this.key, this.ivSeqPair());
46
+ const cipher = this._crypto.createCipheriv("aes-128-cbc", this.key, this.ivSeqPair());
37
47
  const cipherText = Buffer.concat([cipher.update(data), cipher.final()]);
38
48
  const seqBuffer = Buffer.alloc(4);
39
49
  seqBuffer.writeInt32BE(this.seq, 0);
40
- const hash = this.crypto.createHash("sha256");
50
+ const hash = this._crypto.createHash("sha256");
41
51
  hash.update(Buffer.concat([this.sig, seqBuffer, cipherText]));
42
52
  const signature = hash.digest();
43
53
  return {
@@ -46,24 +56,35 @@ class NewTpLinkCipher {
46
56
  };
47
57
  }
48
58
  decrypt(data) {
49
- const decipher = this.crypto.createDecipheriv("aes-128-cbc", this.key, this.ivSeqPair());
59
+ const decipher = this._crypto.createDecipheriv("aes-128-cbc", this.key, this.ivSeqPair());
50
60
  const decrypted = Buffer.concat([decipher.update(data.subarray(32)), decipher.final()]);
51
- return decrypted.toString("utf8");
61
+ const dec = decrypted.toString("utf8");
62
+ this.log.debug("decrypted: " + dec);
63
+ let dec_fixed = "";
64
+ if (dec.match(/{"error_code":([-0-9]+)[^,}]$/)) {
65
+ dec_fixed = dec.replace(/{"error_code":([-0-9]+)[^,}]/gm, '{"error_code":"$1"}');
66
+ } else if (dec.match(/{"error_code":([-0-9]+)}$/)) {
67
+ dec_fixed = dec.replace(/{"error_code":([-0-9]+)}$/gm, '{"error_code":"$1"}');
68
+ } else {
69
+ dec_fixed = dec.replace(/{"error_code":([-0-9]+)[^,}](.*)/gm, '{"error_code":"$1",$2');
70
+ }
71
+ this.log.debug("decrypted fixed: " + dec_fixed);
72
+ return dec_fixed;
52
73
  }
53
74
  calculateKey(local_seed, remote_seed, auth_hash) {
54
75
  const buf = Buffer.concat([Buffer.from("lsk"), local_seed, remote_seed, auth_hash]);
55
- const hash = this.crypto.createHash("sha256").update(buf).digest();
76
+ const hash = this._crypto.createHash("sha256").update(buf).digest();
56
77
  this.key = hash.subarray(0, 16);
57
78
  }
58
79
  calculateIvSeq(local_seed, remote_seed, auth_hash) {
59
80
  const buf = Buffer.concat([Buffer.from("iv"), local_seed, remote_seed, auth_hash]);
60
- const ivBuf = this.crypto.createHash("sha256").update(buf).digest();
81
+ const ivBuf = this._crypto.createHash("sha256").update(buf).digest();
61
82
  this.seq = ivBuf.subarray(-4).readInt32BE(0);
62
83
  this.iv = ivBuf.subarray(0, 12);
63
84
  }
64
85
  calculateSig(local_seed, remote_seed, auth_hash) {
65
86
  const payload = Buffer.concat([Buffer.from("ldk"), local_seed, remote_seed, auth_hash]);
66
- this.sig = this.crypto.createHash("sha256").update(payload).digest().subarray(0, 28);
87
+ this.sig = this._crypto.createHash("sha256").update(payload).digest().subarray(0, 28);
67
88
  }
68
89
  ivSeqPair() {
69
90
  const seq = Buffer.alloc(4);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/newTpLinkCipher.ts"],
4
- "sourcesContent": ["export default class NewTpLinkCipher {\n public iv: any;\n public key: any;\n private crypto = require(\"crypto\");\n public sig: any;\n public seq: any;\n\n constructor(localSeed: Buffer, remoteSeed: Buffer, authHash: Buffer) {\n this.calculateKey(localSeed, remoteSeed, authHash);\n this.calculateIvSeq(localSeed, remoteSeed, authHash);\n this.calculateSig(localSeed, remoteSeed, authHash);\n }\n\n public encrypt(data: Buffer | string) {\n this.seq += 1;\n\n if (typeof data === \"string\") {\n data = Buffer.from(data, \"utf8\");\n }\n\n const cipher = this.crypto.createCipheriv(\"aes-128-cbc\", this.key, this.ivSeqPair());\n const cipherText = Buffer.concat([cipher.update(data), cipher.final()]);\n\n const seqBuffer = Buffer.alloc(4);\n seqBuffer.writeInt32BE(this.seq, 0);\n\n const hash = this.crypto.createHash(\"sha256\");\n hash.update(Buffer.concat([this.sig, seqBuffer, cipherText]));\n\n const signature = hash.digest();\n\n return {\n encryptedPayload: Buffer.concat([signature, cipherText]),\n seq: this.seq,\n };\n }\n\n public decrypt(data: Buffer) {\n const decipher = this.crypto.createDecipheriv(\"aes-128-cbc\", this.key, this.ivSeqPair());\n const decrypted = Buffer.concat([decipher.update(data.subarray(32)), decipher.final()]);\n\n return decrypted.toString(\"utf8\");\n }\n\n private calculateKey(local_seed: Buffer, remote_seed: Buffer, auth_hash: Buffer) {\n const buf = Buffer.concat([Buffer.from(\"lsk\"), local_seed, remote_seed, auth_hash]);\n const hash = this.crypto.createHash(\"sha256\").update(buf).digest();\n this.key = hash.subarray(0, 16);\n }\n\n private calculateIvSeq(local_seed: Buffer, remote_seed: Buffer, auth_hash: Buffer) {\n const buf = Buffer.concat([Buffer.from(\"iv\"), local_seed, remote_seed, auth_hash]);\n const ivBuf = this.crypto.createHash(\"sha256\").update(buf).digest();\n this.seq = ivBuf.subarray(-4).readInt32BE(0);\n this.iv = ivBuf.subarray(0, 12);\n }\n\n private calculateSig(local_seed: Buffer, remote_seed: Buffer, auth_hash: Buffer) {\n const payload = Buffer.concat([Buffer.from(\"ldk\"), local_seed, remote_seed, auth_hash]);\n this.sig = this.crypto.createHash(\"sha256\").update(payload).digest().subarray(0, 28);\n }\n\n private ivSeqPair() {\n const seq = Buffer.alloc(4);\n seq.writeInt32BE(this.seq, 0);\n return Buffer.concat([this.iv, seq]);\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAO,gBAA8B;AAAA,EAOnC,YAAY,WAAmB,YAAoB,UAAkB;AAJrE,SAAQ,SAAS,QAAQ,QAAQ;AAK/B,SAAK,aAAa,WAAW,YAAY,QAAQ;AACjD,SAAK,eAAe,WAAW,YAAY,QAAQ;AACnD,SAAK,aAAa,WAAW,YAAY,QAAQ;AAAA,EACnD;AAAA,EAEO,QAAQ,MAAuB;AACpC,SAAK,OAAO;AAEZ,QAAI,OAAO,SAAS,UAAU;AAC5B,aAAO,OAAO,KAAK,MAAM,MAAM;AAAA,IACjC;AAEA,UAAM,SAAS,KAAK,OAAO,eAAe,eAAe,KAAK,KAAK,KAAK,UAAU,CAAC;AACnF,UAAM,aAAa,OAAO,OAAO,CAAC,OAAO,OAAO,IAAI,GAAG,OAAO,MAAM,CAAC,CAAC;AAEtE,UAAM,YAAY,OAAO,MAAM,CAAC;AAChC,cAAU,aAAa,KAAK,KAAK,CAAC;AAElC,UAAM,OAAO,KAAK,OAAO,WAAW,QAAQ;AAC5C,SAAK,OAAO,OAAO,OAAO,CAAC,KAAK,KAAK,WAAW,UAAU,CAAC,CAAC;AAE5D,UAAM,YAAY,KAAK,OAAO;AAE9B,WAAO;AAAA,MACL,kBAAkB,OAAO,OAAO,CAAC,WAAW,UAAU,CAAC;AAAA,MACvD,KAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA,EAEO,QAAQ,MAAc;AAC3B,UAAM,WAAW,KAAK,OAAO,iBAAiB,eAAe,KAAK,KAAK,KAAK,UAAU,CAAC;AACvF,UAAM,YAAY,OAAO,OAAO,CAAC,SAAS,OAAO,KAAK,SAAS,EAAE,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC;AAEtF,WAAO,UAAU,SAAS,MAAM;AAAA,EAClC;AAAA,EAEQ,aAAa,YAAoB,aAAqB,WAAmB;AAC/E,UAAM,MAAM,OAAO,OAAO,CAAC,OAAO,KAAK,KAAK,GAAG,YAAY,aAAa,SAAS,CAAC;AAClF,UAAM,OAAO,KAAK,OAAO,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO;AACjE,SAAK,MAAM,KAAK,SAAS,GAAG,EAAE;AAAA,EAChC;AAAA,EAEQ,eAAe,YAAoB,aAAqB,WAAmB;AACjF,UAAM,MAAM,OAAO,OAAO,CAAC,OAAO,KAAK,IAAI,GAAG,YAAY,aAAa,SAAS,CAAC;AACjF,UAAM,QAAQ,KAAK,OAAO,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO;AAClE,SAAK,MAAM,MAAM,SAAS,EAAE,EAAE,YAAY,CAAC;AAC3C,SAAK,KAAK,MAAM,SAAS,GAAG,EAAE;AAAA,EAChC;AAAA,EAEQ,aAAa,YAAoB,aAAqB,WAAmB;AAC/E,UAAM,UAAU,OAAO,OAAO,CAAC,OAAO,KAAK,KAAK,GAAG,YAAY,aAAa,SAAS,CAAC;AACtF,SAAK,MAAM,KAAK,OAAO,WAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,OAAO,EAAE,SAAS,GAAG,EAAE;AAAA,EACrF;AAAA,EAEQ,YAAY;AAClB,UAAM,MAAM,OAAO,MAAM,CAAC;AAC1B,QAAI,aAAa,KAAK,KAAK,CAAC;AAC5B,WAAO,OAAO,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC;AAAA,EACrC;AACF;",
6
- "names": []
4
+ "sourcesContent": ["import crypto from \"crypto\";\n\nexport default class NewTpLinkCipher {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public iv: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public key: any;\n private _crypto = crypto;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public sig: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public seq: any;\n\n constructor(\n localSeed: Buffer,\n remoteSeed: Buffer,\n authHash: Buffer | undefined,\n public readonly log: any,\n ) {\n if (authHash) {\n this.calculateKey(localSeed, remoteSeed, authHash);\n this.calculateIvSeq(localSeed, remoteSeed, authHash);\n this.calculateSig(localSeed, remoteSeed, authHash);\n }\n }\n\n public encrypt(data: Buffer | string) {\n this.seq += 1;\n\n if (typeof data === \"string\") {\n data = Buffer.from(data, \"utf8\");\n }\n\n const cipher = this._crypto.createCipheriv(\"aes-128-cbc\", this.key, this.ivSeqPair());\n const cipherText = Buffer.concat([cipher.update(data), cipher.final()]);\n\n const seqBuffer = Buffer.alloc(4);\n seqBuffer.writeInt32BE(this.seq, 0);\n\n const hash = this._crypto.createHash(\"sha256\");\n hash.update(Buffer.concat([this.sig, seqBuffer, cipherText]));\n\n const signature = hash.digest();\n\n return {\n encryptedPayload: Buffer.concat([signature, cipherText]),\n seq: this.seq,\n };\n }\n\n public decrypt(data: Buffer) {\n const decipher = this._crypto.createDecipheriv(\"aes-128-cbc\", this.key, this.ivSeqPair());\n const decrypted = Buffer.concat([decipher.update(data.subarray(32)), decipher.final()]);\n\n const dec = decrypted.toString(\"utf8\");\n this.log.debug(\"decrypted: \" + dec);\n\n //Some times the json returned is malformed, or the number returned in error_code\n //is not valid e.g. -0301, so we need to use regex to replace the malformed/invalid json parts\n let dec_fixed = \"\";\n if (dec.match(/{\"error_code\":([-0-9]+)[^,}]$/)) {\n dec_fixed = dec.replace(/{\"error_code\":([-0-9]+)[^,}]/gm, '{\"error_code\":\"$1\"}');\n } else if (dec.match(/{\"error_code\":([-0-9]+)}$/)) {\n dec_fixed = dec.replace(/{\"error_code\":([-0-9]+)}$/gm, '{\"error_code\":\"$1\"}');\n } else {\n dec_fixed = dec.replace(/{\"error_code\":([-0-9]+)[^,}](.*)/gm, '{\"error_code\":\"$1\",$2');\n }\n\n this.log.debug(\"decrypted fixed: \" + dec_fixed);\n\n return dec_fixed;\n }\n\n private calculateKey(local_seed: Buffer, remote_seed: Buffer, auth_hash: Buffer) {\n const buf = Buffer.concat([Buffer.from(\"lsk\"), local_seed, remote_seed, auth_hash]);\n const hash = this._crypto.createHash(\"sha256\").update(buf).digest();\n this.key = hash.subarray(0, 16);\n }\n\n private calculateIvSeq(local_seed: Buffer, remote_seed: Buffer, auth_hash: Buffer) {\n const buf = Buffer.concat([Buffer.from(\"iv\"), local_seed, remote_seed, auth_hash]);\n const ivBuf = this._crypto.createHash(\"sha256\").update(buf).digest();\n this.seq = ivBuf.subarray(-4).readInt32BE(0);\n this.iv = ivBuf.subarray(0, 12);\n }\n\n private calculateSig(local_seed: Buffer, remote_seed: Buffer, auth_hash: Buffer) {\n const payload = Buffer.concat([Buffer.from(\"ldk\"), local_seed, remote_seed, auth_hash]);\n this.sig = this._crypto.createHash(\"sha256\").update(payload).digest().subarray(0, 28);\n }\n\n private ivSeqPair() {\n const seq = Buffer.alloc(4);\n seq.writeInt32BE(this.seq, 0);\n return Buffer.concat([this.iv, seq]);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["crypto"]
7
7
  }