@switchbot/homebridge-switchbot 3.5.0-beta.57 → 3.5.0-beta.59

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 (164) hide show
  1. package/.vscode/settings.json +4 -1
  2. package/dist/device/blindtilt.d.ts +5 -5
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +103 -69
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts +4 -4
  7. package/dist/device/bot.d.ts.map +1 -1
  8. package/dist/device/bot.js +201 -154
  9. package/dist/device/bot.js.map +1 -1
  10. package/dist/device/ceilinglight.d.ts +3 -3
  11. package/dist/device/ceilinglight.d.ts.map +1 -1
  12. package/dist/device/ceilinglight.js +41 -36
  13. package/dist/device/ceilinglight.js.map +1 -1
  14. package/dist/device/colorbulb.d.ts +3 -3
  15. package/dist/device/colorbulb.d.ts.map +1 -1
  16. package/dist/device/colorbulb.js +36 -37
  17. package/dist/device/colorbulb.js.map +1 -1
  18. package/dist/device/contact.d.ts +4 -4
  19. package/dist/device/contact.d.ts.map +1 -1
  20. package/dist/device/contact.js +76 -55
  21. package/dist/device/contact.js.map +1 -1
  22. package/dist/device/curtain.d.ts +4 -4
  23. package/dist/device/curtain.d.ts.map +1 -1
  24. package/dist/device/curtain.js +99 -55
  25. package/dist/device/curtain.js.map +1 -1
  26. package/dist/device/device.d.ts +4 -4
  27. package/dist/device/device.d.ts.map +1 -1
  28. package/dist/device/device.js +11 -9
  29. package/dist/device/device.js.map +1 -1
  30. package/dist/device/fan.d.ts +3 -3
  31. package/dist/device/fan.d.ts.map +1 -1
  32. package/dist/device/fan.js +54 -24
  33. package/dist/device/fan.js.map +1 -1
  34. package/dist/device/hub.d.ts +4 -4
  35. package/dist/device/hub.d.ts.map +1 -1
  36. package/dist/device/hub.js +40 -57
  37. package/dist/device/hub.js.map +1 -1
  38. package/dist/device/humidifier.d.ts +3 -3
  39. package/dist/device/humidifier.d.ts.map +1 -1
  40. package/dist/device/humidifier.js +39 -39
  41. package/dist/device/humidifier.js.map +1 -1
  42. package/dist/device/iosensor.d.ts +3 -3
  43. package/dist/device/iosensor.d.ts.map +1 -1
  44. package/dist/device/iosensor.js +41 -50
  45. package/dist/device/iosensor.js.map +1 -1
  46. package/dist/device/lightstrip.d.ts +4 -4
  47. package/dist/device/lightstrip.d.ts.map +1 -1
  48. package/dist/device/lightstrip.js +36 -33
  49. package/dist/device/lightstrip.js.map +1 -1
  50. package/dist/device/lock.d.ts +3 -3
  51. package/dist/device/lock.d.ts.map +1 -1
  52. package/dist/device/lock.js +68 -59
  53. package/dist/device/lock.js.map +1 -1
  54. package/dist/device/meter.d.ts +3 -3
  55. package/dist/device/meter.d.ts.map +1 -1
  56. package/dist/device/meter.js +42 -51
  57. package/dist/device/meter.js.map +1 -1
  58. package/dist/device/meterplus.d.ts +3 -3
  59. package/dist/device/meterplus.d.ts.map +1 -1
  60. package/dist/device/meterplus.js +42 -51
  61. package/dist/device/meterplus.js.map +1 -1
  62. package/dist/device/motion.d.ts +3 -3
  63. package/dist/device/motion.d.ts.map +1 -1
  64. package/dist/device/motion.js +52 -40
  65. package/dist/device/motion.js.map +1 -1
  66. package/dist/device/plug.d.ts +3 -3
  67. package/dist/device/plug.d.ts.map +1 -1
  68. package/dist/device/plug.js +13 -13
  69. package/dist/device/plug.js.map +1 -1
  70. package/dist/device/robotvacuumcleaner.d.ts +4 -4
  71. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  72. package/dist/device/robotvacuumcleaner.js +81 -98
  73. package/dist/device/robotvacuumcleaner.js.map +1 -1
  74. package/dist/device/waterdetector.d.ts +3 -3
  75. package/dist/device/waterdetector.d.ts.map +1 -1
  76. package/dist/device/waterdetector.js +39 -31
  77. package/dist/device/waterdetector.js.map +1 -1
  78. package/dist/homebridge-ui/public/index.html +20 -14
  79. package/dist/index.d.ts +1 -1
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +1 -1
  82. package/dist/index.js.map +1 -1
  83. package/dist/irdevice/airconditioner.d.ts +3 -3
  84. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  85. package/dist/irdevice/airconditioner.js +9 -9
  86. package/dist/irdevice/airconditioner.js.map +1 -1
  87. package/dist/irdevice/airpurifier.d.ts +3 -3
  88. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  89. package/dist/irdevice/airpurifier.js +1 -1
  90. package/dist/irdevice/airpurifier.js.map +1 -1
  91. package/dist/irdevice/camera.d.ts +3 -3
  92. package/dist/irdevice/camera.d.ts.map +1 -1
  93. package/dist/irdevice/camera.js +2 -2
  94. package/dist/irdevice/camera.js.map +1 -1
  95. package/dist/irdevice/fan.d.ts +6 -6
  96. package/dist/irdevice/fan.d.ts.map +1 -1
  97. package/dist/irdevice/fan.js +37 -29
  98. package/dist/irdevice/fan.js.map +1 -1
  99. package/dist/irdevice/irdevice.d.ts +3 -3
  100. package/dist/irdevice/irdevice.d.ts.map +1 -1
  101. package/dist/irdevice/irdevice.js.map +1 -1
  102. package/dist/irdevice/light.d.ts +9 -14
  103. package/dist/irdevice/light.d.ts.map +1 -1
  104. package/dist/irdevice/light.js +67 -88
  105. package/dist/irdevice/light.js.map +1 -1
  106. package/dist/irdevice/other.d.ts +3 -3
  107. package/dist/irdevice/other.d.ts.map +1 -1
  108. package/dist/irdevice/other.js +1 -1
  109. package/dist/irdevice/other.js.map +1 -1
  110. package/dist/irdevice/tv.d.ts +3 -3
  111. package/dist/irdevice/tv.d.ts.map +1 -1
  112. package/dist/irdevice/tv.js +3 -3
  113. package/dist/irdevice/tv.js.map +1 -1
  114. package/dist/irdevice/vacuumcleaner.d.ts +3 -3
  115. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  116. package/dist/irdevice/vacuumcleaner.js +2 -2
  117. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  118. package/dist/irdevice/waterheater.d.ts +3 -3
  119. package/dist/irdevice/waterheater.d.ts.map +1 -1
  120. package/dist/irdevice/waterheater.js +2 -2
  121. package/dist/irdevice/waterheater.js.map +1 -1
  122. package/dist/platform.d.ts +7 -7
  123. package/dist/platform.d.ts.map +1 -1
  124. package/dist/platform.js +20 -23
  125. package/dist/platform.js.map +1 -1
  126. package/dist/settings.d.ts +24 -10
  127. package/dist/settings.d.ts.map +1 -1
  128. package/dist/settings.js +16 -0
  129. package/dist/settings.js.map +1 -1
  130. package/eslint.config.js +89 -78
  131. package/package.json +3 -3
  132. package/src/device/blindtilt.ts +120 -87
  133. package/src/device/bot.ts +238 -175
  134. package/src/device/ceilinglight.ts +49 -46
  135. package/src/device/colorbulb.ts +40 -43
  136. package/src/device/contact.ts +91 -65
  137. package/src/device/curtain.ts +113 -66
  138. package/src/device/device.ts +12 -13
  139. package/src/device/fan.ts +66 -29
  140. package/src/device/hub.ts +53 -60
  141. package/src/device/humidifier.ts +54 -56
  142. package/src/device/iosensor.ts +57 -56
  143. package/src/device/lightstrip.ts +43 -39
  144. package/src/device/lock.ts +79 -68
  145. package/src/device/meter.ts +54 -54
  146. package/src/device/meterplus.ts +54 -54
  147. package/src/device/motion.ts +62 -46
  148. package/src/device/plug.ts +19 -18
  149. package/src/device/robotvacuumcleaner.ts +89 -104
  150. package/src/device/waterdetector.ts +46 -34
  151. package/src/homebridge-ui/public/index.html +20 -14
  152. package/src/index.ts +3 -2
  153. package/src/irdevice/airconditioner.ts +13 -11
  154. package/src/irdevice/airpurifier.ts +5 -3
  155. package/src/irdevice/camera.ts +6 -4
  156. package/src/irdevice/fan.ts +42 -29
  157. package/src/irdevice/irdevice.ts +4 -5
  158. package/src/irdevice/light.ts +83 -103
  159. package/src/irdevice/other.ts +5 -3
  160. package/src/irdevice/tv.ts +7 -5
  161. package/src/irdevice/vacuumcleaner.ts +6 -4
  162. package/src/irdevice/waterheater.ts +6 -4
  163. package/src/platform.ts +59 -66
  164. package/src/settings.ts +73 -58
