@switchbot/homebridge-switchbot 3.5.0-beta.22 → 3.5.0-beta.24

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 (150) hide show
  1. package/config.schema.json +23 -2
  2. package/dist/device/blindtilt.d.ts +21 -98
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +332 -785
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts +25 -75
  7. package/dist/device/bot.d.ts.map +1 -1
  8. package/dist/device/bot.js +566 -778
  9. package/dist/device/bot.js.map +1 -1
  10. package/dist/device/ceilinglight.d.ts +13 -71
  11. package/dist/device/ceilinglight.d.ts.map +1 -1
  12. package/dist/device/ceilinglight.js +168 -606
  13. package/dist/device/ceilinglight.js.map +1 -1
  14. package/dist/device/colorbulb.d.ts +13 -78
  15. package/dist/device/colorbulb.d.ts.map +1 -1
  16. package/dist/device/colorbulb.js +218 -655
  17. package/dist/device/colorbulb.js.map +1 -1
  18. package/dist/device/contact.d.ts +14 -69
  19. package/dist/device/contact.d.ts.map +1 -1
  20. package/dist/device/contact.js +196 -553
  21. package/dist/device/contact.js.map +1 -1
  22. package/dist/device/curtain.d.ts +17 -90
  23. package/dist/device/curtain.d.ts.map +1 -1
  24. package/dist/device/curtain.js +324 -810
  25. package/dist/device/curtain.js.map +1 -1
  26. package/dist/device/device.d.ts +58 -0
  27. package/dist/device/device.d.ts.map +1 -0
  28. package/dist/device/device.js +629 -0
  29. package/dist/device/device.js.map +1 -0
  30. package/dist/device/hub.d.ts +15 -63
  31. package/dist/device/hub.d.ts.map +1 -1
  32. package/dist/device/hub.js +223 -610
  33. package/dist/device/hub.js.map +1 -1
  34. package/dist/device/humidifier.d.ts +10 -69
  35. package/dist/device/humidifier.d.ts.map +1 -1
  36. package/dist/device/humidifier.js +192 -595
  37. package/dist/device/humidifier.js.map +1 -1
  38. package/dist/device/iosensor.d.ts +11 -68
  39. package/dist/device/iosensor.d.ts.map +1 -1
  40. package/dist/device/iosensor.js +156 -599
  41. package/dist/device/iosensor.js.map +1 -1
  42. package/dist/device/lightstrip.d.ts +10 -72
  43. package/dist/device/lightstrip.d.ts.map +1 -1
  44. package/dist/device/lightstrip.js +204 -591
  45. package/dist/device/lightstrip.js.map +1 -1
  46. package/dist/device/lock.d.ts +15 -66
  47. package/dist/device/lock.d.ts.map +1 -1
  48. package/dist/device/lock.js +199 -566
  49. package/dist/device/lock.js.map +1 -1
  50. package/dist/device/meter.d.ts +13 -67
  51. package/dist/device/meter.d.ts.map +1 -1
  52. package/dist/device/meter.js +152 -592
  53. package/dist/device/meter.js.map +1 -1
  54. package/dist/device/meterplus.d.ts +13 -68
  55. package/dist/device/meterplus.d.ts.map +1 -1
  56. package/dist/device/meterplus.js +151 -599
  57. package/dist/device/meterplus.js.map +1 -1
  58. package/dist/device/motion.d.ts +13 -73
  59. package/dist/device/motion.d.ts.map +1 -1
  60. package/dist/device/motion.js +129 -540
  61. package/dist/device/motion.js.map +1 -1
  62. package/dist/device/plug.d.ts +9 -61
  63. package/dist/device/plug.d.ts.map +1 -1
  64. package/dist/device/plug.js +71 -476
  65. package/dist/device/plug.js.map +1 -1
  66. package/dist/device/robotvacuumcleaner.d.ts +11 -66
  67. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  68. package/dist/device/robotvacuumcleaner.js +122 -471
  69. package/dist/device/robotvacuumcleaner.js.map +1 -1
  70. package/dist/device/waterdetector.d.ts +9 -66
  71. package/dist/device/waterdetector.d.ts.map +1 -1
  72. package/dist/device/waterdetector.js +105 -478
  73. package/dist/device/waterdetector.js.map +1 -1
  74. package/dist/irdevice/airconditioner.d.ts +5 -36
  75. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  76. package/dist/irdevice/airconditioner.js +228 -337
  77. package/dist/irdevice/airconditioner.js.map +1 -1
  78. package/dist/irdevice/airpurifier.d.ts +5 -34
  79. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  80. package/dist/irdevice/airpurifier.js +19 -267
  81. package/dist/irdevice/airpurifier.js.map +1 -1
  82. package/dist/irdevice/camera.d.ts +5 -34
  83. package/dist/irdevice/camera.d.ts.map +1 -1
  84. package/dist/irdevice/camera.js +13 -261
  85. package/dist/irdevice/camera.js.map +1 -1
  86. package/dist/irdevice/fan.d.ts +5 -34
  87. package/dist/irdevice/fan.d.ts.map +1 -1
  88. package/dist/irdevice/fan.js +13 -260
  89. package/dist/irdevice/fan.js.map +1 -1
  90. package/dist/irdevice/irdevice.d.ts +39 -0
  91. package/dist/irdevice/irdevice.d.ts.map +1 -0
  92. package/dist/irdevice/irdevice.js +502 -0
  93. package/dist/irdevice/irdevice.js.map +1 -0
  94. package/dist/irdevice/light.d.ts +5 -34
  95. package/dist/irdevice/light.d.ts.map +1 -1
  96. package/dist/irdevice/light.js +13 -267
  97. package/dist/irdevice/light.js.map +1 -1
  98. package/dist/irdevice/other.d.ts +18 -48
  99. package/dist/irdevice/other.d.ts.map +1 -1
  100. package/dist/irdevice/other.js +349 -551
  101. package/dist/irdevice/other.js.map +1 -1
  102. package/dist/irdevice/tv.d.ts +7 -40
  103. package/dist/irdevice/tv.d.ts.map +1 -1
  104. package/dist/irdevice/tv.js +79 -325
  105. package/dist/irdevice/tv.js.map +1 -1
  106. package/dist/irdevice/vacuumcleaner.d.ts +6 -36
  107. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  108. package/dist/irdevice/vacuumcleaner.js +38 -288
  109. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  110. package/dist/irdevice/waterheater.d.ts +6 -36
  111. package/dist/irdevice/waterheater.d.ts.map +1 -1
  112. package/dist/irdevice/waterheater.js +39 -291
  113. package/dist/irdevice/waterheater.js.map +1 -1
  114. package/dist/settings.d.ts +15 -2
  115. package/dist/settings.d.ts.map +1 -1
  116. package/dist/utils.d.ts +68 -0
  117. package/dist/utils.d.ts.map +1 -1
  118. package/dist/utils.js +71 -0
  119. package/dist/utils.js.map +1 -1
  120. package/package.json +8 -8
  121. package/src/device/blindtilt.ts +356 -809
  122. package/src/device/bot.ts +601 -865
  123. package/src/device/ceilinglight.ts +182 -628
  124. package/src/device/colorbulb.ts +235 -683
  125. package/src/device/contact.ts +220 -575
  126. package/src/device/curtain.ts +344 -836
  127. package/src/device/device.ts +655 -0
  128. package/src/device/hub.ts +246 -636
  129. package/src/device/humidifier.ts +224 -645
  130. package/src/device/iosensor.ts +181 -625
  131. package/src/device/lightstrip.ts +230 -622
  132. package/src/device/lock.ts +236 -607
  133. package/src/device/meter.ts +177 -616
  134. package/src/device/meterplus.ts +175 -624
  135. package/src/device/motion.ts +147 -563
  136. package/src/device/plug.ts +81 -505
  137. package/src/device/robotvacuumcleaner.ts +139 -494
  138. package/src/device/waterdetector.ts +126 -506
  139. package/src/irdevice/airconditioner.ts +228 -353
  140. package/src/irdevice/airpurifier.ts +23 -282
  141. package/src/irdevice/camera.ts +18 -277
  142. package/src/irdevice/fan.ts +18 -275
  143. package/src/irdevice/irdevice.ts +518 -0
  144. package/src/irdevice/light.ts +18 -283
  145. package/src/irdevice/other.ts +394 -621
  146. package/src/irdevice/tv.ts +97 -344
  147. package/src/irdevice/vacuumcleaner.ts +46 -310
  148. package/src/irdevice/waterheater.ts +47 -315
  149. package/src/settings.ts +20 -3
  150. package/src/utils.ts +71 -0
