@switchbot/homebridge-switchbot 3.7.1-beta.2 → 3.7.1-beta.21

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 (199) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +14 -0
  3. package/assets/security-privacy-bluetooth.png +0 -0
  4. package/config.schema.json +74 -2
  5. package/dist/device/blindtilt.d.ts +21 -9
  6. package/dist/device/blindtilt.d.ts.map +1 -1
  7. package/dist/device/blindtilt.js +167 -96
  8. package/dist/device/blindtilt.js.map +1 -1
  9. package/dist/device/bot-old.d.ts +132 -0
  10. package/dist/device/bot-old.d.ts.map +1 -0
  11. package/dist/device/bot-old.js +1482 -0
  12. package/dist/device/bot-old.js.map +1 -0
  13. package/dist/device/bot.d.ts +10 -9
  14. package/dist/device/bot.d.ts.map +1 -1
  15. package/dist/device/bot.js +186 -187
  16. package/dist/device/bot.js.map +1 -1
  17. package/dist/device/ceilinglight.d.ts +14 -13
  18. package/dist/device/ceilinglight.d.ts.map +1 -1
  19. package/dist/device/ceilinglight.js +87 -97
  20. package/dist/device/ceilinglight.js.map +1 -1
  21. package/dist/device/colorbulb.d.ts +13 -12
  22. package/dist/device/colorbulb.d.ts.map +1 -1
  23. package/dist/device/colorbulb.js +92 -105
  24. package/dist/device/colorbulb.js.map +1 -1
  25. package/dist/device/contact.d.ts +6 -5
  26. package/dist/device/contact.d.ts.map +1 -1
  27. package/dist/device/contact.js +71 -68
  28. package/dist/device/contact.js.map +1 -1
  29. package/dist/device/curtain.d.ts +17 -5
  30. package/dist/device/curtain.d.ts.map +1 -1
  31. package/dist/device/curtain.js +184 -118
  32. package/dist/device/curtain.js.map +1 -1
  33. package/dist/device/device.d.ts +18 -18
  34. package/dist/device/device.d.ts.map +1 -1
  35. package/dist/device/device.js +33 -36
  36. package/dist/device/device.js.map +1 -1
  37. package/dist/device/fan.d.ts +9 -8
  38. package/dist/device/fan.d.ts.map +1 -1
  39. package/dist/device/fan.js +94 -101
  40. package/dist/device/fan.js.map +1 -1
  41. package/dist/device/hub.d.ts +6 -5
  42. package/dist/device/hub.d.ts.map +1 -1
  43. package/dist/device/hub.js +69 -65
  44. package/dist/device/hub.js.map +1 -1
  45. package/dist/device/humidifier.d.ts +6 -5
  46. package/dist/device/humidifier.d.ts.map +1 -1
  47. package/dist/device/humidifier.js +89 -104
  48. package/dist/device/humidifier.js.map +1 -1
  49. package/dist/device/iosensor.d.ts +6 -5
  50. package/dist/device/iosensor.d.ts.map +1 -1
  51. package/dist/device/iosensor.js +72 -66
  52. package/dist/device/iosensor.js.map +1 -1
  53. package/dist/device/lightstrip.d.ts +7 -6
  54. package/dist/device/lightstrip.d.ts.map +1 -1
  55. package/dist/device/lightstrip.js +85 -99
  56. package/dist/device/lightstrip.js.map +1 -1
  57. package/dist/device/lock.d.ts +10 -9
  58. package/dist/device/lock.d.ts.map +1 -1
  59. package/dist/device/lock.js +89 -79
  60. package/dist/device/lock.js.map +1 -1
  61. package/dist/device/meter.d.ts +6 -5
  62. package/dist/device/meter.d.ts.map +1 -1
  63. package/dist/device/meter.js +72 -65
  64. package/dist/device/meter.js.map +1 -1
  65. package/dist/device/meterplus.d.ts +6 -5
  66. package/dist/device/meterplus.d.ts.map +1 -1
  67. package/dist/device/meterplus.js +72 -64
  68. package/dist/device/meterplus.js.map +1 -1
  69. package/dist/device/motion.d.ts +6 -5
  70. package/dist/device/motion.d.ts.map +1 -1
  71. package/dist/device/motion.js +65 -58
  72. package/dist/device/motion.js.map +1 -1
  73. package/dist/device/plug.d.ts +13 -12
  74. package/dist/device/plug.d.ts.map +1 -1
  75. package/dist/device/plug.js +68 -52
  76. package/dist/device/plug.js.map +1 -1
  77. package/dist/device/robotvacuumcleaner.d.ts +12 -11
  78. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  79. package/dist/device/robotvacuumcleaner.js +93 -82
  80. package/dist/device/robotvacuumcleaner.js.map +1 -1
  81. package/dist/device/waterdetector.d.ts +6 -5
  82. package/dist/device/waterdetector.d.ts.map +1 -1
  83. package/dist/device/waterdetector.js +73 -63
  84. package/dist/device/waterdetector.js.map +1 -1
  85. package/dist/homebridge-ui/server.js +2 -2
  86. package/dist/homebridge-ui/server.js.map +1 -1
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +0 -4
  89. package/dist/index.js.map +1 -1
  90. package/dist/irdevice/airconditioner.d.ts +8 -8
  91. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  92. package/dist/irdevice/airconditioner.js +61 -105
  93. package/dist/irdevice/airconditioner.js.map +1 -1
  94. package/dist/irdevice/airpurifier.d.ts +10 -10
  95. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  96. package/dist/irdevice/airpurifier.js +22 -42
  97. package/dist/irdevice/airpurifier.js.map +1 -1
  98. package/dist/irdevice/camera.d.ts +9 -9
  99. package/dist/irdevice/camera.d.ts.map +1 -1
  100. package/dist/irdevice/camera.js +15 -25
  101. package/dist/irdevice/camera.js.map +1 -1
  102. package/dist/irdevice/fan.d.ts +8 -8
  103. package/dist/irdevice/fan.d.ts.map +1 -1
  104. package/dist/irdevice/fan.js +21 -40
  105. package/dist/irdevice/fan.js.map +1 -1
  106. package/dist/irdevice/irdevice.d.ts +11 -11
  107. package/dist/irdevice/irdevice.d.ts.map +1 -1
  108. package/dist/irdevice/irdevice.js +14 -22
  109. package/dist/irdevice/irdevice.js.map +1 -1
  110. package/dist/irdevice/light.d.ts +9 -9
  111. package/dist/irdevice/light.d.ts.map +1 -1
  112. package/dist/irdevice/light.js +24 -47
  113. package/dist/irdevice/light.js.map +1 -1
  114. package/dist/irdevice/other.d.ts +9 -9
  115. package/dist/irdevice/other.d.ts.map +1 -1
  116. package/dist/irdevice/other.js +40 -83
  117. package/dist/irdevice/other.js.map +1 -1
  118. package/dist/irdevice/tv.d.ts +9 -9
  119. package/dist/irdevice/tv.d.ts.map +1 -1
  120. package/dist/irdevice/tv.js +29 -54
  121. package/dist/irdevice/tv.js.map +1 -1
  122. package/dist/irdevice/vacuumcleaner.d.ts +5 -5
  123. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  124. package/dist/irdevice/vacuumcleaner.js +11 -21
  125. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  126. package/dist/irdevice/waterheater.d.ts +5 -5
  127. package/dist/irdevice/waterheater.d.ts.map +1 -1
  128. package/dist/irdevice/waterheater.js +11 -22
  129. package/dist/irdevice/waterheater.js.map +1 -1
  130. package/dist/platform.d.ts +24 -23
  131. package/dist/platform.d.ts.map +1 -1
  132. package/dist/platform.js +509 -723
  133. package/dist/platform.js.map +1 -1
  134. package/dist/settings.d.ts +5 -2
  135. package/dist/settings.d.ts.map +1 -1
  136. package/dist/settings.js.map +1 -1
  137. package/dist/types/bledevicestatus.d.ts +9 -9
  138. package/dist/types/bledevicestatus.d.ts.map +1 -1
  139. package/dist/types/devicelist.d.ts +6 -6
  140. package/dist/types/devicelist.d.ts.map +1 -1
  141. package/dist/types/deviceresponse.d.ts +4 -4
  142. package/dist/types/deviceresponse.d.ts.map +1 -1
  143. package/dist/types/devicestatus.d.ts +2 -2
  144. package/dist/types/devicestatus.d.ts.map +1 -1
  145. package/dist/types/devicewebhookstatus.d.ts +5 -5
  146. package/dist/types/devicewebhookstatus.d.ts.map +1 -1
  147. package/dist/types/irdevicelist.d.ts +4 -4
  148. package/dist/types/irdevicelist.d.ts.map +1 -1
  149. package/dist/types/pushbody.d.ts +2 -2
  150. package/dist/types/pushbody.d.ts.map +1 -1
  151. package/dist/utils.d.ts +4 -4
  152. package/dist/utils.d.ts.map +1 -1
  153. package/dist/utils.js +9 -13
  154. package/dist/utils.js.map +1 -1
  155. package/eslint.config.js +48 -93
  156. package/package.json +64 -57
  157. package/src/device/blindtilt.ts +537 -456
  158. package/src/device/bot-old.ts +1540 -0
  159. package/src/device/bot.ts +732 -725
  160. package/src/device/ceilinglight.ts +359 -368
  161. package/src/device/colorbulb.ts +441 -453
  162. package/src/device/contact.ts +229 -226
  163. package/src/device/curtain.ts +526 -444
  164. package/src/device/device.ts +206 -208
  165. package/src/device/fan.ts +336 -345
  166. package/src/device/hub.ts +213 -214
  167. package/src/device/humidifier.ts +326 -347
  168. package/src/device/iosensor.ts +211 -209
  169. package/src/device/lightstrip.ts +391 -404
  170. package/src/device/lock.ts +292 -282
  171. package/src/device/meter.ts +212 -210
  172. package/src/device/meterplus.ts +212 -209
  173. package/src/device/motion.ts +198 -190
  174. package/src/device/plug.ts +203 -182
  175. package/src/device/robotvacuumcleaner.ts +280 -269
  176. package/src/device/waterdetector.ts +198 -189
  177. package/src/homebridge-ui/server.ts +16 -15
  178. package/src/index.ts +5 -6
  179. package/src/irdevice/airconditioner.ts +277 -326
  180. package/src/irdevice/airpurifier.ts +124 -143
  181. package/src/irdevice/camera.ts +58 -64
  182. package/src/irdevice/fan.ts +106 -123
  183. package/src/irdevice/irdevice.ts +116 -119
  184. package/src/irdevice/light.ts +119 -143
  185. package/src/irdevice/other.ts +417 -461
  186. package/src/irdevice/tv.ts +155 -177
  187. package/src/irdevice/vacuumcleaner.ts +54 -60
  188. package/src/irdevice/waterheater.ts +56 -63
  189. package/src/platform.ts +1491 -1681
  190. package/src/settings.ts +172 -169
  191. package/src/types/bledevicestatus.ts +252 -256
  192. package/src/types/devicelist.ts +79 -79
  193. package/src/types/deviceresponse.ts +12 -13
  194. package/src/types/devicestatus.ts +124 -124
  195. package/src/types/devicewebhookstatus.ts +126 -131
  196. package/src/types/irdevicelist.ts +10 -10
  197. package/src/types/pushbody.ts +5 -5
  198. package/src/utils.ts +64 -65
  199. package/tsconfig.json +10 -9
