homebridge-gree-ac 2.2.2 → 2.3.0-beta.2

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.
@@ -1,3 +1,4 @@
1
+ import dgram from 'dgram';
1
2
  import type { CharacteristicValue } from 'homebridge';
2
3
  import type { GreeACPlatform, MyPlatformAccessory } from './platform.js';
3
4
  import { DeviceConfig } from './settings.js';
@@ -9,24 +10,23 @@ import type { CommandValueMap, Commands } from './commands.js';
9
10
  */
10
11
  export declare class GreeAirConditioner {
11
12
  private readonly platform;
12
- private readonly accessory;
13
- private readonly deviceConfig;
13
+ readonly accessory: MyPlatformAccessory;
14
+ readonly deviceConfig: DeviceConfig;
14
15
  private readonly tsAccessoryMac;
16
+ private readonly socket;
15
17
  private HeaterCooler?;
16
18
  private TemperatureSensor?;
17
19
  private Fan?;
18
- private socket;
19
- private key?;
20
+ key?: string;
20
21
  private cols?;
21
22
  private status;
22
23
  private tsAccessory;
23
24
  private powerPending;
24
25
  private modePending;
25
26
  private silentTimeRanges?;
26
- constructor(platform: GreeACPlatform, accessory: MyPlatformAccessory, deviceConfig: DeviceConfig, tsAccessoryMac: string);
27
+ constructor(platform: GreeACPlatform, accessory: MyPlatformAccessory, deviceConfig: DeviceConfig, tsAccessoryMac: string, socket: dgram.Socket);
27
28
  initCharacteristics(): void;
28
29
  initAccessory(): void;
29
- checkBindingStatus(bindNo: number): void;
30
30
  /**
31
31
  * Handle "SET" requests from HomeKit
32
32
  * These are sent when the user changes the state of an accessory, for example, turning on a Light bulb.
@@ -102,7 +102,6 @@ export declare class GreeAirConditioner {
102
102
  size: number;
103
103
  }) => void;
104
104
  sendMessage(message: unknown): void;
105
- sendBindRequest(): void;
106
105
  sendCommand(cmd: Record<string, unknown>): void;
107
106
  requestDeviceStatus(): void;
108
107
  }
@@ -1,5 +1,4 @@
1
- import dgram from 'dgram';
2
- import { PLATFORM_NAME, PLUGIN_NAME, TEMPERATURE_TABLE, MODIFY_VERTICAL_SWING_POSITION, TS_TYPE, BINDING_TIMEOUT, TEMPERATURE_LIMITS, DEFAULT_DEVICE_CONFIG } from './settings.js';
1
+ import { PLATFORM_NAME, PLUGIN_NAME, TEMPERATURE_TABLE, MODIFY_VERTICAL_SWING_POSITION, TS_TYPE, TEMPERATURE_LIMITS, DEFAULT_DEVICE_CONFIG } from './settings.js';
3
2
  import { GreeAirConditionerTS } from './tsAccessory.js';
4
3
  import crypto from './crypto.js';
5
4
  import commands from './commands.js';
@@ -13,10 +12,10 @@ export class GreeAirConditioner {
13
12
  accessory;
14
13
  deviceConfig;
15
14
  tsAccessoryMac;
15
+ socket;
16
16
  HeaterCooler;
17
17
  TemperatureSensor;
18
18
  Fan;
19
- socket;
20
19
  key;
21
20
  cols;
22
21
  status;
@@ -24,14 +23,16 @@ export class GreeAirConditioner {
24
23
  powerPending = -1;
25
24
  modePending = -1;
26
25
  silentTimeRanges;
27
- constructor(platform, accessory, deviceConfig, tsAccessoryMac) {
26
+ constructor(platform, accessory, deviceConfig, tsAccessoryMac, socket) {
28
27
  this.platform = platform;
29
28
  this.accessory = accessory;
30
29
  this.deviceConfig = deviceConfig;
31
30
  this.tsAccessoryMac = tsAccessoryMac;
31
+ this.socket = socket;
32
32
  // platform, accessory and service initialization is implemented in a separate funcion (initAccessory), because
33
33
  // it should be made only on successful binding with network device
34
34
  this.platform.log.debug(`[${this.getDeviceLabel()}] deviceConfig -> %j`, deviceConfig);
35
+ this.status = {};
35
36
  // calculate silent time ranges
36
37
  if (deviceConfig.silentTimeRange) {
37
38
  const time1 = +(deviceConfig.silentTimeRange.substring(0, 5).replace(':', ''));
@@ -48,27 +49,6 @@ export class GreeAirConditioner {
48
49
  else {
49
50
  this.platform.log.debug(`[${this.getDeviceLabel()}] silentTimeRanges: No silentTimeRange is defined`);
50
51
  }
51
- // initialize communication with device
52
- this.status = {};
53
- this.socket = dgram.createSocket({ type: 'udp4', reuseAddr: true });
54
- this.socket.on('error', (err) => {
55
- this.platform.log.error(`[${this.getDeviceLabel()}] Network - Error:`, err.message);
56
- });
57
- this.socket.on('message', this.handleMessage);
58
- this.socket.on('close', () => {
59
- this.platform.log.error(`[${this.getDeviceLabel()}] Network - Connection closed`);
60
- });
61
- if (this.platform.ports.indexOf(this.deviceConfig.port || 0) >= 0) {
62
- this.platform.log.warn(`[${this.getDeviceLabel()}] Warning: Configured port (%i) is already used - replacing with auto assigned port`, this.deviceConfig.port);
63
- this.deviceConfig.port = undefined;
64
- }
65
- this.socket.bind(this.deviceConfig.port, undefined, () => {
66
- this.platform.log.info(`[${this.getDeviceLabel()}] Device handler is listening on UDP port %d`, this.socket.address().port);
67
- this.platform.ports.push(this.socket.address().port);
68
- this.socket.setBroadcast(false);
69
- this.sendBindRequest();
70
- setTimeout(this.checkBindingStatus.bind(this, 1), BINDING_TIMEOUT);
71
- });
72
52
  }
73
53
  initCharacteristics() {
74
54
  // these characteristic properties are not updated by HomeKit, they are initialized only once
@@ -261,29 +241,6 @@ export class GreeAirConditioner {
261
241
  this.HeaterCooler.getCharacteristic(this.platform.Characteristic.Name)
262
242
  .onGet(this.getName.bind(this));
263
243
  }
264
- // this function is a callback to check the status of binding after timeout period has ellapsed
265
- checkBindingStatus(bindNo) {
266
- if (!this.accessory.bound) {
267
- this.platform.log.debug(`[${this.getDeviceLabel()}] Device binding timeout`);
268
- switch (bindNo) {
269
- case 1: {
270
- // 1. timeout -> repeat bind request with alternate encryption version
271
- if (this.accessory.context.device.encryptionVersion === 1) {
272
- this.accessory.context.device.encryptionVersion = 2;
273
- }
274
- else {
275
- this.accessory.context.device.encryptionVersion = 1;
276
- }
277
- this.sendBindRequest();
278
- setTimeout(this.checkBindingStatus.bind(this, bindNo + 1), BINDING_TIMEOUT);
279
- break;
280
- }
281
- default: {
282
- this.platform.log.error(`[${this.getDeviceLabel()}] Error: Device is not bound`, '(unknown device type or device is malfunctioning [turning the power supply off and on may help])', '- Restart homebridge when issue has fixed!');
283
- }
284
- }
285
- }
286
- }
287
244
  /**
288
245
  * Handle "SET" requests from HomeKit
289
246
  * These are sent when the user changes the state of an accessory, for example, turning on a Light bulb.
@@ -1583,19 +1540,7 @@ export class GreeAirConditioner {
1583
1540
  this.platform.log.debug(`[${this.getDeviceLabel()}] handleMessage - Package -> %j`, pack);
1584
1541
  switch (pack.t.toLowerCase()) {
1585
1542
  case 'bindok': // package type is binding confirmation
1586
- if (!this.accessory.bound) {
1587
- this.platform.log.debug(`[${this.getDeviceLabel()}] Device binding in progress`);
1588
- this.key = pack.key;
1589
- this.initAccessory();
1590
- this.accessory.bound = true;
1591
- this.platform.log.success(`[${this.getDeviceLabel()}] Device is bound -> ${pack.mac} (`, (this.accessory.context.device.uid ?? 0).toString(), ')');
1592
- this.platform.log.debug(`[${this.getDeviceLabel()}] Device key -> ${this.key}`);
1593
- this.requestDeviceStatus();
1594
- setInterval(this.requestDeviceStatus.bind(this), this.deviceConfig.statusUpdateInterval * 1000); // statusUpdateInterval in seconds
1595
- }
1596
- else {
1597
- this.platform.log.debug(`[${this.getDeviceLabel()}] Binding response received from already bound device`);
1598
- }
1543
+ this.platform.log.warn(`[${this.getDeviceLabel()}] Warning: Binding response received from already bound device`);
1599
1544
  break;
1600
1545
  case 'dat': // package type is device status
1601
1546
  if (this.accessory.bound) {
@@ -1697,15 +1642,15 @@ export class GreeAirConditioner {
1697
1642
  return;
1698
1643
  }
1699
1644
  const payload = (tag === '') ? {
1700
- tcid: this.accessory.context.device.mac.substring(this.accessory.context.device.mac.indexOf('@') + 1),
1701
- uid: this.accessory.context.device.uid ?? 0,
1645
+ tcid: this.accessory.context.device.mac,
1646
+ uid: 0,
1702
1647
  t: 'pack',
1703
1648
  pack,
1704
1649
  i: this.key === undefined ? 1 : 0,
1705
1650
  cid: 'app',
1706
1651
  } : {
1707
- tcid: this.accessory.context.device.mac.substring(this.accessory.context.device.mac.indexOf('@') + 1),
1708
- uid: this.accessory.context.device.uid ?? 0,
1652
+ tcid: this.accessory.context.device.mac,
1653
+ uid: 0,
1709
1654
  t: 'pack',
1710
1655
  pack,
1711
1656
  i: this.key === undefined ? 1 : 0,
@@ -1721,16 +1666,6 @@ export class GreeAirConditioner {
1721
1666
  this.platform.log.error(`[${this.getDeviceLabel()}] sendMessage - Error:`, err.message);
1722
1667
  }
1723
1668
  }
1724
- sendBindRequest() {
1725
- const message = {
1726
- mac: this.accessory.context.device.mac.substring(this.accessory.context.device.mac.indexOf('@') + 1),
1727
- t: 'bind',
1728
- uid: this.accessory.context.device.mac.indexOf('@') < 0 ? 0 :
1729
- this.accessory.context.device.mac.substring(0, this.accessory.context.device.mac.indexOf('@')),
1730
- };
1731
- this.platform.log.debug(`[${this.getDeviceLabel()}] Bind to device -> ${this.accessory.context.device.mac}`);
1732
- this.sendMessage(message);
1733
- }
1734
1669
  sendCommand(cmd) {
1735
1670
  if (this.isSilentTime()) {
1736
1671
  // add buzzer off command if current time is in silent time range