@@ -1,108 +1,53 @@
1
+ /* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
+ *
3
+ * curtain.ts: @switchbot/homebridge-switchbot.
4
+ */
5
+ import { hostname } from 'os';
1
6
  import { request } from 'undici';
2
- import { sleep } from '../utils.js';
3
- import { MqttClient } from 'mqtt';
4
7
  import { interval, Subject } from 'rxjs';
5
- import asyncmqtt from 'async-mqtt';
8
+ import { deviceBase } from './device.js';
6
9
  import { SwitchBotPlatform } from '../platform.js';
7
10
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
8
- import { Service, PlatformAccessory, CharacteristicValue, CharacteristicChange, API, Logging, HAP } from 'homebridge';
9
- import { device, devicesConfig, serviceData, deviceStatus, Devices, SwitchBotPlatformConfig } from '../settings.js';
10
- import { hostname } from 'os';
11
+ import { Service, PlatformAccessory, CharacteristicValue, CharacteristicChange } from 'homebridge';
12
+ import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../settings.js';
11
13
 
12
- export class Curtain {
13
- public readonly api: API;
14
- public readonly log: Logging;
15
- public readonly config!: SwitchBotPlatformConfig;
16
- protected readonly hap: HAP;
14
+ export class Curtain extends deviceBase {
17
15
  // Services
18
- batteryService: Service;
19
- lightSensorService?: Service;
20
- windowCoveringService!: Service;
21
-
22
- // Characteristic Values
23
- BatteryLevel!: CharacteristicValue;
24
- HoldPosition!: CharacteristicValue;
25
- PositionState!: CharacteristicValue;
26
- TargetPosition!: CharacteristicValue;
27
- CurrentPosition!: CharacteristicValue;
28
- FirmwareRevision!: CharacteristicValue;
29
- StatusLowBattery!: CharacteristicValue;
30
- CurrentAmbientLightLevel?: CharacteristicValue;
31
-
32
- // OpenAPI Status
33
- OpenAPI_InMotion: deviceStatus['moving'];
34
- OpenAPI_BatteryLevel: deviceStatus['battery'];
35
- OpenAPI_FirmwareRevision: deviceStatus['version'];
36
- OpenAPI_CurrentPosition: deviceStatus['slidePosition'];
37
- OpenAPI_CurrentAmbientLightLevel: deviceStatus['brightness'];
38
-
39
- // Others
40
- Mode!: string;
41
- setPositionMode?: string;
42
-
43
- // BLE Status
44
- BLE_InMotion: serviceData['inMotion'];
45
- BLE_BatteryLevel: serviceData['battery'];
46
- BLE_Calibration: serviceData['calibration'];
47
- BLE_CurrentPosition: serviceData['position'];
48
- BLE_CurrentAmbientLightLevel: serviceData['lightLevel'];
49
-
50
- // BLE Others
51
- BLE_IsConnected?: boolean;
52
- spaceBetweenLevels!: number;
16
+ private WindowCovering!: {
17
+ Service: Service;
18
+ PositionState: CharacteristicValue;
19
+ TargetPosition: CharacteristicValue;
20
+ CurrentPosition: CharacteristicValue;
21
+ HoldPosition: CharacteristicValue;
22
+ };
23
+
24
+ private Battery!: {
25
+ Service: Service;
26
+ BatteryLevel: CharacteristicValue;
27
+ StatusLowBattery: CharacteristicValue;
28
+ };
29
+
30
+ private LightSensor?: {
31
+ Service: Service;
32
+ CurrentAmbientLightLevel?: CharacteristicValue;
33
+ };
53
34
 
54
35
  // Target
55
36
  setNewTarget!: boolean;
56
37
  setNewTargetTimer!: NodeJS.Timeout;
57
38
 
58
- //MQTT stuff
59
- mqttClient: MqttClient | null = null;
60
-
61
- // Config
62
- updateRate!: number;
63
- set_minLux!: number;
64
- set_maxLux!: number;
65
- set_minStep!: number;
66
- setOpenMode!: string;
67
- setCloseMode!: string;
68
- scanDuration!: number;
69
- deviceLogging!: string;
70
- deviceRefreshRate!: number;
71
- maxRetries!: number;
72
- delayBetweenRetries!: number;
73
-
74
39
  // Updates
75
40
  curtainUpdateInProgress!: boolean;
76
41
  doCurtainUpdate!: Subject<void>;
77
42
 
78
- // Connection
79
- private readonly OpenAPI: boolean;
80
- private readonly BLE: boolean;
81
-
82
- // EVE history service handler
83
- historyService: any = null;
84
-
85
43
  constructor(
86
- private readonly platform: SwitchBotPlatform,
87
- private accessory: PlatformAccessory,
88
- public device: device & devicesConfig,
44
+ readonly platform: SwitchBotPlatform,
45
+ accessory: PlatformAccessory,
46
+ device: device & devicesConfig,
89
47
  ) {
90
- this.api = this.platform.api;
91
- this.log = this.platform.log;
92
- this.config = this.platform.config;
93
- this.hap = this.api.hap;
94
- // Connection
95
- this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
96
- this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
97
- // default placeholders
98
- this.deviceLogs(device);
99
- this.refreshRate(device);
100
- this.scan(device);
101
- this.setupMqtt(device);
102
- this.deviceContext();
103
- this.deviceRetry(device);
104
- this.deviceConfig(device);
105
-
48
+ super(platform, accessory, device);
49
+ // default placeholder
50
+ this.history(device);
106
51
  // this is subject we use to track when we need to POST changes to the SwitchBot API
107
52
  this.doCurtainUpdate = new Subject();
108
53
  this.curtainUpdateInProgress = false;
@@ -110,33 +55,45 @@ export class Curtain {
110
55
 
111
56
  // Retrieve initial values and updateHomekit
112
57
  this.refreshStatus();
113
-
114
- // set accessory information
115
- accessory
116
- .getService(this.hap.Service.AccessoryInformation)!
117
- .setCharacteristic(this.hap.Characteristic.Manufacturer, 'SwitchBot')
118
- .setCharacteristic(this.hap.Characteristic.Model, 'W0701600')
119
- .setCharacteristic(this.hap.Characteristic.SerialNumber, device.deviceId)
120
- .setCharacteristic(this.hap.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision);
58
+ // Initialize LightBulb property
59
+ this.WindowCovering = {
60
+ Service: this.accessory.addService(this.hap.Service.WindowCovering),
61
+ PositionState: this.accessory.context.PositionState || this.hap.Characteristic.PositionState.STOPPED,
62
+ TargetPosition: this.accessory.context.TargetPosition || 100,
63
+ CurrentPosition: this.accessory.context.CurrentPosition || 100,
64
+ HoldPosition: this.accessory.context.HoldPosition || false,
65
+ };
66
+
67
+ // Initialize Battery property
68
+ this.Battery = {
69
+ Service: this.accessory.addService(this.hap.Service.Battery),
70
+ BatteryLevel: this.accessory.context.BatteryLevel || 100,
71
+ StatusLowBattery: this.accessory.context.StatusLowBattery || this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
72
+ };
73
+
74
+ // Initialize LightSensor property
75
+ if (!this.device.curtain?.hide_lightsensor) {
76
+ this.LightSensor = {
77
+ Service: this.accessory.addService(this.hap.Service.LightSensor),
78
+ CurrentAmbientLightLevel: this.accessory.context.CurrentAmbientLightLevel || 0,
79
+ };
80
+ }
121
81
 
122
82
  // get the WindowCovering service if it exists, otherwise create a new WindowCovering service
123
83
  // you can create multiple services for each accessory
124
- const windowCoveringService = `${accessory.displayName} ${device.deviceType}`;
125
- (this.windowCoveringService = accessory.getService(this.hap.Service.WindowCovering)
126
- || accessory.addService(this.hap.Service.WindowCovering)), windowCoveringService;
84
+ const WindowCoveringService = `${accessory.displayName} ${device.deviceType}`;
85
+ (this.WindowCovering.Service = accessory.getService(this.hap.Service.WindowCovering)
86
+ || accessory.addService(this.hap.Service.WindowCovering)), WindowCoveringService;
127
87
 
128
- this.windowCoveringService.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
129
- if (!this.windowCoveringService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
130
- this.windowCoveringService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
131
- }
88
+ this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
132
89
 
133
90
  // each service must implement at-minimum the "required characteristics" for the given service type
134
91
  // see https://developers.homebridge.io/#/service/WindowCovering
135
92
 
136
93
  // create handlers for required characteristics
137
- this.windowCoveringService.setCharacteristic(this.hap.Characteristic.PositionState, this.PositionState);
94
+ this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
138
95
 
139
- this.windowCoveringService
96
+ this.WindowCovering.Service
140
97
  .getCharacteristic(this.hap.Characteristic.CurrentPosition)
141
98
  .setProps({
142
99
  minStep: this.minStep(device),
@@ -145,10 +102,10 @@ export class Curtain {
145
102
  validValueRanges: [0, 100],
146
103
  })
147
104
  .onGet(() => {
148
- return this.CurrentPosition;
105
+ return this.WindowCovering.CurrentPosition;
149
106
  });
150
107
 
151
- this.windowCoveringService
108
+ this.WindowCovering.Service
152
109
  .getCharacteristic(this.hap.Characteristic.TargetPosition)
153
110
  .setProps({
154
111
  minStep: this.minStep(device),
@@ -158,38 +115,32 @@ export class Curtain {
158
115
  })
159
116
  .onSet(this.TargetPositionSet.bind(this));
160
117
 
161
- this.windowCoveringService
118
+ this.WindowCovering.Service
162
119
  .getCharacteristic(this.hap.Characteristic.HoldPosition)
163
120
  .onSet(this.HoldPositionSet.bind(this));
164
121
 
165
122
  // Light Sensor Service
166
123
  if (device.curtain?.hide_lightsensor) {
167
124
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
168
- this.lightSensorService = this.accessory.getService(this.hap.Service.LightSensor);
169
- accessory.removeService(this.lightSensorService!);
170
- } else if (!this.lightSensorService) {
125
+ this.LightSensor!.Service = this.accessory.getService(this.hap.Service.LightSensor) as Service;
126
+ accessory.removeService(this.LightSensor!.Service);
127
+ } else if (!this.LightSensor?.Service) {
171
128
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Light Sensor Service`);
172
- const lightSensorService = `${accessory.displayName} Light Sensor`;
173
- (this.lightSensorService = this.accessory.getService(this.hap.Service.LightSensor)
174
- || this.accessory.addService(this.hap.Service.LightSensor)), lightSensorService;
129
+ const LightSensorService = `${accessory.displayName} Light Sensor`;
130
+ (this.LightSensor!.Service = this.accessory.getService(this.hap.Service.LightSensor)
131
+ || this.accessory.addService(this.hap.Service.LightSensor)), LightSensorService;
175
132
 
176
- this.lightSensorService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Light Sensor`);
177
- if (!this.lightSensorService?.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
178
- this.lightSensorService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Light Sensor`);
179
- }
133
+ this.LightSensor!.Service.setCharacteristic(this.hap.Characteristic.Name, LightSensorService);
180
134
  } else {
181
135
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
182
136
  }
183
137
 
184
138
  // Battery Service
185
139
  const batteryService = `${accessory.displayName} Battery`;
186
- (this.batteryService = this.accessory.getService(this.hap.Service.Battery)
140
+ (this.Battery.Service = this.accessory.getService(this.hap.Service.Battery)
187
141
  || accessory.addService(this.hap.Service.Battery)), batteryService;
188
142
 
189
- this.batteryService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Battery`);
190
- if (!this.batteryService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
191
- this.batteryService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Battery`);
192
- }
143
+ this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Battery`);
193
144
 
194
145
  // Update Homekit
195
146
  this.updateHomeKitCharacteristics();
@@ -208,13 +159,12 @@ export class Curtain {
208
159
  try {
209
160
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
210
161
  const { slidePosition, battery } = context;
211
- const { CurrentPosition, BatteryLevel } = this;
212
162
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
213
163
  '(slidePosition, battery) = ' +
214
164
  `Webhook:(${slidePosition}, ${battery}), ` +
215
- `current:(${CurrentPosition}, ${BatteryLevel})`);
216
- this.CurrentPosition = slidePosition;
217
- this.BatteryLevel = battery;
165
+ `current:(${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel})`);
166
+ this.WindowCovering.CurrentPosition = slidePosition;
167
+ this.Battery.BatteryLevel = battery;
218
168
  this.updateHomeKitCharacteristics();
219
169
  } catch (e: any) {
220
170
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
@@ -224,13 +174,14 @@ export class Curtain {
224
174
  }
225
175
 
226
176
  // update slide progress
227
- interval(this.updateRate * 1000)
177
+ interval(this.deviceUpdateRate * 1000)
228
178
  //.pipe(skipWhile(() => this.curtainUpdateInProgress))
229
179
  .subscribe(async () => {
230
- if (this.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
180
+ if (this.WindowCovering.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
231
181
  return;
232
182
  }
233
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving, PositionState: ${this.PositionState}`);
183
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving,`
184
+ + ` PositionState: ${this.WindowCovering.PositionState}`);
234
185
  await this.refreshStatus();
235
186
  });
236
187
 
@@ -260,6 +211,16 @@ export class Curtain {
260
211
  this.setupHistoryService(device);
261
212
  }
262
213
 
214
+ private history(device: device & devicesConfig) {
215
+ if (device.history === true) {
216
+ // initialize when this accessory is newly created.
217
+ this.accessory.context.lastActivation = this.accessory.context.lastActivation ?? 0;
218
+ } else {
219
+ // removes cached values if history is turned off
220
+ delete this.accessory.context.lastActivation;
221
+ }
222
+ }
223
+
263
224
  /*
264
225
  * Setup EVE history features for curtain devices.
265
226
  */
@@ -307,7 +268,7 @@ export class Curtain {
307
268
  }
308
269
 
309
270
  async updateHistory(): Promise<void> {
310
- const motion = Number(this.CurrentPosition) > 0 ? 1 : 0;
271
+ const motion = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
311
272
  this.historyService.addEntry({
312
273
  time: Math.round(new Date().valueOf() / 1000),
313
274
  motion: motion,
@@ -320,198 +281,189 @@ export class Curtain {
320
281
  );
321
282
  }
322
283
 
323
- /**
324
- * Parse the device status from the SwitchBot api
325
- */
326
- async parseStatus(): Promise<void> {
327
- if (!this.device.enableCloudService && this.OpenAPI) {
328
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
329
- } else if (this.BLE) {
330
- await this.BLEparseStatus();
331
- } else if (this.OpenAPI && this.platform.config.credentials?.token) {
332
- await this.openAPIparseStatus();
333
- } else {
334
- await this.offlineOff();
335
- this.debugWarnLog(
336
- `${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`,
337
- );
338
- }
339
- }
340
-
341
- async BLEparseStatus(): Promise<void> {
284
+ async BLEparseStatus(serviceData: serviceData): Promise<void> {
342
285
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
343
286
  // CurrentPosition
344
- this.CurrentPosition = 100 - Number(this.BLE_CurrentPosition);
287
+ this.WindowCovering.CurrentPosition = 100 - Number(serviceData.position);
345
288
  await this.setMinMax();
346
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.CurrentPosition}`);
289
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.WindowCovering.CurrentPosition}`);
347
290
  if (this.setNewTarget) {
348
291
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
349
292
  await this.setMinMax();
350
- if (Number(this.TargetPosition) > this.CurrentPosition) {
351
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition}`);
352
- this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
353
- this.windowCoveringService.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.PositionState);
354
- this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} INCREASING PositionState: ${this.PositionState}`);
355
- } else if (Number(this.TargetPosition) < this.CurrentPosition) {
356
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.CurrentPosition}`);
357
- this.PositionState = this.hap.Characteristic.PositionState.DECREASING;
358
- this.windowCoveringService.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.PositionState);
359
- this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} DECREASING PositionState: ${this.PositionState}`);
293
+ if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
294
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
295
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
296
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
297
+ this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
298
+ + ` PositionState: ${this.WindowCovering.PositionState}`);
299
+ } else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
300
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
301
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
302
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
303
+ this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
304
+ + ` PositionState: ${this.WindowCovering.PositionState}`);
360
305
  } else {
361
- this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby, CurrentPosition: ${this.CurrentPosition}`);
362
- this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
363
- this.windowCoveringService.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.PositionState);
364
- this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} STOPPED PositionState: ${this.PositionState}`);
306
+ this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
307
+ + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
308
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
309
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
310
+ this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
311
+ + ` PositionState: ${this.WindowCovering.PositionState}`);
365
312
  }