@@ -2,84 +2,103 @@
2
2
  *
3
3
  * blindtilt.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
- import { deviceBase } from './device.js';
6
- import { BlindTiltMappingMode } from '../utils.js';
7
- import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
8
- import { Subject, debounceTime, interval, skipWhile, take, tap } from 'rxjs';
5
+ import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
9
6
 
10
- import type { devicesConfig } from '../settings.js';
11
- import type { device } from '../types/devicelist.js';
12
- import type { SwitchBotPlatform } from '../platform.js';
13
- import type { blindTiltServiceData } from '../types/bledevicestatus.js';
14
- import type { blindTiltStatus } from '../types/devicestatus.js';
15
- import type { blindTiltWebhookContext } from '../types/devicewebhookstatus.js';
16
- import type { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
7
+ import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { devicesConfig } from '../settings.js'
9
+ import type { blindTiltServiceData } from '../types/bledevicestatus.js'
10
+ import type { device } from '../types/devicelist.js'
11
+ import type { blindTiltStatus } from '../types/devicestatus.js'
12
+ import type { blindTiltWebhookContext } from '../types/devicewebhookstatus.js'
17
13
 
14
+ /*
15
+ * For Testing Locally:
16
+ * import { SwitchBotBLEModel, SwitchBotBLEModelName } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
17
+ */
18
+ import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot'
19
+ import { debounceTime, interval, skipWhile, Subject, take, tap } from 'rxjs'
20
+
21
+ import { BlindTiltMappingMode } from '../utils.js'
22
+ import { deviceBase } from './device.js'
18
23
 
19
24
  export class BlindTilt extends deviceBase {
20
25
  // Services
21
26
  private WindowCovering: {
22
- Name: CharacteristicValue;
23
- Service: Service;
24
- PositionState: CharacteristicValue;
25
- TargetPosition: CharacteristicValue;
26
- CurrentPosition: CharacteristicValue;
27
- TargetHorizontalTiltAngle: CharacteristicValue;
28
- CurrentHorizontalTiltAngle: CharacteristicValue;
29
- };
27
+ Name: CharacteristicValue
28
+ Service: Service
29
+ PositionState: CharacteristicValue
30
+ TargetPosition: CharacteristicValue
31
+ CurrentPosition: CharacteristicValue
32
+ TargetHorizontalTiltAngle: CharacteristicValue
33
+ CurrentHorizontalTiltAngle: CharacteristicValue
34
+ }
30
35
 
31
36
  private Battery: {
32
- Name: CharacteristicValue;
33
- Service: Service;
34
- BatteryLevel: CharacteristicValue;
35
- StatusLowBattery: CharacteristicValue;
36
- ChargingState?: CharacteristicValue;
37
- };
37
+ Name: CharacteristicValue
38
+ Service: Service
39
+ BatteryLevel: CharacteristicValue
40
+ StatusLowBattery: CharacteristicValue
41
+ ChargingState?: CharacteristicValue
42
+ }
38
43
 
39
44
  private LightSensor?: {
40
- Name: CharacteristicValue;
41
- Service: Service;
42
- CurrentAmbientLightLevel?: CharacteristicValue;
43
- };
45
+ Name: CharacteristicValue
46
+ Service: Service
47
+ CurrentAmbientLightLevel?: CharacteristicValue
48
+ }
49
+
50
+ private OpenModeSwitch?: {
51
+ Name: CharacteristicValue
52
+ Service: Service
53
+ On: CharacteristicValue
54
+ }
55
+
56
+ private CloseModeSwitch?: {
57
+ Name: CharacteristicValue
58
+ Service: Service
59
+ On: CharacteristicValue
60
+ }
44
61
 
45
62
  // OpenAPI
46
- deviceStatus!: blindTiltStatus;
47
- mappingMode: BlindTiltMappingMode = BlindTiltMappingMode.OnlyUp;
63
+ deviceStatus!: blindTiltStatus
64
+ mappingMode: BlindTiltMappingMode = BlindTiltMappingMode.OnlyUp
48
65
 
49
- //Webhook
50
- webhookContext!: blindTiltWebhookContext;
66
+ // Webhook
67
+ webhookContext!: blindTiltWebhookContext
51
68
 
52
69
  // BLE
53
- serviceData!: blindTiltServiceData;
70
+ serviceData!: blindTiltServiceData
54
71
 
55
72
  // Target
56
- setNewTarget!: boolean;
57
- setNewTargetTimer!: NodeJS.Timeout;
73
+ setNewTarget!: boolean
74
+ setNewTargetTimer!: NodeJS.Timeout
58
75
 
59
76
  // Updates
60
- blindTiltUpdateInProgress;
61
- doBlindTiltUpdate: Subject<void>;
77
+ blindTiltMoving: boolean
78
+ blindTiltUpdateInProgress: boolean
79
+ doBlindTiltUpdate: Subject<void>
62
80
 
63
81
  constructor(
64
82
  readonly platform: SwitchBotPlatform,
65
83
  accessory: PlatformAccessory,
66
84
  device: device & devicesConfig,
67
85
  ) {
68
- super(platform, accessory, device);
86
+ super(platform, accessory, device)
69
87
  // Set category
70
- accessory.category = this.hap.Categories.WINDOW_COVERING;
88
+ accessory.category = this.hap.Categories.WINDOW_COVERING
71
89
 
72
90
  // default placeholders
73
- this.mappingMode = (device.blindTilt?.mode as BlindTiltMappingMode) ?? BlindTiltMappingMode.OnlyUp;
74
- this.debugLog(`Mapping mode: ${this.mappingMode}`);
91
+ this.mappingMode = (device.blindTilt?.mode as BlindTiltMappingMode) ?? BlindTiltMappingMode.OnlyUp
92
+ this.debugLog(`Mapping mode: ${this.mappingMode}`)
75
93
 
76
94
  // this is subject we use to track when we need to POST changes to the SwitchBot API
77
- this.doBlindTiltUpdate = new Subject();
78
- this.blindTiltUpdateInProgress = false;
79
- this.setNewTarget = false;
95
+ this.doBlindTiltUpdate = new Subject()
96
+ this.blindTiltMoving = false
97
+ this.blindTiltUpdateInProgress = false
98
+ this.setNewTarget = false
80
99
 
81
100
  // Initialize WindowCovering Service
82
- accessory.context.WindowCovering = accessory.context.WindowCovering ?? {};
101
+ accessory.context.WindowCovering = accessory.context.WindowCovering ?? {}
83
102
  this.WindowCovering = {
84
103
  Name: accessory.displayName,
85
104
  Service: accessory.getService(this.hap.Service.WindowCovering) ?? accessory.addService(this.hap.Service.WindowCovering) as Service,
@@ -88,291 +107,336 @@ export class BlindTilt extends deviceBase {
88
107
  CurrentPosition: accessory.context.CurrentPosition ?? 100,
89
108
  TargetHorizontalTiltAngle: accessory.context.TargetHorizontalTiltAngle ?? 90,
90
109
  CurrentHorizontalTiltAngle: accessory.context.CurrentHorizontalTiltAngle ?? 90,
91
- };
92
- accessory.context.WindowCovering = this.WindowCovering as object;
110
+ }
111
+ accessory.context.WindowCovering = this.WindowCovering as object
93
112
 
94
113
  // Initialize WindowCovering Characteristics
95
- this.WindowCovering.Service
96
- .setCharacteristic(this.hap.Characteristic.Name, this.WindowCovering.Name)
97
- .getCharacteristic(this.hap.Characteristic.TargetPosition)
98
- .setProps({
99
- minStep: device.blindTilt?.set_minStep ?? 1,
100
- minValue: 0,
101
- maxValue: 100,
102
- validValueRanges: [0, 100],
103
- })
104
- .onGet(() => {
105
- return this.WindowCovering.TargetPosition;
106
- })
107
- .onSet(this.TargetPositionSet.bind(this));
114
+ this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.Name, this.WindowCovering.Name).getCharacteristic(this.hap.Characteristic.TargetPosition).setProps({
115
+ minStep: device.blindTilt?.set_minStep ?? 1,
116
+ minValue: 0,
117
+ maxValue: 100,
118
+ validValueRanges: [0, 100],
119
+ }).onGet(() => {
120
+ return this.WindowCovering.TargetPosition
121
+ }).onSet(this.TargetPositionSet.bind(this))
108
122
 