@@ -3,11 +3,13 @@
3
3
  *
4
4
  * motion.ts: @switchbot/homebridge-switchbot.
5
5
  */
6
+ import { Devices } from '../settings.js';
6
7
  import { deviceBase } from './device.js';
7
- import { SwitchBotPlatform } from '../platform.js';
8
8
  import { Subject, interval, skipWhile } from 'rxjs';
9
- import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
- import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../settings.js';
9
+
10
+ import type { SwitchBotPlatform } from '../platform.js';
11
+ import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
12
+ import type { device, devicesConfig, serviceData, deviceStatus } from '../settings.js';
11
13
 
12
14
  /**
13
15
  * Platform Accessory
@@ -16,18 +18,21 @@ import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../se
16
18
  */
17
19
  export class Motion extends deviceBase {
18
20
  // Services
19
- private Battery!: {
21
+ private Battery: {
22
+ Name: CharacteristicValue;
20
23
  Service: Service;
21
24
  BatteryLevel: CharacteristicValue;
22
25
  StatusLowBattery: CharacteristicValue;
23
26
  };
24
27
 
25
- private MotionSensor!: {
28
+ private MotionSensor: {
29
+ Name: CharacteristicValue;
26
30
  Service: Service;
27
31
  MotionDetected: CharacteristicValue;
28
32
  };
29
33
 
30
34
  private LightSensor?: {
35
+ Name: CharacteristicValue;
31
36
  Service: Service;
32
37
  CurrentAmbientLightLevel: CharacteristicValue;
33
38
  };
@@ -48,61 +53,72 @@ export class Motion extends deviceBase {
48
53
 
49
54
  // Initialize Motion Sensor property
50
55
  this.MotionSensor = {
51
- Service: accessory.getService(this.hap.Service.MotionSensor) as Service,
52
- MotionDetected: accessory.context.MotionDetected || false,
56
+ Name: accessory.context.MotionSensor.Name ?? `${accessory.displayName} Motion Sensor`,
57
+ Service: accessory.getService(this.hap.Service.MotionSensor) ?? accessory.addService(this.hap.Service.MotionSensor) as Service,
58
+ MotionDetected: accessory.context.MotionDetected ?? false,
53
59
  };
54
60
 
55
- // Initialize Battery property
56
- this.Battery = {
57
- Service: accessory.getService(this.hap.Service.Battery) as Service,
58
- BatteryLevel: accessory.context.BatteryLevel || 100,
59
- StatusLowBattery: accessory.context.StatusLowBattery || this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
60
- };
61
+ // Initialize Motion Sensor Characteristics
62
+ this.MotionSensor.Service
63
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
64
+ .setCharacteristic(this.hap.Characteristic.StatusActive, true)
65
+ .getCharacteristic(this.hap.Characteristic.MotionDetected)
66
+ .onGet(() => {
67
+ return this.MotionSensor.MotionDetected;
68
+ });
69
+ accessory.context.MotionSensor.Name = this.MotionSensor.Name;
61
70
 
62
- // Initialize Motion Sensor property
63
- if (!device.motion?.hide_lightsensor) {
64
- this.LightSensor = {
65
- Service: accessory.getService(this.hap.Service.LightSensor) as Service,
66
- CurrentAmbientLightLevel: accessory.context.CurrentAmbientLightLevel || 0,
67
- };
71
+ // Initialize Battery Service
72
+ this.Battery = {
73
+ Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
74
+ Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
75
+ BatteryLevel: accessory.context.BatteryLevel ?? 100,
76
+ StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
68
77
  };
69
78
 
79
+ // Initialize Battery Characteristics
80
+ this.Battery.Service
81
+ .setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
82
+ .setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE)
83
+ .getCharacteristic(this.hap.Characteristic.BatteryLevel)
84
+ .onGet(() => {
85
+ return this.Battery.BatteryLevel;
86
+ });
70
87
 
71
- // Retrieve initial values and updateHomekit
72
- this.refreshStatus();
73
-
74
- // get the Battery service if it exists, otherwise create a new Motion service
75
- // you can create multiple services for each accessory
76
- (this.MotionSensor.Service = accessory.getService(this.hap.Service.MotionSensor)
77
- || accessory.addService(this.hap.Service.MotionSensor)), `${accessory.displayName} Motion Sensor`;
78
-
79
- this.MotionSensor.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
80
- // each service must implement at-minimum the "required characteristics" for the given service type
81
- // see https://developers.homebridge.io/#/service/MotionSensor
88
+ this.Battery.Service
89
+ .setCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery)
90
+ .getCharacteristic(this.hap.Characteristic.StatusLowBattery)
91
+ .onGet(() => {
92
+ return this.Battery.StatusLowBattery;
93
+ });
94
+ accessory.context.Battery.Name = this.Battery.Name;
82
95
 
83
- // Light Sensor Service
96
+ // Initialize Light Sensor Service
84
97
  if (device.motion?.hide_lightsensor) {
85
98
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
86
99
  this.LightSensor!.Service = this.accessory.getService(this.hap.Service.LightSensor) as Service;
87
100
  accessory.removeService(this.LightSensor!.Service);
88
- } else if (!this.LightSensor?.Service) {
89
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Light Sensor Service`);
90
- const LightSensorService = `${accessory.displayName} Light Sensor`;
91
- (this.LightSensor!.Service = this.accessory.getService(this.hap.Service.LightSensor)
92
- || this.accessory.addService(this.hap.Service.LightSensor)), LightSensorService;
93
-
94
- this.LightSensor!.Service.setCharacteristic(this.hap.Characteristic.Name, LightSensorService);
95
101
  } else {
96
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
97
- }
102
+ this.LightSensor = {
103
+ Name: accessory.context.LightSensor.Name ?? `${accessory.displayName} Light Sensor`,
104
+ Service: accessory.getService(this.hap.Service.LightSensor) ?? this.accessory.addService(this.hap.Service.LightSensor) as Service,
105
+ CurrentAmbientLightLevel: accessory.context.CurrentAmbientLightLevel ?? 0,
106
+ };
107
+
108
+ // Initialize LightSensor Characteristics
109
+ this.LightSensor!.Service
110
+ .setCharacteristic(this.hap.Characteristic.Name, this.LightSensor!.Name)
111
+ .setCharacteristic(this.hap.Characteristic.StatusActive, true)
112
+ .getCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel)
113
+ .onGet(() => {
114
+ return this.LightSensor!.CurrentAmbientLightLevel;
115
+ });
116
+ accessory.context.LightSensor.Name = this.LightSensor.Name;
117
+ };
98
118
 
99
- // Battery Service
100
- const BatteryService = `${accessory.displayName} Battery`;
101
- (this.Battery.Service = this.accessory.getService(this.hap.Service.Battery)
102
- || accessory.addService(this.hap.Service.Battery)), BatteryService;
103
119
 
104
- this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, BatteryService);
105
- this.Battery.Service.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
120
+ // Retrieve initial values and updateHomekit
121
+ this.refreshStatus();
106
122
 
107
123
  // Retrieve initial values and updateHomekit
108
124
  this.updateHomeKitCharacteristics();
@@ -3,14 +3,17 @@
3
3
  * plug.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import { request } from 'undici';
6
+ import { Devices } from '../settings.js';
6
7
  import { deviceBase } from './device.js';
7
- import { SwitchBotPlatform } from '../platform.js';
8
8
  import { Subject, debounceTime, interval, skipWhile, take, tap } from 'rxjs';
9
- import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
- import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../settings.js';
9
+
10
+ import type { SwitchBotPlatform } from '../platform.js';
11
+ import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
12
+ import type { device, devicesConfig, serviceData, deviceStatus} from '../settings.js';
11
13
  export class Plug extends deviceBase {
12
14
  // Services
13
15
  private Outlet: {
16
+ Name: CharacteristicValue;
14
17
  Service: Service;
15
18
  On: CharacteristicValue;
16
19
  };
@@ -29,28 +32,26 @@ export class Plug extends deviceBase {
29
32
  this.doPlugUpdate = new Subject();
30
33
  this.plugUpdateInProgress = false;
31
34
 
32
- // Initialize Outlet property
35
+ // Initialize Outlet Service
33
36
  this.Outlet = {
34
- Service: accessory.getService(this.hap.Service.Outlet) as Service,
37
+ Name: accessory.context.Outlet.Name ?? accessory.displayName,
38
+ Service: accessory.getService(this.hap.Service.Outlet) ?? accessory.addService(this.hap.Service.Outlet) as Service,
35
39
  On: accessory.context.On || false,
36
40
  };
37
41
 
42
+ // Initialize Outlet Characteristics
43
+ this.Outlet.Service
44
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
45
+ .getCharacteristic(this.hap.Characteristic.On)
46
+ .onGet(() => {
47
+ return this.Outlet.On;
48
+ })
49
+ .onSet(this.OnSet.bind(this));
50
+ accessory.context.Outlet.Name = this.Outlet.Name;
51
+
38
52
  // Retrieve initial values and updateHomekit
39
53
  this.refreshStatus();
40
54
 
41
- // get the Outlet service if it exists, otherwise create a new Outlet service
42
- // you can create multiple services for each accessory
43
- const OutletService = `${accessory.displayName} ${device.deviceType}`;
44
- (this.Outlet.Service = accessory.getService(this.hap.Service.Outlet)
45
- || accessory.addService(this.hap.Service.Outlet)), OutletService;
46
-
47
- this.Outlet.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
48
- // each service must implement at-minimum the "required characteristics" for the given service type
49
- // see https://developers.homebridge.io/#/service/Outlet
50
-
51
- // create handlers for required characteristics
52
- this.Outlet.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
53
-
54
55
  // Update Homekit
55
56
  this.updateHomeKitCharacteristics();
56
57
 
@@ -3,25 +3,30 @@
3
3
  * robotvacuumcleaner.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import { request } from 'undici';
6
- import { Subject, interval, skipWhile } from 'rxjs';
6
+ import { Devices } from '../settings.js';
7
7
  import { deviceBase } from './device.js';
8
- import { SwitchBotPlatform } from '../platform.js';
8
+ import { Subject, interval, skipWhile } from 'rxjs';
9
9
  import { debounceTime, take, tap } from 'rxjs/operators';
10
- import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
11
- import { device, devicesConfig, deviceStatus, serviceData, Devices } from '../settings.js';
10
+
11
+ import type { SwitchBotPlatform } from '../platform.js';
12
+ import type { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
13
+ import type { device, devicesConfig, deviceStatus, serviceData } from '../settings.js';
12
14
 
13
15
  export class RobotVacuumCleaner extends deviceBase {
14
16
  // Services
15
17
  private LightBulb: {
18
+ Name: CharacteristicValue;
16
19
  Service: Service;
17
20
  On: CharacteristicValue;
18
21
  Brightness: CharacteristicValue;
19
22
  };
20
23
 
21
24
  private Battery: {
25
+ Name: CharacteristicValue;
22
26
  Service: Service;
23
27
  BatteryLevel: CharacteristicValue;
24
28
  StatusLowBattery: CharacteristicValue;
29
+ ChargingState: CharacteristicValue;
25
30
  };
26
31
 
27
32
  // Updates
@@ -38,37 +43,24 @@ export class RobotVacuumCleaner extends deviceBase {
38
43
  this.doRobotVacuumCleanerUpdate = new Subject();
39
44
  this.robotVacuumCleanerUpdateInProgress = false;
40
45
 
41
- // Initialize Lightbulb property
46
+ // Initialize Lightbulb Service
42
47
  this.LightBulb = {
43
- Service: accessory.getService(this.hap.Service.Lightbulb) as Service,
44
- On: accessory.context.On || false,
45
- Brightness: accessory.context.Brightness || 0,
46
- };
47
-
48
- // Initialize Battery property
49
- this.Battery = {
50
- Service: accessory.getService(this.hap.Service.Battery) as Service,
51
- BatteryLevel: accessory.context.BatteryLevel || 100,
52
- StatusLowBattery: accessory.context.StatusLowBattery || this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
48
+ Name: accessory.context.LightBulb.Name ?? accessory.displayName,
49
+ Service: accessory.getService(this.hap.Service.Lightbulb) ?? accessory.addService(this.hap.Service.Lightbulb) as Service,
50
+ On: accessory.context.On ?? false,
51
+ Brightness: accessory.context.Brightness ?? 0,
53
52
  };
54
53
 
55
- // Retrieve initial values and updateHomekit
56
- this.refreshStatus();
57
-
58
- // get the Lightbulb service if it exists, otherwise create a new Lightbulb service
59
- // you can create multiple services for each accessory
60
- const LightBulbService = `${accessory.displayName} ${device.deviceType}`;
61
- (this.LightBulb.Service = accessory.getService(this.hap.Service.Lightbulb)
62
- || accessory.addService(this.hap.Service.Lightbulb)), LightBulbService;
63
-
64
- this.LightBulb.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
65
- // each service must implement at-minimum the "required characteristics" for the given service type
66
- // see https://developers.homebridge.io/#/service/Lightbulb
67
-
68
- // create handlers for required characteristics
69
- this.LightBulb.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
54
+ // Initialize LightBulb Characteristics
55
+ this.LightBulb.Service
56
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
57
+ .getCharacteristic(this.hap.Characteristic.On)
58
+ .onGet(() => {
59
+ return this.LightBulb.On;
60
+ })
61
+ .onSet(this.OnSet.bind(this));
70
62
 
71
- // handle Brightness events using the Brightness characteristic
63
+ // Initialize LightBulb Brightness Characteristic
72
64
  this.LightBulb.Service
73
65
  .getCharacteristic(this.hap.Characteristic.Brightness)
74
66
  .setProps({
@@ -82,14 +74,40 @@ export class RobotVacuumCleaner extends deviceBase {
82
74
  return this.LightBulb.Brightness;
83
75
  })
84
76
  .onSet(this.BrightnessSet.bind(this));
77
+ accessory.context.LightBulb.Name = this.LightBulb.Name;
78
+
79
+ // Initialize Battery Service
80
+ this.Battery = {
81
+ Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
82
+ Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
83
+ BatteryLevel: accessory.context.BatteryLevel ?? 100,
84
+ StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
85
+ ChargingState: accessory.context.ChargingState ?? this.hap.Characteristic.ChargingState.NOT_CHARGING,
86
+ };
87
+
88
+ // Initialize Battery Characteristics
89
+ this.Battery.Service
90
+ .setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
91
+ .getCharacteristic(this.hap.Characteristic.BatteryLevel)
92
+ .onGet(() => {
93
+ return this.Battery.BatteryLevel;
94
+ });
85
95
 
86
- // Battery Service
87
- const BatteryService = `${accessory.displayName} Battery`;
88
- (this.Battery.Service = this.accessory.getService(this.hap.Service.Battery)
89
- || accessory.addService(this.hap.Service.Battery)), BatteryService;
96
+ this.Battery.Service
97
+ .getCharacteristic(this.hap.Characteristic.StatusLowBattery)
98
+ .onGet(() => {
99
+ return this.Battery.StatusLowBattery;
100
+ });
90
101
 
91
- this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, BatteryService);
102
+ this.Battery.Service
103
+ .getCharacteristic(this.hap.Characteristic.ChargingState)
104
+ .onGet(() => {
105
+ return this.Battery.ChargingState;
106
+ });
107
+ accessory.context.Battery.Name = this.Battery.Name;
92
108
 
109
+ // Retrieve initial values and updateHomekit
110
+ this.refreshStatus();
93
111
  // Update Homekit
94
112
  this.updateHomeKitCharacteristics();
95
113
 
@@ -106,14 +124,16 @@ export class RobotVacuumCleaner extends deviceBase {
106
124
  this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
107
125
  try {
108
126
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
109
- const { onlineStatus, battery } = context;
127
+ const { onlineStatus, battery, workingStatus } = context;
110
128
  const { On } = this.LightBulb;
111
- const { BatteryLevel } = this.Battery;
129
+ const { BatteryLevel, ChargingState } = this.Battery;
112
130
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
113
- '(onlineStatus, battery) = ' +
114
- `Webhook:(${onlineStatus}, ${battery}), ` +
115
- `current:(${On}, ${BatteryLevel})`);
131
+ '(onlineStatus, battery, workingStatus) = ' +
132
+ `Webhook:(${onlineStatus}, ${battery}, ${workingStatus}), ` +
133
+ `current:(${On}, ${BatteryLevel}, ${ChargingState})`);
116
134
  this.LightBulb.On = onlineStatus === 'online' ? true : false;
135
+ this.Battery.ChargingState = workingStatus === 'Charging'
136
+ ? this.hap.Characteristic.ChargingState.CHARGING : this.hap.Characteristic.ChargingState.NOT_CHARGING;
117
137
  this.Battery.BatteryLevel = battery;
118
138
  this.updateHomeKitCharacteristics();
119
139
  } catch (e: any) {
@@ -187,6 +207,8 @@ export class RobotVacuumCleaner extends deviceBase {
187
207
 
188
208
  // BatteryLevel
189
209
  this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
210
+
211
+ // StatusLowBattery
190
212
  if (this.Battery.BatteryLevel < 10) {
191
213
  this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
192
214
  } else {
@@ -195,8 +217,11 @@ export class RobotVacuumCleaner extends deviceBase {
195
217
  if (Number.isNaN(this.Battery.BatteryLevel)) {
196
218
  this.Battery.BatteryLevel = 100;
197
219
  }
220
+ // ChargingState
221
+ this.Battery.ChargingState = deviceStatus.body.workingStatus === 'Charging'
222
+ ? this.hap.Characteristic.ChargingState.CHARGING : this.hap.Characteristic.ChargingState.NOT_CHARGING;
198
223
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
199
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
224
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}, ChargingState: ${this.Battery.ChargingState}`);
200
225
 
201
226
  // Firmware Version
202
227
  const version = deviceStatus.body.version?.toString();
@@ -217,8 +242,8 @@ export class RobotVacuumCleaner extends deviceBase {
217
242
  async refreshStatus(): Promise<void> {
218
243
  if (!this.device.enableCloudService && this.OpenAPI) {
219
244
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus enableCloudService: ${this.device.enableCloudService}`);
220
- /*} else if (this.BLE) {
221
- await this.BLERefreshStatus();*/
245
+ } else if (this.BLE) {
246
+ await this.BLERefreshStatus();
222
247
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
223
248
  await this.openAPIRefreshStatus();
224
249
  } else {
@@ -242,21 +267,19 @@ export class RobotVacuumCleaner extends deviceBase {
242
267
  this.getCustomBLEAddress(switchbot);
243
268
  // Start to monitor advertisement packets
244
269
  (async () => {
245
- await switchbot.startScan({
246
- model: '?',
247
- id: this.device.bleMac,
248
- });
270
+ // Start to monitor advertisement packets
271
+ await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
249
272
  // Set an event handler
250
273
  switchbot.onadvertisement = (ad: any) => {
251
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
252
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.serviceData.model}`);
253
- if (this.device.bleMac === ad.address && ad.serviceData.model === '?') {
274
+ if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
275
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
276
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
254
277
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
255
278
  } else {
256
279
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
257
280
  }
258
281
  };
259
- // Wait 1 seconds
282
+ // Wait 10 seconds
260
283
  await switchbot.wait(this.scanDuration * 1000);
261
284
  // Stop to monitor
262
285
  await switchbot.stopScan();
@@ -264,63 +287,16 @@ export class RobotVacuumCleaner extends deviceBase {
264
287
  await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
265
288
  await this.updateHomeKitCharacteristics();
266
289
  })();
267
- /*if (switchbot !== false) {
268
- switchbot
269
- .startScan({
270
- model: this.BLEmodel(),
271
- id: this.device.bleMac,
272
- })
273
- .then(async () => {
274
- // Set an event handler
275
- switchbot.onadvertisement = async (ad: ad) => {
276
- this.debugLog(
277
- `${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
278
- ` BLE Address Found: ${ad.address}`,
279
- );
280
- serviceData.state = ad.serviceData.state;
281
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
282
- this.debugLog(
283
- `${this.device.deviceType}: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
284
- `delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
285
- `wifiRssi: ${ad.serviceData.wifiRssi}, overload: ${ad.serviceData.overload}, currentPower: ${ad.serviceData.currentPower}`,
286
- );
287
-
288
- if (ad.serviceData) {
289
- this.BLE_IsConnected = true;
290
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
291
- await this.stopScanning(switchbot);
292
- } else {
293
- this.BLE_IsConnected = false;
294
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
295
- }
296
- };
297
- // Wait
298
- return await sleep(this.scanDuration * 1000);
299
- })
300
- .then(async () => {
301
- // Stop to monitor
302
- await this.stopScanning(switchbot);
303
- })
304
- .catch(async (e: any) => {
305
- this.apiError(e);
306
- this.errorLog(
307
- `${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
308
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
309
- );
310
- await this.BLERefreshConnection(switchbot);
311
- });
312
- } else {
290
+ if (switchbot === undefined) {
313
291
  await this.BLERefreshConnection(switchbot);
314
- }*/
292
+ }
315
293
  }
316
294
 
317
- async openAPIRefreshStatus() {
295
+ async openAPIRefreshStatus(): Promise<void> {
318
296
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
319
297
  try {
320
298
  const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
321
- `${Devices}/${this.device.deviceId}/status`, {
322
- headers: this.platform.generateHeaders(),
323
- });
299
+ `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
324
300
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
325
301
  const deviceStatus: any = await body.json();
326
302
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -594,7 +570,7 @@ export class RobotVacuumCleaner extends deviceBase {
594
570
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
595
571
  } else {
596
572
  this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
597
- this.Battery.Service?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
573
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
598
574
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
599
575
  }
600
576
  // StatusLowBattery
@@ -606,6 +582,15 @@ export class RobotVacuumCleaner extends deviceBase {
606
582
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
607
583
  + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
608
584
  }
585
+ // ChargingState
586
+ if (this.Battery.ChargingState === undefined) {
587
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ChargingState: ${this.Battery.ChargingState}`);
588
+ } else {
589
+ this.accessory.context.ChargingState = this.Battery.ChargingState;
590
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, this.Battery.ChargingState);
591
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
592
+ + ` ChargingState: ${this.Battery.ChargingState}`);
593
+ }
609
594
  }