366
313
  } else {
367
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.CurrentPosition}`);
368
- this.TargetPosition = this.CurrentPosition;
369
- this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
314
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
315
+ this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
316
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
370
317
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
371
318
  }
372
319
  this.debugLog(
373
- `${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
374
- ` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
320
+ `${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},` +
321
+ ` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`,
375
322
  );
376
323
 
377
324
  if (!this.device.curtain?.hide_lightsensor) {
378
- this.set_minLux = this.minLux();
379
- this.set_maxLux = this.maxLux();
380
- this.spaceBetweenLevels = 9;
325
+ const set_minLux = await this.minLux();
326
+ const set_maxLux = await this.maxLux();
327
+ const spaceBetweenLevels = 9;
381
328
 
382
329
  // Brightness
383
- switch (this.BLE_CurrentAmbientLightLevel) {
330
+ switch (serviceData.lightLevel) {
384
331
  case 1:
385
- this.CurrentAmbientLightLevel = this.set_minLux;
386
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel}`);
332
+ this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
333
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
387
334
  break;
388
335
  case 2:
389
- this.CurrentAmbientLightLevel = (this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels;
336
+ this.LightSensor!.CurrentAmbientLightLevel = (set_maxLux - set_minLux) / spaceBetweenLevels;
390
337
  this.debugLog(
391
- `${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel},` +
392
- ` Calculation: ${(this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels}`,
338
+ `${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},` +
339
+ ` Calculation: ${(set_maxLux - set_minLux) / spaceBetweenLevels}`,
393
340
  );
394
341
  break;
395
342
  case 3:
396
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 2;
397
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel}`);
343
+ this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 2;
344
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
398
345
  break;
399
346
  case 4:
400
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 3;
401
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel}`);
347
+ this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 3;
348
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
402
349
  break;