109
123
  // Initialize WindowCovering CurrentPosition Characteristic
110
- this.WindowCovering.Service
111
- .getCharacteristic(this.hap.Characteristic.CurrentPosition)
112
- .setProps({
113
- minStep: device.blindTilt?.set_minStep ?? 1,
114
- minValue: 0,
115
- maxValue: 100,
116
- validValueRanges: [0, 100],
117
- }).onGet(() => {
118
- return this.WindowCovering.CurrentPosition ?? 0;
119
- });
124
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.CurrentPosition).setProps({
125
+ minStep: device.blindTilt?.set_minStep ?? 1,
126
+ minValue: 0,
127
+ maxValue: 100,
128
+ validValueRanges: [0, 100],
129
+ }).onGet(() => {
130
+ return this.WindowCovering.CurrentPosition ?? 0
131
+ })
120
132
 
121
133
  // Initialize WindowCovering TargetHorizontalTiltAngle Characteristic
122
- this.WindowCovering.Service
123
- .getCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle)
124
- .setProps({
125
- minStep: 180,
126
- minValue: -90,
127
- maxValue: 90,
128
- validValues: [-90, 90],
129
- })
130
- .onGet(() => {
131
- return this.WindowCovering.TargetHorizontalTiltAngle;
132
- })
133
- .onSet(this.TargetHorizontalTiltAngleSet.bind(this));
134
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle).setProps({
135
+ minStep: 180,
136
+ minValue: -90,
137
+ maxValue: 90,
138
+ validValues: [-90, 90],
139
+ }).onGet(() => {
140
+ return this.WindowCovering.TargetHorizontalTiltAngle
141
+ }).onSet(this.TargetHorizontalTiltAngleSet.bind(this))
134
142
 
135
143
  // Initialize WindowCovering CurrentHorizontalTiltAngle Characteristic
136
- this.WindowCovering.Service
137
- .getCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle)
138
- .setProps({
139
- minStep: 180,
140
- minValue: -90,
141
- maxValue: 90,
142
- validValues: [-90, 90],
143
- }).onGet(() => {
144
- return this.WindowCovering.CurrentHorizontalTiltAngle ?? 0;
145
- });
144
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle).setProps({
145
+ minStep: 180,
146
+ minValue: -90,
147
+ maxValue: 90,
148
+ validValues: [-90, 90],
149
+ }).onGet(() => {
150
+ return this.WindowCovering.CurrentHorizontalTiltAngle ?? 0
151
+ })
146
152
 
147
153
  // Initialize Battery Service
148
- accessory.context.Battery = accessory.context.Battery ?? {};
154
+ accessory.context.Battery = accessory.context.Battery ?? {}
149
155
  this.Battery = {
150
156
  Name: `${accessory.displayName} Battery`,
151
157
  Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
152
158
  BatteryLevel: accessory.context.BatteryLevel ?? 100,
153
159
  StatusLowBattery: this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
154
160
  ChargingState: accessory.context.ChargingState ?? this.hap.Characteristic.ChargingState.NOT_CHARGING,
155
- };
156
- accessory.context.Battery = this.Battery as object;
161
+ }
162
+ accessory.context.Battery = this.Battery as object
157
163
 
158
164
  // Initialize Battery Name Characteristic
159
- this.Battery.Service
160
- .setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
161
- .setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
165
+ this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name).setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE)
162
166
 
163
167
  // Initialize LightSensor Service
164
168
  if (device.blindTilt?.hide_lightsensor) {
165
169
  if (this.LightSensor?.Service) {
166
- this.debugLog('Removing Light Sensor Service');
167
- this.LightSensor.Service = accessory.getService(this.hap.Service.LightSensor) as Service;
168
- accessory.removeService(this.LightSensor.Service);
169
- accessory.context.LightSensor = {};
170
+ this.debugLog('Removing Light Sensor Service')
171
+ this.LightSensor.Service = accessory.getService(this.hap.Service.LightSensor) as Service
172
+ accessory.removeService(this.LightSensor.Service)
173
+ accessory.context.LightSensor = {}
170
174
  } else {
171
- this.debugLog('Light Sensor Service is already removed');
175
+ this.debugLog('Light Sensor Service is already removed')
172
176
  }
173
177
  } else {
174
- accessory.context.LightSensor = accessory.context.LightSensor ?? {};
178
+ accessory.context.LightSensor = accessory.context.LightSensor ?? {}
175
179
  this.LightSensor = {
176
180
  Name: `${accessory.displayName} Light Sensor`,
177
181
  Service: accessory.getService(this.hap.Service.LightSensor) ?? accessory.addService(this.hap.Service.LightSensor) as Service,
178
182
  CurrentAmbientLightLevel: accessory.context.CurrentAmbientLightLevel ?? 0.0001,
179
- };
180
- accessory.context.LightSensor = this.LightSensor as object;
183
+ }
184
+ accessory.context.LightSensor = this.LightSensor as object
181
185
 
182
186
  // Initialize LightSensor Characteristics
183
- this.LightSensor.Service
184
- .setCharacteristic(this.hap.Characteristic.Name, this.LightSensor.Name)
185
- .setCharacteristic(this.hap.Characteristic.StatusActive, true)
186
- .getCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel)
187
- .onGet(() => {
188
- return this.LightSensor?.CurrentAmbientLightLevel ?? 0.0001;
189
- });
187
+ this.LightSensor.Service.setCharacteristic(this.hap.Characteristic.Name, this.LightSensor.Name).setCharacteristic(this.hap.Characteristic.StatusActive, true).getCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel).onGet(() => {
188
+ return this.LightSensor?.CurrentAmbientLightLevel ?? 0.0001
189
+ })
190
+ }
191
+
192
+ // Initialize Open Mode Switch Service
193
+ if (!device.blindTilt?.silentModeSwitch) {
194
+ if (this.OpenModeSwitch?.Service) {
195
+ this.debugLog('Removing Open Mode Switch Service')
196
+ this.OpenModeSwitch.Service = this.accessory.getService(this.hap.Service.Switch) as Service
197
+ accessory.removeService(this.OpenModeSwitch.Service)
198
+ accessory.context.OpenModeSwitch = {}
199
+ }
200
+ } else {
201
+ accessory.context.OpenModeSwitch = accessory.context.OpenModeSwitch ?? {}
202
+ this.OpenModeSwitch = {
203
+ Name: `${accessory.displayName} Silent Open Mode`,
204
+ Service: accessory.getService(this.hap.Service.Switch) ?? accessory.addService(this.hap.Service.Switch) as Service,
205
+ On: accessory.context.OpenModeSwitch.On ?? false,
206
+ }
207
+ accessory.context.OpenModeSwitch = this.OpenModeSwitch as object
208
+
209
+ // Initialize Open Mode Switch Service
210
+ this.OpenModeSwitch.Service.setCharacteristic(this.hap.Characteristic.Name, this.OpenModeSwitch.Name).getCharacteristic(this.hap.Characteristic.On).onGet(() => {
211
+ return this.OpenModeSwitch?.On ?? false
212
+ })
213
+
214
+ this.OpenModeSwitch.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OpenModeSwitchSet.bind(this))
215
+ }
216
+
217
+ // Initialize Close Mode Switch Service
218
+ if (!device.blindTilt?.silentModeSwitch) {
219
+ if (this.CloseModeSwitch?.Service) {
220
+ this.debugLog('Removing Close Mode Switch Service')
221
+ this.CloseModeSwitch.Service = this.accessory.getService(this.hap.Service.Switch) as Service
222
+ accessory.removeService(this.CloseModeSwitch.Service)
223
+ accessory.context.CloseModeSwitch = {}
224
+ }
225
+ } else {
226
+ accessory.context.CloseModeSwitch = accessory.context.CloseModeSwitch ?? {}
227
+ this.CloseModeSwitch = {
228
+ Name: `${accessory.displayName} Silent Close Mode`,
229
+ Service: accessory.getService(this.hap.Service.Switch) ?? accessory.addService(this.hap.Service.Switch) as Service,
230
+ On: accessory.context.CloseModeSwitch.On ?? false,
231
+ }
232
+ accessory.context.CloseModeSwitch = this.CloseModeSwitch as object
233
+
234
+ // Initialize Close Mode Switch Service
235
+ this.CloseModeSwitch.Service.setCharacteristic(this.hap.Characteristic.Name, this.CloseModeSwitch.Name).getCharacteristic(this.hap.Characteristic.On).onGet(() => {
236
+ return this.CloseModeSwitch?.On ?? false
237
+ })
238
+
239
+ this.CloseModeSwitch.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.CloseModeSwitchSet.bind(this))
190
240
  }
191
241
 
192
242
  // Retrieve initial values and updateHomekit