610
595
 
611
596
  async BLEPushConnection() {
@@ -4,10 +4,12 @@
4
4
  */
5
5
  import { deviceBase } from './device.js';
6
6
  import { interval, Subject } from 'rxjs';
7
+ import { Devices } from '../settings.js';
7
8
  import { skipWhile } from 'rxjs/operators';
8
- import { SwitchBotPlatform } from '../platform.js';
9
- import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
10
- import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../settings.js';
9
+
10
+ import type { SwitchBotPlatform } from '../platform.js';
11
+ import type { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
12
+ import type { device, devicesConfig, serviceData, deviceStatus} from '../settings.js';
11
13
 
12
14
  /**
13
15
  * Platform Accessory
@@ -17,6 +19,7 @@ import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../se
17
19
  export class WaterDetector extends deviceBase {
18
20
  // Services
19
21
  private Battery: {
22
+ Name: CharacteristicValue
20
23
  Service: Service;
21
24
  BatteryLevel: CharacteristicValue;
22
25
  StatusLowBattery: CharacteristicValue;
@@ -24,6 +27,7 @@ export class WaterDetector extends deviceBase {
24
27
  };
25
28
 
26
29
  private LeakSensor?: {
30
+ Name: CharacteristicValue;
27
31
  Service: Service;
28
32
  StatusActive: CharacteristicValue;
29
33
  LeakDetected: CharacteristicValue;
@@ -46,49 +50,57 @@ export class WaterDetector extends deviceBase {
46
50
  this.doWaterDetectorUpdate = new Subject();
47
51
  this.WaterDetectorUpdateInProgress = false;
48
52
 
49
- // Initialize Battery property
53
+ // Initialize Battery Service
50
54
  this.Battery = {
51
- Service: accessory.getService(this.hap.Service.Battery) as Service,
52
- BatteryLevel: accessory.context.BatteryLevel || 100,
53
- StatusLowBattery: accessory.context.StatusLowBattery || this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
54
- ChargingState: accessory.context.ChargingState || this.hap.Characteristic.ChargingState.NOT_CHARGEABLE,
55
+ Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
56
+ Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
57
+ BatteryLevel: accessory.context.BatteryLevel ?? 100,
58
+ StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
59
+ ChargingState: accessory.context.ChargingState ?? this.hap.Characteristic.ChargingState.NOT_CHARGEABLE,
55
60
  };
56
61
 
57
- // Initialize Leak Sensor property
58
- if (!this.device.waterdetector?.hide_leak) {
59
- this.LeakSensor = {
60
- Service: accessory.getService(this.hap.Service.LeakSensor) as Service,
61
- StatusActive: accessory.context.StatusActive || false,
62
- LeakDetected: accessory.context.LeakDetected || this.hap.Characteristic.LeakDetected.LEAK_NOT_DETECTED,
63
- };
64
- }
62
+ // Initialize Battery Characteristic
63
+ this.Battery.Service
64
+ .setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
65
+ .setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE)
66
+ .getCharacteristic(this.hap.Characteristic.BatteryLevel)
67
+ .onGet(() => {
68
+ return this.Battery.StatusLowBattery;
69
+ });
65
70
 
66
- // Retrieve initial values and updateHomekit
67
- this.refreshStatus();
71
+ this.Battery.Service
72
+ .getCharacteristic(this.hap.Characteristic.StatusLowBattery)
73
+ .onGet(() => {
74
+ return this.Battery.StatusLowBattery;
75
+ });
76
+ accessory.context.Battery.Name = this.Battery.Name;
68
77
 
69
- // Leak Sensor Service
78
+ // Initialize Leak Sensor Service
70
79
  if (device.waterdetector?.hide_leak) {
71
80
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leak Sensor Service`);
72
81
  this.LeakSensor!.Service = this.accessory.getService(this.hap.Service.LeakSensor) as Service;
73
82
  accessory.removeService(this.LeakSensor!.Service);
74
- } else if (!this.LeakSensor?.Service) {
75
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Leak Sensor Service`);
76
- const LeakSensorService = `${accessory.displayName} Leak Sensor`;
77
- (this.LeakSensor!.Service = this.accessory.getService(this.hap.Service.LeakSensor)
78
- || this.accessory.addService(this.hap.Service.LeakSensor)), LeakSensorService;
79
-
80
- this.LeakSensor!.Service.setCharacteristic(this.hap.Characteristic.Name, LeakSensorService);
81
83
  } else {
82
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Leak Sensor Service Not Added`);
83
- }
84
+ this.LeakSensor = {
85
+ Name: accessory.context.LeakSensor.Name ?? `${accessory.displayName} Leak Sensor`,
86
+ Service: accessory.getService(this.hap.Service.LeakSensor) ?? this.accessory.addService(this.hap.Service.LeakSensor) as Service,
87
+ StatusActive: accessory.context.StatusActive ?? false,
88
+ LeakDetected: accessory.context.LeakDetected ?? this.hap.Characteristic.LeakDetected.LEAK_NOT_DETECTED,
89
+ };
84
90
 
85
- // Battery Service
86
- const BatteryService = `${accessory.displayName} Battery`;
87
- (this.Battery.Service = this.accessory.getService(this.hap.Service.Battery)
88
- || accessory.addService(this.hap.Service.Battery)), BatteryService;
91
+ // Initialize LeakSensor Characteristic
92
+ this.LeakSensor!.Service
93
+ .setCharacteristic(this.hap.Characteristic.Name, this.LeakSensor.Name)
94
+ .setCharacteristic(this.hap.Characteristic.StatusActive, true)
95
+ .getCharacteristic(this.hap.Characteristic.LeakDetected)
96
+ .onGet(() => {
97
+ return this.LeakSensor!.LeakDetected;
98
+ });
99
+ accessory.context.LeakSensor.Name = this.LeakSensor.Name;
100
+ }
89
101
 
90
- this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, BatteryService);
91
- this.Battery.Service.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
102
+ // Retrieve initial values and updateHomekit
103
+ this.refreshStatus();
92
104
 
93
105
  // Retrieve initial values and updateHomekit
94
106
  this.updateHomeKitCharacteristics();