403
350
  case 5:
404
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 4;
405
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel}`);
351
+ this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 4;
352
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
406
353
  break;
407
354
  case 6:
408
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 5;
409
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel}`);
355
+ this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 5;
356
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
410
357
  break;
411
358
  case 7:
412
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 6;
413
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel}`);
359
+ this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 6;
360
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
414
361
  break;
415
362
  case 8:
416
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 7;
417
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel}`);
363
+ this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 7;
364
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
418
365
  break;
419
366
  case 9:
420
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 8;
421
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel}`);
367
+ this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 8;
368
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
422
369
  break;
423
370
  case 10:
424
371
  default:
425
- this.CurrentAmbientLightLevel = this.set_maxLux;
372
+ this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
426
373
  this.debugLog();
427
374
  }
428
375
  this.debugLog(
429
- `${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel},` +
430
- ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
376
+ `${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},` +
377
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`,
431
378
  );
432
379
  }
433
380
  // Battery
434
- this.BatteryLevel = Number(this.BLE_BatteryLevel);
435
- if (this.BatteryLevel < 10) {
436
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
381
+ this.Battery.BatteryLevel = Number(serviceData.battery);
382
+ if (this.Battery.BatteryLevel < 10) {
383
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
437
384
  } else {
438
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
385
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
439
386
  }
440
387
  this.debugLog(
441
- `${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},` + ` StatusLowBattery: ${this.StatusLowBattery}`,
388
+ `${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
389
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`,
442
390
  );
443
391
  }
444
392
 
445
- async openAPIparseStatus(): Promise<void> {
393
+ async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
446
394
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
447
395
  // CurrentPosition
448
- this.CurrentPosition = 100 - Number(this.OpenAPI_CurrentPosition);
396
+ this.WindowCovering.CurrentPosition = 100 - Number(deviceStatus.body.slidePosition);
449
397
  await this.setMinMax();
450
- this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
398
+ this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
451
399
  if (this.setNewTarget) {
452
400
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
453
401
  }
454
402
 
455
- if (this.setNewTarget && this.OpenAPI_InMotion) {
403
+ if (this.setNewTarget && deviceStatus.body.moving) {
456
404
  await this.setMinMax();
457
- if (Number(this.TargetPosition) > this.CurrentPosition) {
458
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition} `);
459
- this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
460
- this.windowCoveringService.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.PositionState);
461
- this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} INCREASING PositionState: ${this.PositionState}`);
462
- } else if (Number(this.TargetPosition) < this.CurrentPosition) {
463
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.CurrentPosition} `);
464
- this.PositionState = this.hap.Characteristic.PositionState.DECREASING;
465
- this.windowCoveringService.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.PositionState);
466
- this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} DECREASING PositionState: ${this.PositionState}`);
405
+ if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
406
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
407
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
408
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
409
+ this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
410
+ + ` PositionState: ${this.WindowCovering.PositionState}`);
411
+ } else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
412
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
413
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
414
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
415
+ this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
416
+ + ` PositionState: ${this.WindowCovering.PositionState}`);
467
417
  } else {
468
- this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby, CurrentPosition: ${this.CurrentPosition}`);
469
- this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
470
- this.windowCoveringService.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.PositionState);
471
- this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} STOPPED PositionState: ${this.PositionState}`);
418
+ this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
419
+ + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
420
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
421
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
422
+ this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
423
+ + ` PositionState: ${this.WindowCovering.PositionState}`);
472
424
  }
473
425
  } else {
474
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.CurrentPosition}`);
475
- this.TargetPosition = this.CurrentPosition;
476
- this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
426
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
427
+ this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
428
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
477
429
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
478
430
  }
479
431
  this.debugLog(
480
- `${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
481
- ` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
432
+ `${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},` +
433
+ ` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`,
482
434
  );
483
435
 
484
436
  // Brightness
485
437
  if (!this.device.curtain?.hide_lightsensor) {
486
- this.set_minLux = this.minLux();
487
- this.set_maxLux = this.maxLux();
488
- switch (this.OpenAPI_CurrentAmbientLightLevel) {
438
+ const set_minLux = await this.minLux();
439
+ const set_maxLux = await this.maxLux();
440
+ switch (deviceStatus.body.brightness) {
489
441
  case 'dim':
490
- this.CurrentAmbientLightLevel = this.set_minLux;
442
+ this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
491
443
  break;
492
444
  case 'bright':
493
445
  default:
494
- this.CurrentAmbientLightLevel = this.set_maxLux;
446
+ this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
495
447
  }
496
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
448
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
449
+ + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
497
450
  }
498
451
 
499
452
  // BatteryLevel
500
- this.BatteryLevel = Number(this.OpenAPI_BatteryLevel);
501
- if (this.BatteryLevel < 10) {
502
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
453
+ this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
454
+ if (this.Battery.BatteryLevel < 10) {
455
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
503
456
  } else {
504
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
457
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
505
458
  }
506
- if (Number.isNaN(this.BatteryLevel)) {
507
- this.BatteryLevel = 100;
459
+ if (Number.isNaN(this.Battery.BatteryLevel)) {
460
+ this.Battery.BatteryLevel = 100;
508
461
  }
509
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
510
- + ` StatusLowBattery: ${this.StatusLowBattery}`);
462
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
463
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
511
464
 
512
465
  // FirmwareRevision
513
- this.FirmwareRevision = this.OpenAPI_FirmwareRevision!;
514
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
466
+ this.accessory.context.FirmwareRevision = deviceStatus.body.version;
515
467
  }
516
468
 
517
469
  async refreshStatus(): Promise<void> {
@@ -541,106 +493,37 @@ export class Curtain {
541
493
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
542
494
  this.getCustomBLEAddress(switchbot);
543
495
  // Start to monitor advertisement packets
544
- let model: string;
545
- switch (this.device.configDeviceType) {
546
- case 'Curtain3':
547
- model = '{';
548
- break;
549
- default:
550
- model = 'c';
551
- }
552
496
  (async () => {
553
497
  // Start to monitor advertisement packets
554
- await switchbot.startScan({
555
- model: model,
556
- id: this.device.bleMac,
557
- });
498
+ await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
558
499
  // Set an event handler
559
500
  switchbot.onadvertisement = (ad: any) => {
560
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
561
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.serviceData.model}`);
562
- if (this.device.bleMac === ad.address && ad.serviceData.model === 'c') {
501
+ if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
502
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
503
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
563
504
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
564
- this.BLE_Calibration = ad.serviceData.calibration;
565
- this.BLE_BatteryLevel = ad.serviceData.battery;
566
- this.BLE_InMotion = ad.serviceData.inMotion;
567
- this.BLE_CurrentPosition = ad.serviceData.position;
568
- this.BLE_CurrentAmbientLightLevel = ad.serviceData.lightLevel;
569
505
  } else {
570
506
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
571
507
  }
572
508
  };
573
- // Wait 1 seconds
509
+ // Wait 10 seconds
574
510
  await switchbot.wait(this.scanDuration * 1000);
575
511
  // Stop to monitor
576
512
  await switchbot.stopScan();
577
513
  // Update HomeKit
578
- await this.BLEparseStatus();
514
+ await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
579
515
  await this.updateHomeKitCharacteristics();
580
516
  })();