193
- this.debugLog('Retrieve initial values and update Homekit');
194
- this.refreshStatus();
243
+ try {
244
+ this.debugLog('Retrieve initial values and update Homekit')
245
+ this.refreshStatus()
246
+ } catch (e: any) {
247
+ this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e}`)
248
+ }
249
+
250
+ // regisiter webhook event handler if enabled
251
+ try {
252
+ this.debugLog('Registering Webhook Event Handler')
253
+ this.registerWebhook()
254
+ } catch (e: any) {
255
+ this.errorLog(`failed to registerWebhook, Error: ${e}`)
256
+ }
195
257
 
196
- //regisiter webhook event handler
197
- this.debugLog('Registering Webhook Event Handler');
198
- this.registerWebhook();
258
+ // regisiter platform BLE event handler if enabled
259
+ try {
260
+ this.debugLog('Registering Platform BLE Event Handler')
261
+ this.registerPlatformBLE()
262
+ } catch (e: any) {
263
+ this.errorLog(`failed to registerPlatformBLE, Error: ${e}`)
264
+ }
199
265
 
200
266
  // Start an update interval
201
267
  interval(this.deviceRefreshRate * 1000)
202
268
  .pipe(skipWhile(() => this.blindTiltUpdateInProgress))
203
269
  .subscribe(async () => {
204
- await this.refreshStatus();
205
- });
270
+ await this.refreshStatus()
271
+ })
206
272
 
207
273
  // update slide progress
208
274
  interval(this.deviceUpdateRate * 1000)
275
+ .pipe(skipWhile(() => !this.blindTiltMoving))
209
276
  .subscribe(async () => {
210
277
  if (this.WindowCovering.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
211
- return;
278
+ return
212
279
  }
213
- this.debugLog(`Refresh Status When Moving, PositionState: ${this.WindowCovering.PositionState}`);
214
- await this.refreshStatus();
215
- });
280
+ this.debugLog(`Refresh Status When Moving, PositionState: ${this.WindowCovering.PositionState}`)
281
+ await this.refreshStatus()
282
+ })
216
283
 
217
284
  // Watch for BlindTilt change events
218
285
  // We put in a debounce of 100ms so we don't make duplicate calls
219
286
  this.doBlindTiltUpdate
220
287
  .pipe(
221
288
  tap(() => {
222
- this.blindTiltUpdateInProgress = true;
289
+ this.blindTiltUpdateInProgress = true
223
290
  }),
224
291
  debounceTime(this.devicePushRate * 1000),
225
292
  )
226
293
  .subscribe(async () => {
227
294
  try {
228
- await this.pushChanges();
295
+ await this.pushChanges()
229
296
  } catch (e: any) {
230
- await this.apiError(e);
231
- await this.errorLog(`failed pushChanges with ${device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
297
+ await this.apiError(e)
298
+ await this.errorLog(`failed pushChanges with ${device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
232
299
  }
233
- this.blindTiltUpdateInProgress = false;
234
- });
300
+ this.blindTiltUpdateInProgress = false
301
+ })
235
302
  }
236
303
 
237
304
  /**
238
305
  * Parse the device status from the SwitchBotBLE API
239
306
  */
240
307
  async BLEparseStatus(): Promise<void> {
241
- await this.debugLog('BLEparseStatus');
242
- await this.debugLog(`(direction, slidePosition, battery, version) = BLE:(${this.serviceData.tilt}, ${this.serviceData.tilt},`
243
- + ` ${this.serviceData.battery}, ${this.accessory.context.version}), current:(${this.WindowCovering.CurrentHorizontalTiltAngle},`
244
- + ` ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`);
308
+ await this.debugLog('BLEparseStatus')
309
+ await this.debugLog(`(direction, slidePosition, battery, version) = BLE:(${this.serviceData.tilt}, ${this.serviceData.tilt}, ${this.serviceData.battery}, ${this.accessory.context.version}), current:(${this.WindowCovering.CurrentHorizontalTiltAngle}, ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`)
245
310
 
246
311
  // CurrentPosition
247
- this.WindowCovering.CurrentPosition = 100 - Number(this.serviceData.tilt);
248
- await this.setMinMax();
249
- await this.debugLog(`CurrentPosition ${this.WindowCovering.CurrentPosition}`);
312
+ this.WindowCovering.CurrentPosition = 100 - Number(this.serviceData.tilt)
313
+ await this.setMinMax()
314
+ await this.debugLog(`CurrentPosition ${this.WindowCovering.CurrentPosition}`)
250
315
  if (this.setNewTarget) {
251
- await this.infoLog('Checking Status ...');
316
+ await this.infoLog('Checking Status ...')
252
317
  }
253
318
  if (this.setNewTarget && this.serviceData.inMotion) {
254
- await this.setMinMax();
319
+ this.blindTiltMoving = true
320
+ await this.setMinMax()
255
321
  if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
256
- await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
257
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
258
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
259
- await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`);
322
+ await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
323
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING
324
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
325
+ await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`)
260
326
  } else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
261
- await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
262
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
263
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
264
- await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`);
327
+ await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
328
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING
329
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
330
+ await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`)
265
331
  } else {
266
- await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
267
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
268
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
269
- await this.debugLog('Stopped, PositionState', this.WindowCovering.PositionState);
332
+ await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
333
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
334
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
335
+ await this.debugLog('Stopped, PositionState', this.WindowCovering.PositionState)
270
336
  }
271
337
  } else {
272
- await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
273
- this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
274
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
275
- await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
338
+ this.blindTiltMoving = false
339
+ await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
340
+ this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition
341
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
342
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`)
276
343
  }
277
- await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition},`
278
- + ` PositionState: ${this.WindowCovering.PositionState}`);
344
+ await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState}`)
279
345
 
280
346
  // CurrentAmbientLightLevel
281
347
  if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
282
- const set_minLux = this.device.blindTilt?.set_minLux ?? 1;
283
- const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001;
284
- const spaceBetweenLevels = 9;
285
-
348
+ const set_minLux = this.device.blindTilt?.set_minLux ?? 1
349
+ const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001
350
+ const spaceBetweenLevels = 9
286
351
 
287
- await this.getLightLevel(this.serviceData.lightLevel, set_minLux, set_maxLux, spaceBetweenLevels);
288
- await this.debugLog(`LightLevel: ${this.serviceData.lightLevel}, CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
352
+ await this.getLightLevel(this.serviceData.lightLevel, set_minLux, set_maxLux, spaceBetweenLevels)
353
+ await this.debugLog(`LightLevel: ${this.serviceData.lightLevel}, CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`)
289
354
  }
290
355
 
291
356
  // BatteryLevel
292
- this.Battery.BatteryLevel = this.serviceData.battery;
293
- await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
357
+ this.Battery.BatteryLevel = this.serviceData.battery
358
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
294
359
 
295
360
  // StatusLowBattery
296
361
  this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
297
- ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
298
- await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
362
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
363
+ : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
364
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
299
365
  };
300
366
 
301
367
  /**
302
368
  * Parse the device status from the SwitchBot OpenAPI
303
369
  */
304
370
  async openAPIparseStatus(): Promise<void> {
305
- await this.debugLog('openAPIparseStatus');
306
- await this.debugLog(`(direction, slidePosition, battery, version) = OpenAPI:(${this.deviceStatus.direction}, ${this.deviceStatus.slidePosition},`
307
- + ` ${this.deviceStatus.battery}, ${this.deviceStatus.version}), current:(${this.WindowCovering.CurrentHorizontalTiltAngle},`
308
- + ` ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`);
371
+ await this.debugLog('openAPIparseStatus')
372
+ await this.debugLog(`(direction, slidePosition, battery, version) = OpenAPI:(${this.deviceStatus.direction}, ${this.deviceStatus.slidePosition}, ${this.deviceStatus.battery}, ${this.deviceStatus.version}), current:(${this.WindowCovering.CurrentHorizontalTiltAngle}, ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`)
309
373
 
310
374
  // CurrentPosition
311
- await this.getCurrentPosttionDirection(this.deviceStatus.direction, this.deviceStatus.slidePosition);
375
+ await this.getCurrentPosttionDirection(this.deviceStatus.direction, this.deviceStatus.slidePosition)
312
376
 
313
377
  if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
314
- const set_minLux = this.device.blindTilt?.set_minLux ?? 1;
315
- const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001;
316
- const lightLevel = this.deviceStatus.lightLevel === 'bright' ? set_maxLux : set_minLux;
317
- this.LightSensor.CurrentAmbientLightLevel = await this.getLightLevel(lightLevel, set_minLux, set_maxLux, 2);
318
- await this.debugLog(`LightLevel: ${this.deviceStatus.lightLevel}, CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
378
+ const set_minLux = this.device.blindTilt?.set_minLux ?? 1
379
+ const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001
380
+ const lightLevel = this.deviceStatus.lightLevel === 'bright' ? set_maxLux : set_minLux
381
+ this.LightSensor.CurrentAmbientLightLevel = await this.getLightLevel(lightLevel, set_minLux, set_maxLux, 2)
382
+ await this.debugLog(`LightLevel: ${this.deviceStatus.lightLevel}, CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`)
319
383
  }
320
384
 
321
385
  // BatteryLevel
322
- this.Battery.BatteryLevel = this.deviceStatus.battery;
323
- await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
386
+ this.Battery.BatteryLevel = this.deviceStatus.battery
387
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
324
388
 
325
389
  // StatusLowBattery
326
390
  this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
327
- ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
328
- await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
391
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
392
+ : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
393
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
329
394
 
330
395
  // Firmware Version
331
- const version = this.deviceStatus.version.toString();
332
- await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`);
333
- let deviceVersion: string;
396
+ const version = this.deviceStatus.version.toString()
397
+ await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`)
398
+ let deviceVersion: string
334
399
  if (version?.includes('.') === false) {
335
- const replace = version?.replace(/^V|-.*$/g, '');
336
- const match = replace?.match(/.{1,1}/g);
337
- const blindTiltVersion = match?.join('.') ?? '0.0.0';
338
- deviceVersion = blindTiltVersion;
400
+ const replace = version?.replace(/^V|-.*$/g, '')
401
+ const match = replace?.match(/./g)
402
+ const blindTiltVersion = match?.join('.') ?? '0.0.0'
403
+ deviceVersion = blindTiltVersion
339
404
  } else {
340
- deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0';
405
+ deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0'
341
406
  }
342
407
  this.accessory
343
408
  .getService(this.hap.Service.AccessoryInformation)!
344
409
  .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
345
410
  .setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
346
411
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
347
- .updateValue(deviceVersion);
348
- this.accessory.context.version = deviceVersion;
349
- await this.debugLog(`version: ${this.accessory.context.version}`);
412
+ .updateValue(deviceVersion)
413
+ this.accessory.context.version = deviceVersion
414
+ await this.debugLog(`version: ${this.accessory.context.version}`)
350
415
  }
