@switchbot/homebridge-switchbot 3.5.0-beta.7 → 3.5.0-beta.70

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