581
-
582
-
583
- /*if (switchbot !== false) {
584
- switchbot
585
- .startScan({
586
- model: model,
587
- id: this.device.bleMac,
588
- })
589
- .then(async () => {
590
- // Set an event handler
591
- switchbot.onadvertisement = async (ad: ad) => {
592
- this.debugLog(
593
- `${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
594
- ` BLE Address Found: ${ad.address}`,
595
- );
596
- this.BLE_Calibration = ad.serviceData.calibration;
597
- this.BLE_BatteryLevel = ad.serviceData.battery;
598
- this.BLE_InMotion = ad.serviceData.inMotion;
599
- this.BLE_CurrentPosition = ad.serviceData.position;
600
- this.BLE_CurrentAmbientLightLevel = ad.serviceData.lightLevel;
601
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
602
- this.debugLog(
603
- `${this.device.deviceType}: ${this.accessory.displayName} calibration: ${ad.serviceData.calibration}, ` +
604
- `position: ${ad.serviceData.position}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}, ` +
605
- `inMotion: ${ad.serviceData.inMotion}`,
606
- );
607
-
608
- if (ad.serviceData) {
609
- this.BLE_IsConnected = true;
610
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
611
- await this.stopScanning(switchbot);
612
- } else {
613
- this.BLE_IsConnected = false;
614
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
615
- }
616
- };
617
- // Wait
618
- return await sleep(this.scanDuration * 1000);
619
- })
620
- .then(async () => {
621
- // Stop to monitor
622
- await this.stopScanning(switchbot);
623
- })
624
- .catch(async (e: any) => {
625
- this.apiError(e);
626
- this.errorLog(
627
- `${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
628
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
629
- );
630
- await this.BLERefreshConnection(switchbot);
631
- });
632
- } else {
517
+ if (switchbot === undefined) {
633
518
  await this.BLERefreshConnection(switchbot);
634
- }*/
519
+ }
635
520
  }
636
521
 
637
522
  async openAPIRefreshStatus(): Promise<void> {
638
523
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
639
524
  try {
640
- const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
641
- `${Devices}/${this.device.deviceId}/status`, {
642
- headers: this.platform.generateHeaders(),
643
- });
525
+ const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
526
+ `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
644
527
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
645
528
  const deviceStatus: any = await body.json();
646
529
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -648,12 +531,7 @@ export class Curtain {
648
531
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
649
532
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
650
533
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
651
- this.OpenAPI_CurrentPosition = deviceStatus.body.slidePosition;
652
- this.OpenAPI_InMotion = deviceStatus.body.moving;
653
- this.OpenAPI_CurrentAmbientLightLevel = deviceStatus.body.brightness;
654
- this.OpenAPI_BatteryLevel = deviceStatus.body.battery;
655
- this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
656
- this.openAPIparseStatus();
534
+ this.openAPIparseStatus(deviceStatus);
657
535
  this.updateHomeKitCharacteristics();
658
536
  } else {
659
537
  this.statusCode(statusCode);
@@ -692,7 +570,7 @@ export class Curtain {
692
570
 
693
571
  async BLEpushChanges(): Promise<void> {
694
572
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
695
- if (this.TargetPosition !== this.CurrentPosition) {
573
+ if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
696
574
  const switchbot = await this.platform.connectBLE();
697
575
  // Convert to BLE Address
698
576
  this.device.bleMac = this.device
@@ -700,29 +578,29 @@ export class Curtain {
700
578
  .join(':')
701
579
  .toLowerCase();
702
580
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
703
- this.SilentPerformance();
704
- const adjustedMode = this.setPositionMode === '1' ? 0x01 : 0xff;
705
- this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
581
+ const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
582
+ const adjustedMode = setPositionMode === 1 ? 0x01 : 0xff;
583
+ this.debugLog(`${this.accessory.displayName} Mode: ${Mode}`);
706
584
  if (switchbot !== false) {
707
585
  try {
708
586
  const device_list = await switchbot.discover({ model: 'c', quick: true, id: this.device.bleMac });
709
- this.infoLog(`${this.accessory.displayName} Target Position: ${this.TargetPosition}`);
587
+ this.infoLog(`${this.accessory.displayName} Target Position: ${this.WindowCovering.TargetPosition}`);
710
588
 
711
- await this.retry({
712
- max: this.maxRetry(),
589
+ await this.retryBLE({
590
+ max: await this.maxRetryBLE(),
713
591
  fn: async () => {
714
- await device_list[0].runToPos(100 - Number(this.TargetPosition), adjustedMode);
592
+ await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode);
715
593
  },
716
594
  });
717
595
 
718
596
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
719
597
  this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
720
- + `TargetPosition: ${this.TargetPosition} sent over BLE, sent successfully`);
598
+ + `TargetPosition: ${this.WindowCovering.TargetPosition} sent over BLE, sent successfully`);
721
599
  } catch (e) {
722
600
  this.apiError(e);
723
601
  this.errorLog(
724
602
  `${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}` +
725
- ` Connection, Error Message: ${JSON.stringify((e as Error).message)}`,
603
+ ` Connection, Error Message: ${JSON.stringify((e as Error).message)}`,
726
604
  );
727
605
  await this.BLEPushConnection();
728
606
  throw new Error('Connection error');
@@ -734,54 +612,23 @@ export class Curtain {
734
612
  } else {
735
613
  this.debugLog(
736
614
  `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.` +
737
- ` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
615
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`,
738
616
  );
739
617
  }
740
618
  }
741
619
 
742
- async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
743
- return fn().catch(async (e: any) => {
744
- if (max === 0) {
745
- throw e;
746
- }
747
- this.infoLog(e);
748
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Retrying`);
749
- await sleep(1000);
750
- return this.retry({ max: max - 1, fn });
751
- });
752
- }
753
-
754
- maxRetry(): number {
755
- if (this.device.maxRetry) {
756
- return this.device.maxRetry;
757
- } else {
758
- return 5;
759
- }
760
- }
761
-
762
620
  async openAPIpushChanges(): Promise<void> {
763
621
  let command: string;
764
622
  let parameter: string;
765
623
  let commandType: string;
766
624
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
767
- if (this.TargetPosition !== this.CurrentPosition || this.device.disableCaching) {
768
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.TargetPosition}`);
769
- const adjustedTargetPosition = 100 - Number(this.TargetPosition);
770
- if (Number(this.TargetPosition) > 50) {
771
- this.setPositionMode = this.device.curtain?.setOpenMode;
772
- } else {
773
- this.setPositionMode = this.device.curtain?.setCloseMode;
774
- }
775
- if (this.setPositionMode === '1') {
776
- this.Mode = 'Silent Mode';
777
- } else if (this.setPositionMode === '0') {
778
- this.Mode = 'Performance Mode';
779
- } else {
780
- this.Mode = 'Default Mode';
781
- }
782
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${this.Mode}`);
783
- const adjustedMode = this.setPositionMode || 'ff';
784
- if (this.HoldPosition) {
625
+ if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition || this.device.disableCaching) {
626
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.WindowCovering.TargetPosition}`);
627
+ const adjustedTargetPosition = 100 - Number(this.WindowCovering.TargetPosition);
628
+ const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
629
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${Mode}`);
630
+ const adjustedMode = setPositionMode || 'ff';
631
+ if (this.WindowCovering.HoldPosition) {
785
632
  command = 'pause';
786
633
  parameter = 'default';
787
634
  commandType = 'command';
@@ -811,7 +658,7 @@ export class Curtain {
811
658
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
812
659
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
813
660
  this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
814
- + `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
661
+ + `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
815
662
  } else {
816
663
  this.statusCode(statusCode);
817
664
  this.statusCode(deviceStatus.statusCode);
@@ -826,7 +673,7 @@ export class Curtain {
826
673
  } else {
827
674
  this.debugLog(
828
675
  `${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.` +
829
- ` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
676
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`,
830
677
  );
831
678
  }
832
679
  }
@@ -835,50 +682,53 @@ export class Curtain {
835
682
  * Handle requests to set the value of the "Target Position" characteristic
836
683
  */
837
684
  async TargetPositionSet(value: CharacteristicValue): Promise<void> {
838
- if (this.TargetPosition === this.accessory.context.TargetPosition) {
685
+ if (this.WindowCovering.TargetPosition === this.accessory.context.TargetPosition) {
839
686
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetPosition: ${value}`);
840
687
  } else {
841
688
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
842
689
  }
843
690
 
844
691
  // Set HoldPosition to false when TargetPosition is changed
845
- this.HoldPosition = false;
846
- this.windowCoveringService.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.HoldPosition);
692
+ this.WindowCovering.HoldPosition = false;
693
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
847
694
 
848
- this.TargetPosition = value;
695
+ this.WindowCovering.TargetPosition = value;
849
696
  if (this.device.mqttURL) {
850
- this.mqttPublish('TargetPosition', this.TargetPosition);
851
- this.mqttPublish('HoldPosition', this.HoldPosition);
697
+ this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
698
+ this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString()); // Convert boolean to string
852
699
  }
853
700
 
854
701
  await this.setMinMax();
855
- if (value > this.CurrentPosition) {
856
- this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
702
+ if (value > this.WindowCovering.CurrentPosition) {
703
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
857
704
  this.setNewTarget = true;
858
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
859
- } else if (value < this.CurrentPosition) {
860
- this.PositionState = this.hap.Characteristic.PositionState.DECREASING;
705
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
706
+ + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
707
+ } else if (value < this.WindowCovering.CurrentPosition) {
708
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
861
709
  this.setNewTarget = true;
862
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
710
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
711
+ + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
863
712
  } else {
864
- this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
713
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
865
714
  this.setNewTarget = false;
866
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
715
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
716
+ + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
867
717
  }
868
- this.windowCoveringService.setCharacteristic(this.hap.Characteristic.PositionState, this.PositionState);
869
- this.windowCoveringService.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.PositionState);
718
+ this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
719
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
870
720
 
871
721
  /**
872
722
  * If Curtain movement time is short, the moving flag from backend is always false.
873
723
  * The minimum time depends on the network control latency.
874
724
  */
875
725
  clearTimeout(this.setNewTargetTimer);
876
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.updateRate}`);
726
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.deviceUpdateRate}`);
877
727
  if (this.setNewTarget) {
878
728
  this.setNewTargetTimer = setTimeout(() => {
879
729
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
880
730
  this.setNewTarget = false;
881
- }, this.updateRate * 1000);
731
+ }, this.deviceUpdateRate * 1000);
882
732
  }
883
733
  this.doCurtainUpdate.next();
884
734
  }
@@ -888,153 +738,98 @@ export class Curtain {
888
738
  */
889
739
  async HoldPositionSet(value: CharacteristicValue): Promise<void> {
890
740
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${value}`);
891
- this.HoldPosition = value;
741
+ this.WindowCovering.HoldPosition = value;
892
742
  this.doCurtainUpdate.next();
893
743
  }
894
744
 
895
745
  async updateHomeKitCharacteristics(): Promise<void> {
896
746
  await this.setMinMax();
897
- if (this.CurrentPosition === undefined || Number.isNaN(this.CurrentPosition)) {
898
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
747
+ if (this.WindowCovering.CurrentPosition === undefined || Number.isNaN(this.WindowCovering.CurrentPosition)) {
748
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
899
749
  } else {
750
+ this.accessory.context.CurrentPosition = this.WindowCovering.CurrentPosition;
751
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.WindowCovering.CurrentPosition));
752
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
753
+ + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
900
754
  if (this.device.mqttURL) {
901
- this.mqttPublish('CurrentPosition', this.CurrentPosition);
755
+ this.mqttPublish('CurrentPosition', this.WindowCovering.CurrentPosition.toString()); // Convert to string
902
756
  }
903
- this.accessory.context.CurrentPosition = this.CurrentPosition;
904
- this.windowCoveringService.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.CurrentPosition));
905
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentPosition: ${this.CurrentPosition}`);
906
757
  }
907
- if (this.PositionState === undefined) {
908
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.PositionState}`);
758
+ if (this.WindowCovering.PositionState === undefined) {
759
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.WindowCovering.PositionState}`);
909
760
  } else {
910
761
  if (this.device.mqttURL) {
911
- this.mqttPublish('PositionState', this.PositionState);
762
+ this.mqttPublish('PositionState', this.WindowCovering.PositionState.toString());
912
763
  }
913
- this.accessory.context.PositionState = this.PositionState;
914
- this.windowCoveringService.updateCharacteristic(this.hap.Characteristic.PositionState, Number(this.PositionState));
915
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic PositionState: ${this.PositionState}`);
764
+ this.accessory.context.PositionState = this.WindowCovering.PositionState;
765
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, Number(this.WindowCovering.PositionState));
766
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
767
+ + ` PositionState: ${this.WindowCovering.PositionState}`);
916
768
  }