351
416
 
352
417
  async parseStatusWebhook(): Promise<void> {
353
- await this.debugLog('parseStatusWebhook');
354
- await this.debugLog(`(slidePosition, battery, version) = Webhook:(${this.webhookContext.direction}, ${this.webhookContext.slidePosition},`
355
- + ` ${this.webhookContext.battery}, ${this.webhookContext.version}, current:(${this.WindowCovering.CurrentHorizontalTiltAngle},`
356
- + ` ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`);
418
+ await this.debugLog('parseStatusWebhook')
419
+ await this.debugLog(`(slidePosition, battery, version) = Webhook:(${this.webhookContext.direction}, ${this.webhookContext.slidePosition}, ${this.webhookContext.battery}, ${this.webhookContext.version}, current:(${this.WindowCovering.CurrentHorizontalTiltAngle}, ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`)
357
420
  // CurrentPosition and CurrentHorizontalTiltAngle
358
- await this.getCurrentPosttionDirection(this.webhookContext.direction, this.webhookContext.slidePosition);
421
+ await this.getCurrentPosttionDirection(this.webhookContext.direction, this.webhookContext.slidePosition)
359
422
  // BatteryLevel
360
- this.Battery.BatteryLevel = this.webhookContext.battery;
361
- await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
423
+ this.Battery.BatteryLevel = this.webhookContext.battery
424
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
362
425
  // StatusLowBattery
363
426
  this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
364
- ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
365
- await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
427
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
428
+ : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
429
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
366
430
  // Firmware Version
367
- const deviceVersion = this.webhookContext.version.replace(/^V|-.*$/g, '') ?? '0.0.0';
431
+ const deviceVersion = this.webhookContext.version.replace(/^V|-.*$/g, '') ?? '0.0.0'
368
432
  this.accessory
369
433
  .getService(this.hap.Service.AccessoryInformation)!
370
434
  .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
371
435
  .setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
372
436
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
373
- .updateValue(deviceVersion);
374
- this.accessory.context.version = deviceVersion;
375
- await this.debugSuccessLog(`version: ${this.accessory.context.version}`);
437
+ .updateValue(deviceVersion)
438
+ this.accessory.context.version = deviceVersion
439
+ await this.debugSuccessLog(`version: ${this.accessory.context.version}`)
376
440
  }
377
441
 
378
442
  /**
@@ -380,123 +444,128 @@ export class BlindTilt extends deviceBase {
380
444
  */
381
445
  async refreshStatus(): Promise<void> {
382
446
  if (!this.device.enableCloudService && this.OpenAPI) {
383
- await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`);
384
- } else if (this.BLE || this.config.options?.BLE) {
385
- await this.BLERefreshStatus();
447
+ await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`)
448
+ } else if (this.BLE) {
449
+ await this.BLERefreshStatus()
386
450
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
387
- await this.openAPIRefreshStatus();
451
+ await this.openAPIRefreshStatus()
388
452
  } else {
389
- await this.offlineOff();
390
- await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`);
453
+ await this.offlineOff()
454
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`)
391
455
  }
392
456
  }
393
457
 
394
458
  async BLERefreshStatus(): Promise<void> {
459
+ await this.debugLog('BLERefreshStatus')
460
+ const switchbot = await this.switchbotBLE()
461
+ if (switchbot === undefined) {
462
+ await this.BLERefreshConnection(switchbot)
463
+ } else {
464
+ // Start to monitor advertisement packets
465
+ (async () => {
466
+ // Start to monitor advertisement packets
467
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as blindTiltServiceData
468
+ // Update HomeKit
469
+ if (serviceData.model === SwitchBotBLEModel.BlindTilt && serviceData.modelName === SwitchBotBLEModelName.BlindTilt) {
470
+ this.serviceData = serviceData
471
+ await this.BLEparseStatus()
472
+ await this.updateHomeKitCharacteristics()
473
+ } else {
474
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`)
475
+ await this.BLERefreshConnection(switchbot)
476
+ }
477
+ })()
478
+ }
479
+ }
480
+
481
+ async registerPlatformBLE(): Promise<void> {
482
+ await this.debugLog('registerPlatformBLE')
395
483
  if (this.config.options?.BLE) {
396
- await this.debugLog('is listening to Platform BLE.');
397
- this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
398
- await this.debugLog(`bleMac: ${this.device.bleMac}`);
484
+ await this.debugLog('is listening to Platform BLE.')
485
+ this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase()
486
+ await this.debugLog(`bleMac: ${this.device.bleMac}`)
399
487
  this.platform.bleEventHandler[this.device.bleMac] = async (context: blindTiltServiceData) => {
400
488
  try {
401
- await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
402
- this.serviceData = context;
403
- await this.BLEparseStatus();
404
- await this.updateHomeKitCharacteristics();
489
+ await this.debugLog(`received BLE: ${JSON.stringify(context)}`)
490
+ this.serviceData = context
491
+ await this.BLEparseStatus()
492
+ await this.updateHomeKitCharacteristics()
405
493
  } catch (e: any) {
406
- await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
494
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`)
407
495
  }
408
- };
409
- } else {
410
- await this.debugLog('is using Device BLE Scanning.');
411
- const switchbot = await this.switchbotBLE();
412
- if (switchbot === undefined) {
413
- await this.BLERefreshConnection(switchbot);
414
- } else {
415
- // Start to monitor advertisement packets
416
- (async () => {
417
- // Start to monitor advertisement packets
418
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as blindTiltServiceData;
419
- // Update HomeKit
420
- if (serviceData.model === SwitchBotBLEModel.BlindTilt && serviceData.modelName === SwitchBotBLEModelName.BlindTilt) {
421
- this.serviceData = serviceData;
422
- await this.BLEparseStatus();
423
- await this.updateHomeKitCharacteristics();
424
- } else {
425
- await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
426
- await this.BLERefreshConnection(switchbot);
427
- }
428
- })();
429
496
  }
497
+ } else {
498
+ await this.debugLog('is not listening to Platform BLE')
430
499
  }
431
500
  }
432
501
 
433
502
  async openAPIRefreshStatus(): Promise<void> {
434
- await this.debugLog('openAPIRefreshStatus');
503
+ await this.debugLog('openAPIRefreshStatus')
435
504
  try {
436
- const { body, statusCode } = await this.deviceRefreshStatus();
437
- const deviceStatus: any = await body.json();
438
- await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);;
505
+ const { body, statusCode } = await this.deviceRefreshStatus()
506
+ const deviceStatus: any = await body.json()
507
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
439
508
  if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
440
- await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
441
- this.deviceStatus = deviceStatus.body;
442
- await this.openAPIparseStatus();
443
- await this.updateHomeKitCharacteristics();
509
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
510
+ this.deviceStatus = deviceStatus.body
511
+ await this.openAPIparseStatus()
512
+ await this.updateHomeKitCharacteristics()
444
513
  } else {
445
- await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
446
- await this.debugWarnLog(statusCode, deviceStatus);
514
+ await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
515
+ await this.debugWarnLog(statusCode, deviceStatus)
447
516
  }
448
517
  } catch (e: any) {
449
- await this.apiError(e);
450
- await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
518
+ await this.apiError(e)
519
+ await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
451
520
  }
452
521
  }
453
522
 