917
- if (this.TargetPosition === undefined || Number.isNaN(this.TargetPosition)) {
918
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
769
+ if (this.WindowCovering.TargetPosition === undefined || Number.isNaN(this.WindowCovering.TargetPosition)) {
770
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.WindowCovering.TargetPosition}`);
919
771
  } else {
920
772
  if (this.device.mqttURL) {
921
- this.mqttPublish('TargetPosition', this.TargetPosition);
773
+ this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
922
774
  }
923
- this.accessory.context.TargetPosition = this.TargetPosition;
924
- this.windowCoveringService.updateCharacteristic(this.hap.Characteristic.TargetPosition, Number(this.TargetPosition));
925
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: ${this.TargetPosition}`);
775
+ this.accessory.context.TargetPosition = this.WindowCovering.TargetPosition;
776
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, Number(this.WindowCovering.TargetPosition));
777
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
778
+ + ` TargetPosition: ${this.WindowCovering.TargetPosition}`);
926
779
  }
927
- if (this.HoldPosition === undefined) {
928
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.HoldPosition}`);
780
+ if (this.WindowCovering.HoldPosition === undefined) {
781
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.WindowCovering.HoldPosition}`);
929
782
  } else {
930
783
  if (this.device.mqttURL) {
931
- this.mqttPublish('HoldPosition', this.HoldPosition);
784
+ this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString());
932
785
  }