454
523
  async registerWebhook(): Promise<void> {
455
524
  if (this.device.webhook) {
456
- await this.debugLog('is listening webhook.');
525
+ await this.debugLog('is listening webhook.')
457
526
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: blindTiltWebhookContext) => {
458
527
  try {
459
- await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
460
- this.webhookContext = context;
461
- await this.parseStatusWebhook();
462
- await this.updateHomeKitCharacteristics();
528
+ await this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
529
+ this.webhookContext = context
530
+ await this.parseStatusWebhook()
531
+ await this.updateHomeKitCharacteristics()
463
532
  } catch (e: any) {
464
- await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
533
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`)
465
534
  }
466
- };
535
+ }
467
536
  } else {
468
- await this.debugLog('is not listening webhook.');
537
+ await this.debugLog('is not listening webhook.')
469
538
  }
470
539
  }
471
540
 
472
541
  async pushChanges(): Promise<void> {
473
542
  if (!this.device.enableCloudService && this.OpenAPI) {
474
- await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`);
543
+ await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`)
475
544
  } else if (this.BLE) {
476
- await this.BLEpushChanges();
545
+ await this.BLEpushChanges()
477
546
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
478
- await this.openAPIpushChanges();
547
+ await this.openAPIpushChanges()
479
548
  } else {
480
- await this.offlineOff();
481
- await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`);
549
+ await this.offlineOff()
550
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`)
482
551
  }
483
552
  // Refresh the status from the API
484
553
  interval(15000)
485
554
  .pipe(skipWhile(() => this.blindTiltUpdateInProgress))
486
555
  .pipe(take(1))
487
556
  .subscribe(async () => {
488
- await this.refreshStatus();
489
- });
557
+ await this.refreshStatus()
558
+ })
490
559
  }
491
560
 
492
561
  async BLEpushChanges(): Promise<void> {
493
- await this.debugLog('BLEpushChanges');
562
+ await this.debugLog('BLEpushChanges')
494
563
  if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
495
- await this.debugLog(`BLEpushChanges On: ${this.WindowCovering.TargetPosition} OnCached: ${this.WindowCovering.CurrentPosition}`);
496
- const switchbot = await this.platform.connectBLE(this.accessory, this.device);
497
- await this.convertBLEAddress();
498
- const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
499
- await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`);
564
+ await this.debugLog(`BLEpushChanges On: ${this.WindowCovering.TargetPosition} OnCached: ${this.WindowCovering.CurrentPosition}`)
565
+ const switchbot = await this.platform.connectBLE(this.accessory, this.device)
566
+ await this.convertBLEAddress()
567
+ const { setPositionMode, Mode }: { setPositionMode: number, Mode: string } = await this.setPerformance()
568
+ await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`)
500
569
  if (switchbot !== false) {
501
570
  switchbot
502
571
  .discover({ model: this.device.bleModel, quick: true, id: this.device.bleMac })
@@ -504,82 +573,78 @@ export class BlindTilt extends deviceBase {
504
573
  return await this.retryBLE({
505
574
  max: await this.maxRetryBLE(),
506
575
  fn: async () => {
507
- return await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), setPositionMode);
576
+ return await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), setPositionMode)
508
577
  },
509
- });
578
+ })
510
579
  })
511
580
  .then(async () => {
512
- await this.successLog(`TargetPostion: ${this.WindowCovering.TargetPosition} sent over SwitchBot BLE, sent successfully`);
513
- await this.updateHomeKitCharacteristics();
581
+ await this.successLog(`TargetPostion: ${this.WindowCovering.TargetPosition} sent over SwitchBot BLE, sent successfully`)
582
+ await this.updateHomeKitCharacteristics()
514
583
  })
515
584
  .catch(async (e: any) => {
516
- await this.apiError(e);
517
- await this.errorLog(`failed BLEpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
518
- await this.BLEPushConnection();
519
- });
585
+ await this.apiError(e)
586
+ await this.errorLog(`failed BLEpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
587
+ await this.BLEPushConnection()
588
+ })
520
589
  } else {
521
- await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
522
- await this.BLEPushConnection();
590
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
591
+ await this.BLEPushConnection()
523
592
  }
524
593
  } else {
525
- await this.debugLog(`No changes (BLEpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition},`
526
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
594
+ await this.debugLog(`No changes (BLEpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
527
595
  }
528
596
  }
529
597
 
530
598
  async openAPIpushChanges(): Promise<void> {
531
- await this.debugLog('openAPIpushChanges');
532
- const hasDifferentAndRelevantHorizontalTiltAngle =
533
- this.mappingMode === BlindTiltMappingMode.UseTiltForDirection
534
- && this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle;
599
+ await this.debugLog('openAPIpushChanges')
600
+ const hasDifferentAndRelevantHorizontalTiltAngle
601
+ = this.mappingMode === BlindTiltMappingMode.UseTiltForDirection
602
+ && this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle
535
603
  if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition
536
604
  || hasDifferentAndRelevantHorizontalTiltAngle || this.device.disableCaching) {
537
- const [direction, position] = this.mapHomekitValuesToDeviceValues(Number(this.WindowCovering.TargetPosition),
538
- Number(this.WindowCovering.TargetHorizontalTiltAngle));
539
- const { Mode, setPositionMode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
540
- await this.debugLog(`Pushing ${this.WindowCovering.TargetPosition} (device = ${direction};${position})`);
541
- await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`);
542
- let bodyChange: string;
605
+ const [direction, position] = this.mapHomekitValuesToDeviceValues(Number(this.WindowCovering.TargetPosition), Number(this.WindowCovering.TargetHorizontalTiltAngle))
606
+ const { Mode, setPositionMode }: { setPositionMode: number, Mode: string } = await this.setPerformance()
607
+ await this.debugLog(`Pushing ${this.WindowCovering.TargetPosition} (device = ${direction};${position})`)
608
+ await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`)
609
+ let bodyChange: string
543
610
  if (position === 100) {
544
611
  bodyChange = JSON.stringify({
545
612
  command: 'fullyOpen',
546
613
  parameter: 'default',
547
614
  commandType: 'command',
548
- });
615
+ })
549
616
  } else if (position === 0) {
550
617
  bodyChange = JSON.stringify({
551
618
  command: direction === 'up' ? 'closeUp' : 'closeDown',
552
619
  parameter: 'default',
553
620
  commandType: 'command',
554
- });
621
+ })
555
622
  } else {
556
623
  bodyChange = JSON.stringify({
557
624
  command: 'setPosition',
558
625
  parameter: `${direction};${position}`,
559
626
  commandType: 'command',
560
- });
627
+ })
561
628
  }
562
- await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`);
629
+ await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`)
563
630
  try {
564
- const { body, statusCode } = await this.pushChangeRequest(bodyChange);
565
- const deviceStatus: any = await body.json();
566
- await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
631
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange)
632
+ const deviceStatus: any = await body.json()
633
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
567
634
  if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
568
- await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
569
- await this.updateHomeKitCharacteristics();
635
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
636
+ await this.updateHomeKitCharacteristics()
570
637
  } else {
571
- await this.statusCode(statusCode);
572
- await this.statusCode(deviceStatus.statusCode);
638
+ await this.statusCode(statusCode)
639
+ await this.statusCode(deviceStatus.statusCode)
573
640
  }
574
641
  } catch (e: any) {
575
- await this.apiError(e);
576
- await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
642
+ await this.apiError(e)
643
+ await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
577
644
  }
578
645
  } else {
579
- await this.debugLog(`No changes (openAPIpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition},`
580
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
581
- await this.debugLog(`No changes (openAPIpushChanges), TargetHorizontalTiltAngle: ${this.WindowCovering.TargetHorizontalTiltAngle},`
582
- + ` CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
646
+ await this.debugLog(`No changes (openAPIpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
647
+ await this.debugLog(`No changes (openAPIpushChanges), TargetHorizontalTiltAngle: ${this.WindowCovering.TargetHorizontalTiltAngle}, CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`)
583
648
  }
584
649
  }
585
650
 
@@ -588,15 +653,15 @@ export class BlindTilt extends deviceBase {
588
653
  */
589
654
  async TargetHorizontalTiltAngleSet(value: CharacteristicValue): Promise<void> {
590
655
  if (this.WindowCovering.TargetHorizontalTiltAngle !== this.accessory.context.TargetHorizontalTiltAngle) {
591
- await this.debugLog(`Set TargetHorizontalTiltAngle: ${value}`);
656
+ await this.debugLog(`Set TargetHorizontalTiltAngle: ${value}`)
592
657
  } else {
593
- await this.debugLog(`No changes, TargetHorizontalTiltAngle: ${value}`);
658
+ await this.debugLog(`No changes, TargetHorizontalTiltAngle: ${value}`)
594
659
  }
595
660
 
596
- //value = value < 0 ? -90 : 90;
597
- this.WindowCovering.TargetHorizontalTiltAngle = value;
598
- await this.mqtt('TargetHorizontalTiltAngle', this.WindowCovering.TargetHorizontalTiltAngle);
599
- await this.startUpdatingBlindTiltIfNeeded();
661
+ // value = value < 0 ? -90 : 90;
662
+ this.WindowCovering.TargetHorizontalTiltAngle = value
663
+ await this.mqtt('TargetHorizontalTiltAngle', this.WindowCovering.TargetHorizontalTiltAngle)
664
+ await this.startUpdatingBlindTiltIfNeeded()
600
665
  }
601
666
 
602
667
  /**
@@ -604,172 +669,188 @@ export class BlindTilt extends deviceBase {
604
669
  */
605
670
  async TargetPositionSet(value: CharacteristicValue): Promise<void> {
606
671
  if (this.WindowCovering.TargetPosition !== this.accessory.context.TargetPosition) {
607
- await this.debugLog(`Set TargetPosition: ${value}`);
672
+ await this.debugLog(`Set TargetPosition: ${value}`)
608
673
  } else {
609
- await this.debugLog(`No changes, TargetPosition: ${value}`);
674
+ await this.debugLog(`No changes, TargetPosition: ${value}`)
610
675
  }
611
676
 
612
- this.WindowCovering.TargetPosition = value;
613
- await this.mqtt('TargetPosition', this.WindowCovering.TargetPosition);
614
- await this.startUpdatingBlindTiltIfNeeded();
677
+ this.WindowCovering.TargetPosition = value
678
+ await this.mqtt('TargetPosition', this.WindowCovering.TargetPosition)
679
+ await this.startUpdatingBlindTiltIfNeeded()
615
680
  }
616
681
 
617
682
  async startUpdatingBlindTiltIfNeeded(): Promise<void> {
618
- await this.setMinMax();
619
- await this.debugLog('setMinMax');
683
+ await this.setMinMax()
684
+ await this.debugLog('setMinMax')
620
685
  if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition
621
686
  || this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle) {
622
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
623
- this.setNewTarget = true;
624
- await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
687
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING
688
+ this.setNewTarget = true
689
+ await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
625
690
  } else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
626
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
627
- this.setNewTarget = true;
628
- await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
691
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING
692
+ this.setNewTarget = true
693
+ await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
629
694
  } else {
630
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
631
- this.setNewTarget = false;
632
- await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
695
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
696
+ this.setNewTarget = false
697
+ await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
633
698
  }
634
- this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
635
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
699
+ this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState)
700
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
636
701
 
637
702
  /**
638
703
  * If Blind Tilt movement time is short, the moving flag from backend is always false.
639
704
  * The minimum time depends on the network control latency.
640
705
  */
641
- clearTimeout(this.setNewTargetTimer);
642
- await this.debugLog(`deviceUpdateRate: ${this.deviceUpdateRate}`);
706
+ clearTimeout(this.setNewTargetTimer)
707
+ await this.debugLog(`deviceUpdateRate: ${this.deviceUpdateRate}`)
643
708
  if (this.setNewTarget) {
644
709
  this.setNewTargetTimer = setTimeout(async () => {
645
- await this.debugLog(`setNewTarget ${this.setNewTarget} timeout`);
646
- this.setNewTarget = false;
647
- }, this.deviceUpdateRate * 1000);
710
+ await this.debugLog(`setNewTarget ${this.setNewTarget} timeout`)
711
+ this.setNewTarget = false
712
+ }, this.deviceUpdateRate * 1000)
713
+ }
714
+ this.doBlindTiltUpdate.next()
715
+ }
716
+
717
+ /**
718
+ * Handle requests to set the value of the "Target Position" characteristic
719
+ */
720
+ async OpenModeSwitchSet(value: CharacteristicValue): Promise<void> {
721
+ if (this.OpenModeSwitch && this.device.blindTilt?.silentModeSwitch) {
722
+ this.debugLog(`Silent Open Mode: ${value}`)
723
+ this.OpenModeSwitch.On = value
724
+ this.accessory.context.OpenModeSwitch.On = value
725
+ this.doBlindTiltUpdate.next()
726
+ }
727
+ }
728
+
729
+ /**
730
+ * Handle requests to set the value of the "Target Position" characteristic
731
+ */
732
+ async CloseModeSwitchSet(value: CharacteristicValue): Promise<void> {
733
+ if (this.CloseModeSwitch && this.device.blindTilt?.silentModeSwitch) {
734
+ this.debugLog(`Silent Close Mode: ${value}`)
735
+ this.CloseModeSwitch.On = value
736
+ this.accessory.context.CloseModeSwitch.On = value
737
+ this.doBlindTiltUpdate.next()
648
738
  }
649
- this.doBlindTiltUpdate.next();
650
739
  }
651
740
 
652
741
  async updateHomeKitCharacteristics(): Promise<void> {
653
- await this.setMinMax();
742
+ await this.setMinMax()
654
743
  // CurrentHorizontalTiltAngle
655
744
  if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
656
- await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.CurrentHorizontalTiltAngle,
657
- this.WindowCovering.CurrentHorizontalTiltAngle, 'CurrentHorizontalTiltAngle');
745
+ await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.CurrentHorizontalTiltAngle, this.WindowCovering.CurrentHorizontalTiltAngle, 'CurrentHorizontalTiltAngle')
658
746
  }
659
747
  // CurrentPosition
660
- await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.CurrentPosition,
661
- this.WindowCovering.CurrentPosition, 'CurrentPosition');
748
+ await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.CurrentPosition, this.WindowCovering.CurrentPosition, 'CurrentPosition')
662
749
  // PositionState
663
- await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.PositionState,
664
- this.WindowCovering.PositionState, 'PositionState');
750
+ await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.PositionState, this.WindowCovering.PositionState, 'PositionState')
665
751
  // TargetPosition
666
- await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.TargetPosition,
667
- this.WindowCovering.TargetPosition, 'TargetPosition');
752
+ await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.TargetPosition, this.WindowCovering.TargetPosition, 'TargetPosition')
668
753
  // CurrentAmbientLightLevel
669
754
  if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
670
- const history = { time: Math.round(new Date().valueOf() / 1000), lux: this.LightSensor.CurrentAmbientLightLevel };
671
- await this.updateCharacteristic(this.LightSensor?.Service, this.hap.Characteristic.CurrentAmbientLightLevel,
672
- this.LightSensor?.CurrentAmbientLightLevel, 'CurrentAmbientLightLevel', history);
755
+ const history = { time: Math.round(new Date().valueOf() / 1000), lux: this.LightSensor.CurrentAmbientLightLevel }
756
+ await this.updateCharacteristic(this.LightSensor?.Service, this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor?.CurrentAmbientLightLevel, 'CurrentAmbientLightLevel', history)
673
757
  }
674
758
  // BatteryLevel
675
- await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel,
676
- this.Battery.BatteryLevel, 'BatteryLevel');
759
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel, 'BatteryLevel')
677
760
  // StatusLowBattery
678
- await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery,
679
- this.Battery.StatusLowBattery, 'StatusLowBattery');
761
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery, 'StatusLowBattery')
680
762
  // ChargingState
681
- await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.ChargingState,
682
- this.Battery.ChargingState, 'ChargingState');
763
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.ChargingState, this.Battery.ChargingState, 'ChargingState')
683
764
  }
684
765
 
685
766
  async BLEPushConnection() {
686
767
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
687
- await this.warnLog('Using OpenAPI Connection to Push Changes');
688
- await this.openAPIpushChanges();
768
+ await this.warnLog('Using OpenAPI Connection to Push Changes')
769
+ await this.openAPIpushChanges()
689
770
  }
690
771
  }
691
772
 
692
773
  async BLERefreshConnection(switchbot: any): Promise<void> {
693
- await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
774
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
694
775
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
695
- await this.warnLog('Using OpenAPI Connection to Refresh Status');
696
- await this.openAPIRefreshStatus();
776
+ await this.warnLog('Using OpenAPI Connection to Refresh Status')
777
+ await this.openAPIRefreshStatus()
697
778
  }
698
779
  }
699
780
 
700
781
  async setPerformance() {
701
- let setPositionMode: number;
702
- let Mode: string;
782
+ let setPositionMode: number
783
+ let Mode: string
703
784
  if (Number(this.WindowCovering.TargetPosition) > 50) {
704
- if (this.device.blindTilt?.setOpenMode === '1') {
705
- setPositionMode = 1;
706
- Mode = 'Silent Mode';
707
- } else if (this.device.blindTilt?.setOpenMode === '0') {
708
- setPositionMode = 0;
709
- Mode = 'Performance Mode';
785
+ if (this.device.blindTilt?.setOpenMode === '1' || this.OpenModeSwitch?.On) {
786
+ setPositionMode = 1
787
+ Mode = 'Silent Mode'
788
+ } else if (this.device.blindTilt?.setOpenMode === '0' || !this.OpenModeSwitch?.On) {
789
+ setPositionMode = 0
790
+ Mode = 'Performance Mode'
710
791
  } else {
711
- setPositionMode = 0;
712
- Mode = 'Default Mode';
792
+ setPositionMode = 0
793
+ Mode = 'Default Mode'
713
794
  }
714
795
  } else {
715
- if (this.device.blindTilt?.setCloseMode === '1') {
716
- setPositionMode = 1;
717
- Mode = 'Silent Mode';
718
- } else if (this.device.blindTilt?.setOpenMode === '0') {
719
- setPositionMode = 0;
720
- Mode = 'Performance Mode';
796
+ if (this.device.blindTilt?.setCloseMode === '1' || this.CloseModeSwitch?.On) {
797
+ setPositionMode = 1
798
+ Mode = 'Silent Mode'
799
+ } else if (this.device.blindTilt?.setOpenMode === '0' || !this.CloseModeSwitch?.On) {
800
+ setPositionMode = 0
801
+ Mode = 'Performance Mode'
721
802
  } else {
722
- setPositionMode = 0;
723
- Mode = 'Default Mode';
803
+ setPositionMode = 0
804
+ Mode = 'Default Mode'
724
805
  }
725
806
  }
726
- return { setPositionMode, Mode };
807
+ return { setPositionMode, Mode }
727
808
  }
728
809
 
729
810
  async setMinMax(): Promise<void> {
730
811
  if (this.device.blindTilt?.set_min) {
731
812
  if (Number(this.WindowCovering.CurrentPosition) <= this.device.blindTilt?.set_min) {
732
- this.WindowCovering.CurrentPosition = 0;
813
+ this.WindowCovering.CurrentPosition = 0
733
814
  }
734
815
  }
735
816
  if (this.device.blindTilt?.set_max) {
736
817
  if (Number(this.WindowCovering.CurrentPosition) >= this.device.blindTilt?.set_max) {
737
- this.WindowCovering.CurrentPosition = 100;
818
+ this.WindowCovering.CurrentPosition = 100
738
819
  }
739
820
  }
740
821
  if (this.device.history) {
741
- const motion = this.accessory.getService(this.hap.Service.MotionSensor);
742
- const state = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
743
- motion?.updateCharacteristic(this.hap.Characteristic.MotionDetected, state);
822
+ const motion = this.accessory.getService(this.hap.Service.MotionSensor)
823
+ const state = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0
824
+ motion?.updateCharacteristic(this.hap.Characteristic.MotionDetected, state)
744
825
  }
745
826
 
746
827
  if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
747
- this.WindowCovering.CurrentHorizontalTiltAngle = Number(this.WindowCovering.CurrentHorizontalTiltAngle) < 0 ? -90 : 90;
828
+ this.WindowCovering.CurrentHorizontalTiltAngle = Number(this.WindowCovering.CurrentHorizontalTiltAngle) < 0 ? -90 : 90
748
829
  }
749
830
  }
750
831
 
751
832
  async offlineOff(): Promise<void> {
752
833
  if (this.device.offline) {
753
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
754
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
755
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
756
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle, 90);
757
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle, 90);
834
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100)
835
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
836
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100)
837
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle, 90)
838
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle, 90)
758
839
  }
759
840
  }
760
841
 
761
842
  async apiError(e: any): Promise<void> {
762
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
763
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
764
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
765
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle, e);
766
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle, e);
767
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
768
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
769
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, e);
843
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e)
844
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e)
845
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e)
846
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle, e)
847
+ this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle, e)
848
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e)
849
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e)
850
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, e)
770
851
  if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
771
- this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
772
- this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e);
852
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e)
853
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e)
773
854
  }
774
855
  }
775
856
 