933
- this.accessory.context.HoldPosition = this.HoldPosition;
934
- this.windowCoveringService.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.HoldPosition);
935
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic HoldPosition: ${this.HoldPosition}`);
786
+ this.accessory.context.HoldPosition = this.WindowCovering.HoldPosition;
787
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
788
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
789
+ + ` HoldPosition: ${this.WindowCovering.HoldPosition}`);
936
790
  }
937
791
  if (!this.device.curtain?.hide_lightsensor) {
938
- if (this.CurrentAmbientLightLevel === undefined || Number.isNaN(this.CurrentAmbientLightLevel)) {
939
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
792
+ if (this.LightSensor!.CurrentAmbientLightLevel === undefined || Number.isNaN(this.LightSensor!.CurrentAmbientLightLevel)) {
793
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
794
+ + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
940
795
  } else {
941
796
  if (this.device.mqttURL) {
942
- this.mqttPublish('CurrentAmbientLightLevel', this.CurrentAmbientLightLevel);
797
+ this.mqttPublish('CurrentAmbientLightLevel', this.LightSensor!.CurrentAmbientLightLevel.toString());
943
798
  }
944
- this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
945
- this.lightSensorService?.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
799
+ this.accessory.context.CurrentAmbientLightLevel = this.LightSensor!.CurrentAmbientLightLevel;
800
+ this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor!.CurrentAmbientLightLevel);
946
801
  this.debugLog(
947
802
  `${this.device.deviceType}: ${this.accessory.displayName}` +
948
- ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
803
+ ` updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`,
949
804
  );
950
805
  if (this.device.history) {
951
806
  this.historyService?.addEntry({
952
807
  time: Math.round(new Date().valueOf() / 1000),
953
- lux: this.CurrentAmbientLightLevel,
808
+ lux: this.LightSensor!.CurrentAmbientLightLevel,
954
809
  });
955
810
  }
956
811
  }
957
812
  }
958
- if (this.BatteryLevel === undefined) {
959
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
813
+ if (this.Battery.BatteryLevel === undefined) {
814
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
960
815
  } else {
961
816
  if (this.device.mqttURL) {
962
- this.mqttPublish('BatteryLevel', this.BatteryLevel);
817
+ this.mqttPublish('BatteryLevel', this.Battery.BatteryLevel.toString());
963
818
  }
964
- this.accessory.context.BatteryLevel = this.BatteryLevel;
965
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.BatteryLevel);
966
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
819
+ this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
820
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
821
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
967
822
  }
968
- if (this.StatusLowBattery === undefined) {
969
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
823
+ if (this.Battery.StatusLowBattery === undefined) {
824
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
970
825
  } else {
971
826
  if (this.device.mqttURL) {
972
- this.mqttPublish('StatusLowBattery', this.StatusLowBattery);
973
- }
974
- this.accessory.context.StatusLowBattery = this.StatusLowBattery;
975
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.StatusLowBattery);
976
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
977
- }
978
- }
979
-
980
- /*
981
- * Publish MQTT message for topics of
982
- * 'homebridge-switchbot/curtain/xx:xx:xx:xx:xx:xx'
983
- */
984
- mqttPublish(topic: string, message: any) {
985
- const mac = this.device.deviceId
986
- ?.toLowerCase()
987
- .match(/[\s\S]{1,2}/g)
988
- ?.join(':');
989
- const options = this.device.mqttPubOptions || {};
990
- this.mqttClient?.publish(`homebridge-switchbot/curtain/${mac}/${topic}`, `${message}`, options);
991
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${topic}/${message} options:${JSON.stringify(options)}`);
992
- }
993
-
994
- /*
995
- * Setup MQTT hadler if URL is specified.
996
- */
997
- async setupMqtt(device: device & devicesConfig): Promise<void> {
998
- if (device.mqttURL) {
999
- try {
1000
- const { connectAsync } = asyncmqtt;
1001
- this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
1002
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT connection has been established successfully.`);
1003
- this.mqttClient.on('error', (e: Error) => {
1004
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
1005
- });
1006
- } catch (e) {
1007
- this.mqttClient = null;
1008
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
827
+ this.mqttPublish('StatusLowBattery', this.Battery.StatusLowBattery.toString());
1009
828
  }
1010
- }
1011
- }
1012
-
1013
- async stopScanning(switchbot: any) {
1014
- switchbot.stopScan();
1015
- if (this.BLE_IsConnected) {
1016
- await this.BLEparseStatus();
1017
- await this.updateHomeKitCharacteristics();
1018
- } else {
1019
- await this.BLERefreshConnection(switchbot);
1020
- }
1021
- }
1022
-
1023
- async getCustomBLEAddress(switchbot: any) {
1024
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
1025
- (async () => {
1026
- // Start to monitor advertisement packets
1027
- await switchbot.startScan({
1028
- model: 'c',
1029
- });
1030
- // Set an event handler
1031
- switchbot.onadvertisement = (ad: any) => {
1032
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
1033
- };
1034
- await sleep(10000);
1035
- // Stop to monitor
1036
- switchbot.stopScan();
1037
- })();
829
+ this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
830
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
831
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
832
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
1038
833
  }
1039
834
  }
1040
835
 
@@ -1054,387 +849,100 @@ export class Curtain {
1054
849
  }
1055
850
  }
1056
851
 
1057
- async SilentPerformance() {
1058
- if (Number(this.TargetPosition) > 50) {
1059
- if (this.device.curtain?.setOpenMode === '1') {
1060
- this.setPositionMode = '1';
1061
- this.Mode = 'Silent Mode';
852
+ async setPerformance() {
853
+ let setPositionMode: number;
854
+ let Mode: string;
855
+ if (Number(this.WindowCovering.TargetPosition) > 50) {
856
+ if (this.device.blindTilt?.setOpenMode === '1') {
857
+ setPositionMode = 1;
858
+ Mode = 'Silent Mode';
859
+ } else if (this.device.blindTilt?.setOpenMode === '0') {
860
+ setPositionMode = 0;
861
+ Mode = 'Performance Mode';
1062
862
  } else {
1063
- this.setPositionMode = '0';
1064
- this.Mode = 'Performance Mode';
863
+ setPositionMode = 0;
864
+ Mode = 'Default Mode';
1065
865
  }
1066
866
  } else {
1067
- if (this.device.curtain?.setCloseMode === '1') {
1068
- this.setPositionMode = '1';
1069
- this.Mode = 'Silent Mode';
867
+ if (this.device.blindTilt?.setCloseMode === '1') {
868
+ setPositionMode = 1;
869
+ Mode = 'Silent Mode';
870
+ } else if (this.device.blindTilt?.setOpenMode === '0') {
871
+ setPositionMode = 0;
872
+ Mode = 'Performance Mode';
1070
873
  } else {
1071
- this.setPositionMode = '0';
1072
- this.Mode = 'Performance Mode';
874
+ setPositionMode = 0;
875
+ Mode = 'Default Mode';
1073
876
  }
1074
877
  }
878
+ return { setPositionMode, Mode };
1075
879
  }
1076
880
 
1077
881
  async setMinMax(): Promise<void> {
1078
882
  if (this.device.curtain?.set_min) {
1079
- if (Number(this.CurrentPosition) <= this.device.curtain?.set_min) {
1080
- this.CurrentPosition = 0;
883
+ if (Number(this.WindowCovering.CurrentPosition) <= this.device.curtain?.set_min) {
884
+ this.WindowCovering.CurrentPosition = 0;
1081
885
  }
1082
886
  }
1083
887
  if (this.device.curtain?.set_max) {
1084
- if (Number(this.CurrentPosition) >= this.device.curtain?.set_max) {
1085
- this.CurrentPosition = 100;
888
+ if (Number(this.WindowCovering.CurrentPosition) >= this.device.curtain?.set_max) {
889
+ this.WindowCovering.CurrentPosition = 100;
1086
890
  }
1087
891
  }
1088
892
  if (this.device.history) {
1089
893
  const motion = this.accessory.getService(this.hap.Service.MotionSensor);
1090
- const state = Number(this.CurrentPosition) > 0 ? 1 : 0;
894
+ const state = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
1091
895
  motion?.updateCharacteristic(this.hap.Characteristic.MotionDetected, state);
1092
896
  }
1093
897
  }
1094
898
 
1095
899
  minStep(device: device & devicesConfig): number {
900
+ let set_minStep: number;
1096
901
  if (device.curtain?.set_minStep) {
1097
- this.set_minStep = device.curtain?.set_minStep;
902
+ set_minStep = device.curtain?.set_minStep;
1098
903
  } else {
1099
- this.set_minStep = 1;
904
+ set_minStep = 1;
1100
905
  }
1101
- return this.set_minStep;
906
+ return set_minStep;
1102
907
  }
1103
908
 
1104
- minLux(): number {
909
+ async minLux(): Promise<number> {
910
+ let set_minLux: number;
1105
911
  if (this.device.curtain?.set_minLux) {
1106
- this.set_minLux = this.device.curtain?.set_minLux;
912
+ set_minLux = this.device.curtain?.set_minLux;
1107
913
  } else {
1108
- this.set_minLux = 1;
914
+ set_minLux = 1;
1109
915
  }
1110
- return this.set_minLux;
916
+ return set_minLux;
1111
917
  }
1112
918
 
1113
- maxLux(): number {
919
+ async maxLux(): Promise<number> {
920
+ let set_maxLux: number;
1114
921
  if (this.device.curtain?.set_maxLux) {
1115
- this.set_maxLux = this.device.curtain?.set_maxLux;
1116
- } else {
1117
- this.set_maxLux = 6001;
1118
- }
1119
- return this.set_maxLux;
1120
- }
1121
-
1122
- async scan(device: device & devicesConfig): Promise<void> {
1123
- if (device.scanDuration) {
1124
- if (this.updateRate > device.scanDuration) {
1125
- this.scanDuration = this.updateRate;
1126
- if (this.BLE) {
1127
- this.warnLog(
1128
- `${this.device.deviceType}: ` +
1129
- `${this.accessory.displayName} scanDuration is less than updateRate, overriding scanDuration with updateRate`,
1130
- );
1131
- }
1132
- } else {
1133
- this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
1134
- }
1135
- if (this.BLE) {
1136
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
1137
- }
922
+ set_maxLux = this.device.curtain?.set_maxLux;
1138
923
  } else {
1139
- if (this.updateRate > 1) {
1140
- this.scanDuration = this.updateRate;
1141
- } else {
1142
- this.scanDuration = this.accessory.context.scanDuration = 1;
1143
- }
1144
- if (this.BLE) {
1145
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
1146
- }
1147
- }
1148
- }
1149
-
1150
- async statusCode(statusCode: number): Promise<void> {
1151
- switch (statusCode) {
1152
- case 151:
1153
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
1154
- break;
1155
- case 152:
1156
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
1157
- break;
1158
- case 160:
1159
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
1160
- break;
1161
- case 161:
1162
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
1163
- this.offlineOff();
1164
- break;
1165
- case 171:
1166
- this.errorLog(
1167
- `${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
1168
- `Hub: ${this.device.hubDeviceId}`,
1169
- );
1170
- this.offlineOff();
1171
- break;
1172
- case 190:
1173
- this.errorLog(
1174
- `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
1175
- ` Or command format is invalid, statusCode: ${statusCode}`,
1176
- );
1177
- break;
1178
- case 100:
1179
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
1180
- break;
1181
- case 200:
1182
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
1183
- break;
1184
- case 400:
1185
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
1186
- + `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
1187
- break;
1188
- case 401:
1189
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
1190
- + `but the request has not been authenticated, statusCode: ${statusCode}`);
1191
- break;
1192
- case 403:
1193
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
1194
- + `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
1195
- break;
1196
- case 404:
1197
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
1198
- + `statusCode: ${statusCode}`);
1199
- break;
1200
- case 406:
1201
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
1202
- + `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
1203
- break;
1204
- case 415:
1205
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
1206
- + `header that is not supported by the server, statusCode: ${statusCode}`);
1207
- break;
1208
- case 422:
1209
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
1210
- + `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
1211
- break;
1212
- case 429:
1213
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
1214
- + `requests allowed for a given time window, statusCode: ${statusCode}`);
1215
- break;
1216
- case 500:
1217
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
1218
- + `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
1219
- break;
1220
- default:
1221
- this.infoLog(
1222
- `${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
1223
- `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`,
1224
- );
924
+ set_maxLux = 6001;
1225
925
  }
926
+ return set_maxLux;
1226
927
  }
1227
928
 
1228
929
  async offlineOff(): Promise<void> {
1229
930
  if (this.device.offline) {
1230
- await this.deviceContext();
1231
- await this.updateHomeKitCharacteristics();
931
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
932
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
933
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
1232
934
  }
1233
935
  }
1234
936
 
1235
937
  async apiError(e: any): Promise<void> {
1236
- this.windowCoveringService.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
1237
- this.windowCoveringService.updateCharacteristic(this.hap.Characteristic.PositionState, e);
1238
- this.windowCoveringService.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
938
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
939
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
940
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
1239
941
  if (!this.device.curtain?.hide_lightsensor) {
1240
- this.lightSensorService?.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
942
+ this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
1241
943
  }
1242
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
1243
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
944
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
945
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
1244
946
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
1245
947
  }
1246
-
1247
- async deviceContext() {
1248
- if (this.accessory.context.CurrentPosition === undefined) {
1249
- this.CurrentPosition = 0;
1250
- } else {
1251
- this.CurrentPosition = this.accessory.context.CurrentPosition;
1252
- }
1253
-
1254
- if (this.accessory.context.TargetPosition === undefined) {
1255
- this.TargetPosition = 0;
1256
- } else {
1257
- this.TargetPosition = this.accessory.context.TargetPosition;
1258
- }
1259
-
1260
- if (this.accessory.context.PositionState === undefined) {
1261
- this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
1262
- } else {
1263
- this.PositionState = this.accessory.context.PositionState;
1264
- }
1265
-
1266
- if (!this.device.curtain?.hide_lightsensor) {
1267
- if (this.accessory.context.CurrentAmbientLightLevel !== undefined) {
1268
- this.CurrentAmbientLightLevel = this.accessory.context.CurrentAmbientLightLevel;
1269
- }
1270
- }
1271
-
1272
- if (this.BLE) {
1273
- if (this.accessory.context.BatteryLevel === undefined) {
1274
- this.BatteryLevel = 100;
1275
- } else {
1276
- this.BatteryLevel = this.accessory.context.BatteryLevel;
1277
- }
1278
- if (this.accessory.context.StatusLowBattery === undefined) {
1279
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
1280
- } else {
1281
- this.StatusLowBattery = this.accessory.context.StatusLowBattery;
1282
- }
1283
- }
1284
-
1285
- if (this.device.history === true) {
1286
- // initialize when this accessory is newly created.
1287
- this.accessory.context.lastActivation = this.accessory.context.lastActivation ?? 0;
1288
- } else {
1289
- // removes cached values if history is turned off
1290
- delete this.accessory.context.lastActivation;
1291
- }
1292
- if (this.FirmwareRevision === undefined) {
1293
- this.FirmwareRevision = this.platform.version;
1294
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
1295
- }
1296
- }
1297
-
1298
- async refreshRate(device: device & devicesConfig): Promise<void> {
1299
- // refreshRate
1300
- if (device.refreshRate) {
1301
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
1302
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
1303
- } else if (this.platform.config.options!.refreshRate) {
1304
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
1305
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
1306
- }
1307
- // updateRate
1308
- if (device?.curtain?.updateRate) {
1309
- this.updateRate = device?.curtain?.updateRate;
1310
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Curtain updateRate: ${this.updateRate}`);
1311
- } else {
1312
- this.updateRate = 7;
1313
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default Curtain updateRate: ${this.updateRate}`);
1314
- }
1315
- }
1316
-
1317
- async deviceRetry(device: device & devicesConfig): Promise<void> {
1318
- if (!device.maxRetries) {
1319
- this.maxRetries = 5; // Maximum number of retries
1320
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
1321
- } else {
1322
- this.maxRetries = device.maxRetries;
1323
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
1324
- }
1325
- if (!device.delayBetweenRetries) {
1326
- this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
1327
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
1328
- } else {
1329
- this.delayBetweenRetries = device.delayBetweenRetries * 1000;
1330
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
1331
- }
1332
- }
1333
-
1334
- async deviceConfig(device: device & devicesConfig): Promise<void> {
1335
- let config = {};
1336
- if (device.curtain) {
1337
- config = device.curtain;
1338
- }
1339
- if (device.connectionType !== undefined) {
1340
- config['connectionType'] = device.connectionType;
1341
- }
1342
- if (device.external !== undefined) {
1343
- config['external'] = device.external;
1344
- }
1345
- if (device.mqttURL !== undefined) {
1346
- config['mqttURL'] = device.mqttURL;
1347
- }
1348
- if (device.logging !== undefined) {
1349
- config['logging'] = device.logging;
1350
- }
1351
- if (device.refreshRate !== undefined) {
1352
- config['refreshRate'] = device.refreshRate;
1353
- }
1354
- if (device.scanDuration !== undefined) {
1355
- config['scanDuration'] = device.scanDuration;
1356
- }
1357
- if (device.maxRetry !== undefined) {
1358
- config['maxRetry'] = device.maxRetry;
1359
- }
1360
- if (device.webhook !== undefined) {
1361
- config['webhook'] = device.webhook;
1362
- }
1363
- if (Object.entries(config).length !== 0) {
1364
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
1365
- }
1366
- }
1367
-
1368
- async deviceLogs(device: device & devicesConfig): Promise<void> {
1369
- if (this.platform.debugMode) {
1370
- this.deviceLogging = this.accessory.context.logging = 'debugMode';
1371
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
1372
- } else if (device.logging) {
1373
- this.deviceLogging = this.accessory.context.logging = device.logging;
1374
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
1375
- } else if (this.platform.config.options?.logging) {
1376
- this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
1377
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
1378
- } else {
1379
- this.deviceLogging = this.accessory.context.logging = 'standard';
1380
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
1381
- }
1382
- }
1383
-
1384
- /**
1385
- * Logging for Device
1386
- */
1387
- successLog(...log: any[]): void {
1388
- if (this.enablingDeviceLogging()) {
1389
- this.platform.log.success(String(...log));
1390
- }
1391
- }
1392
-
1393
- infoLog(...log: any[]): void {
1394
- if (this.enablingDeviceLogging()) {
1395
- this.platform.log.info(String(...log));
1396
- }
1397
- }
1398
-
1399
- warnLog(...log: any[]): void {
1400
- if (this.enablingDeviceLogging()) {
1401
- this.platform.log.warn(String(...log));
1402
- }
1403
- }
1404
-
1405
- debugWarnLog(...log: any[]): void {
1406
- if (this.enablingDeviceLogging()) {
1407
- if (this.deviceLogging?.includes('debug')) {
1408
- this.platform.log.warn('[DEBUG]', String(...log));
1409
- }
1410
- }
1411
- }
1412
-
1413
- errorLog(...log: any[]): void {
1414
- if (this.enablingDeviceLogging()) {
1415
- this.platform.log.error(String(...log));
1416
- }
1417
- }
1418
-
1419
- debugErrorLog(...log: any[]): void {
1420
- if (this.enablingDeviceLogging()) {
1421
- if (this.deviceLogging?.includes('debug')) {
1422
- this.platform.log.error('[DEBUG]', String(...log));
1423
- }
1424
- }
1425
- }
1426
-
1427
- debugLog(...log: any[]): void {
1428
- if (this.enablingDeviceLogging()) {
1429
- if (this.deviceLogging === 'debug') {
1430
- this.platform.log.info('[DEBUG]', String(...log));
1431
- } else {
1432
- this.platform.log.debug(String(...log));
1433
- }
1434
- }
1435
- }
1436
-
1437
- enablingDeviceLogging(): boolean {
1438
- return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
1439
- }
1440
948
  }