@@ -777,58 +858,58 @@ export class BlindTilt extends deviceBase {
777
858
  direction: blindTiltStatus['direction'] | blindTiltWebhookContext['direction'],
778
859
  slidePosition: blindTiltStatus['slidePosition'] | blindTiltWebhookContext['slidePosition'],
779
860
  ) {
780
- const [homekitPosition, homekitTiltAngle] = this.mapDeviceValuesToHomekitValues(Number(slidePosition),
781
- String(direction));
782
- await this.debugLog(`Slide Position: ${slidePosition}`);
783
- await this.debugLog(`Homekit Position: ${homekitPosition}`);
861
+ const [homekitPosition, homekitTiltAngle] = this.mapDeviceValuesToHomekitValues(Number(slidePosition), String(direction))
862
+ await this.debugLog(`Slide Position: ${slidePosition}`)
863
+ await this.debugLog(`Homekit Position: ${homekitPosition}`)
784
864
 
785
- this.WindowCovering.CurrentPosition = homekitPosition;
786
- await this.setMinMax();
787
- await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
865
+ this.WindowCovering.CurrentPosition = homekitPosition
866
+ await this.setMinMax()
867
+ await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
788
868
 
789
869
  if (homekitTiltAngle) {
790
- this.WindowCovering.CurrentHorizontalTiltAngle = homekitTiltAngle!;
791
- await this.debugLog(`CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
870
+ this.WindowCovering.CurrentHorizontalTiltAngle = homekitTiltAngle!
871
+ await this.debugLog(`CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`)
792
872
  }
793
873
 
794
874
  if (this.setNewTarget) {
795
- await this.infoLog('Checking Status ...');
796
- await this.setMinMax();
875
+ this.blindTiltMoving = true
876
+ await this.infoLog('Checking Status ...')
877
+ await this.setMinMax()
797
878
  if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition
798
879
  || (homekitTiltAngle && this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle)) {
799
- await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
800
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
801
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
802
- await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`);
880
+ await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
881
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING
882
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
883
+ await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`)
803
884
  } else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
804
- await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
805
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
806
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
807
- await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`);
885
+ await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
886
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING
887
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
888
+ await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`)
808
889
  } else {
809
- await this.debugLog(`Standby because reached position, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
810
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
811
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
812
- await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
890
+ await this.debugLog(`Standby because reached position, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
891
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
892
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
893
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`)
813
894
  }
814
895
  } else {
815
- await this.debugLog(`Standby because device not moving, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
816
- this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
896
+ this.blindTiltMoving = false
897
+ await this.debugLog(`Standby because device not moving, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
898
+ this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition
817
899
  if (homekitTiltAngle) {
818
- this.WindowCovering.TargetHorizontalTiltAngle = this.WindowCovering.CurrentHorizontalTiltAngle;
900
+ this.WindowCovering.TargetHorizontalTiltAngle = this.WindowCovering.CurrentHorizontalTiltAngle
819
901
  }
820
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
821
- await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
902
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
903
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`)
822
904
  }
823
- await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition},`
824
- + ` PositionState: ${this.WindowCovering.PositionState}`);
905
+ await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState}`)
825
906
  }
826
907
 
827
908
  /**
828
909
  * Maps device values to homekit values
829
910
  *
830
911
  * @param devicePosition the position as reported by the devide
831
- * @param direction the direction as reported by the device
912
+ * @param deviceDirection the direction as reported by the device
832
913
  * @returns [homekit position, homekit tiltAngle]
833
914
  */
834
915
  mapDeviceValuesToHomekitValues(devicePosition: number, deviceDirection: string): [CharacteristicValue, CharacteristicValue?] {
@@ -838,44 +919,44 @@ export class BlindTilt extends deviceBase {
838
919
 
839
920
  // homekit position 0 => closed
840
921
  // homekit position 100 => open
841
- const direction = deviceDirection === 'up' ? 'up' : 'down';
842
- this.debugLog(`Mapping device values to homekit values, devicePostion: ${devicePosition}, deviceDirection: ${direction}`);
922
+ const direction = deviceDirection === 'up' ? 'up' : 'down'
923
+ this.debugLog(`Mapping device values to homekit values, devicePostion: ${devicePosition}, deviceDirection: ${direction}`)
843
924
  switch (this.mappingMode) {
844
925
  case BlindTiltMappingMode.OnlyUp:
845
926
  // we only close upwards, so we see anything that is tilted downwards(<50) as open
846
927
  if (devicePosition < 50) {
847
- return [100, undefined]; // fully open in homekit
928
+ return [100, undefined] // fully open in homekit
848
929
  } else {
849
930
  // we range from 50->100, with 100 being closed, so map to homekit by scaling to 0..100 and then reversing
850
- return [100 - (devicePosition - 50) * 2, undefined];
931
+ return [100 - (devicePosition - 50) * 2, undefined]
851
932
  }
852
933
 
853
934
  case BlindTiltMappingMode.OnlyDown:
854
935
  // we only close downwards, so we see anything that is tilted upwards(>50) as upwards
855
936
  if (devicePosition > 50) {
856
- return [100, undefined]; // fully open in homekit
937
+ return [100, undefined] // fully open in homekit
857
938
  } else {
858
939
  // we range from 0..50 so scale to homekit and then reverse
859
- return [devicePosition * 2, undefined];
940
+ return [devicePosition * 2, undefined]
860
941
  }
861
942
 
862
943
  case BlindTiltMappingMode.DownAndUp:
863
944
  // we close both ways with closed downwards being 0 in homekit and closed upwards in homekit being 100. Open is 50 in homekit
864
- return [devicePosition, undefined];
945
+ return [devicePosition, undefined]
865
946
 
866
947
  case BlindTiltMappingMode.UpAndDown:
867
948
  // we close both ways with closed downwards being 1000 in homekit and closed upwards in homekit being 0. Open is 50 in homekit.,
868
949
  // so we reverse the value
869
- return [100 - devicePosition, undefined];
950
+ return [100 - devicePosition, undefined]
870
951
 
871
952
  case BlindTiltMappingMode.UseTiltForDirection:
872
953
  // we use tilt for direction, so being closed downwards is 0 in homekit with -90 tilt, while being closed upwards is 0 with 90 tilt.
873
954
  if (devicePosition <= 50) {
874
955
  // downwards tilted, so we range from 0..50, with 0 being closed and 50 being open, so scale.
875
- return [devicePosition * 2, -90];
956
+ return [devicePosition * 2, -90]
876
957
  } else {
877
958
  // upwards tilted, so we range from 50..100, with 50 being open and 100 being closed, so scale and rever
878
- return [100 - (devicePosition - 50) * 2, 90];
959
+ return [100 - (devicePosition - 50) * 2, 90]
879
960
  }
880
961
  }
881
962
  }
@@ -884,7 +965,7 @@ export class BlindTilt extends deviceBase {
884
965
  * Maps homekit values to device values
885
966
  *
886
967
  * @param homekitPosition the position as reported by homekit
887
- * @param homekitTiltAngle? the tilt angle as reported by homekit
968
+ * @param homekitTiltAngle the tilt angle as reported by homekit
888
969
  * @returns [device position, device direction]
889
970
  */
890
971
  mapHomekitValuesToDeviceValues(homekitPosition: number, homekitTiltAngle: number): [string, number] {
@@ -899,10 +980,10 @@ export class BlindTilt extends deviceBase {
899
980
  switch (this.mappingMode) {
900
981
  case BlindTiltMappingMode.OnlyUp:
901
982
  // invert
902
- return ['up', homekitPosition];
983
+ return ['up', homekitPosition]
903
984
  case BlindTiltMappingMode.OnlyDown:
904
985
  // invert
905
- return ['down', homekitPosition];
986
+ return ['down', homekitPosition]
906
987
 
907
988
  case BlindTiltMappingMode.DownAndUp:
908
989
  // homekit 0 = downwards closed,
@@ -910,10 +991,10 @@ export class BlindTilt extends deviceBase {
910
991
  // homekit 100 = upwards closed
911
992
  if (homekitPosition <= 50) {
912
993
  // homekit 0..50 -> device 100..0 so scale and invert
913
- return ['down', 100 - homekitPosition * 2];
994
+ return ['down', 100 - homekitPosition * 2]
914
995
  } else {
915
996
  // homekit 50..100 -> device 0..100, so rebase, scale and invert
916
- return ['up', (homekitPosition - 50) * 2];
997
+ return ['up', (homekitPosition - 50) * 2]
917
998
  }
918
999
 
919
1000
  case BlindTiltMappingMode.UpAndDown:
@@ -922,10 +1003,10 @@ export class BlindTilt extends deviceBase {
922
1003
  // homekit 100 = upwards closed
923
1004
  if (homekitPosition <= 50) {
924
1005
  // homekit 0..50 -> device 0..100 so scale and invert
925
- return ['up', homekitPosition * 2];
1006
+ return ['up', homekitPosition * 2]
926
1007
  } else {
927
1008
  // homekit 50..100 -> device 100...0 so scale
928
- return ['down', 100 - homekitPosition * 2];
1009
+ return ['down', 100 - homekitPosition * 2]
929
1010
  }
930
1011
 
931
1012
  case BlindTiltMappingMode.UseTiltForDirection:
@@ -936,11 +1017,11 @@ export class BlindTilt extends deviceBase {
936
1017
  if (homekitTiltAngle! <= 0) {
937
1018
  // downwards
938
1019
  // homekit 0..100 -> device 0..100, so invert
939
- return ['down', homekitPosition];
1020
+ return ['down', homekitPosition]
940
1021
  } else {
941
1022
  // upwards
942
1023
  // homekit 0..100 -> device 0..100, so invert
943
- return ['up', homekitPosition];
1024
+ return ['up', homekitPosition]
944
1025
  }
945
1026
  }
946
1027
  }