@switchbot/homebridge-switchbot 3.5.0-beta.9 → 3.5.1-beta.0

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 +164 -22
  4. package/dist/device/blindtilt.d.ts +21 -96
  5. package/dist/device/blindtilt.d.ts.map +1 -1
  6. package/dist/device/blindtilt.js +457 -866
  7. package/dist/device/blindtilt.js.map +1 -1
  8. package/dist/device/bot.d.ts +27 -72
  9. package/dist/device/bot.d.ts.map +1 -1
  10. package/dist/device/bot.js +851 -913
  11. package/dist/device/bot.js.map +1 -1
  12. package/dist/device/ceilinglight.d.ts +15 -69
  13. package/dist/device/ceilinglight.d.ts.map +1 -1
  14. package/dist/device/ceilinglight.js +316 -742
  15. package/dist/device/ceilinglight.js.map +1 -1
  16. package/dist/device/colorbulb.d.ts +15 -76
  17. package/dist/device/colorbulb.d.ts.map +1 -1
  18. package/dist/device/colorbulb.js +380 -833
  19. package/dist/device/colorbulb.js.map +1 -1
  20. package/dist/device/contact.d.ts +14 -66
  21. package/dist/device/contact.d.ts.map +1 -1
  22. package/dist/device/contact.js +267 -602
  23. package/dist/device/contact.js.map +1 -1
  24. package/dist/device/curtain.d.ts +18 -89
  25. package/dist/device/curtain.d.ts.map +1 -1
  26. package/dist/device/curtain.js +469 -897
  27. package/dist/device/curtain.js.map +1 -1
  28. package/dist/device/device.d.ts +76 -0
  29. package/dist/device/device.d.ts.map +1 -0
  30. package/dist/device/device.js +846 -0
  31. package/dist/device/device.js.map +1 -0
  32. package/dist/device/fan.d.ts +63 -0
  33. package/dist/device/fan.d.ts.map +1 -0
  34. package/dist/device/fan.js +645 -0
  35. package/dist/device/fan.js.map +1 -0
  36. package/dist/device/hub.d.ts +19 -58
  37. package/dist/device/hub.d.ts.map +1 -1
  38. package/dist/device/hub.js +304 -640
  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 +300 -710
  43. package/dist/device/humidifier.js.map +1 -1
  44. package/dist/device/iosensor.d.ts +12 -64
  45. package/dist/device/iosensor.d.ts.map +1 -1
  46. package/dist/device/iosensor.js +225 -643
  47. package/dist/device/iosensor.js.map +1 -1
  48. package/dist/device/lightstrip.d.ts +12 -70
  49. package/dist/device/lightstrip.d.ts.map +1 -1
  50. package/dist/device/lightstrip.js +371 -742
  51. package/dist/device/lightstrip.js.map +1 -1
  52. package/dist/device/lock.d.ts +17 -63
  53. package/dist/device/lock.d.ts.map +1 -1
  54. package/dist/device/lock.js +309 -642
  55. package/dist/device/lock.js.map +1 -1
  56. package/dist/device/meter.d.ts +15 -64
  57. package/dist/device/meter.d.ts.map +1 -1
  58. package/dist/device/meter.js +223 -638
  59. package/dist/device/meter.js.map +1 -1
  60. package/dist/device/meterplus.d.ts +15 -65
  61. package/dist/device/meterplus.d.ts.map +1 -1
  62. package/dist/device/meterplus.js +216 -644
  63. package/dist/device/meterplus.js.map +1 -1
  64. package/dist/device/motion.d.ts +12 -69
  65. package/dist/device/motion.d.ts.map +1 -1
  66. package/dist/device/motion.js +209 -588
  67. package/dist/device/motion.js.map +1 -1
  68. package/dist/device/plug.d.ts +10 -57
  69. package/dist/device/plug.d.ts.map +1 -1
  70. package/dist/device/plug.js +141 -532
  71. package/dist/device/plug.js.map +1 -1
  72. package/dist/device/robotvacuumcleaner.d.ts +13 -63
  73. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  74. package/dist/device/robotvacuumcleaner.js +252 -609
  75. package/dist/device/robotvacuumcleaner.js.map +1 -1
  76. package/dist/device/waterdetector.d.ts +11 -63
  77. package/dist/device/waterdetector.d.ts.map +1 -1
  78. package/dist/device/waterdetector.js +179 -521
  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 +337 -482
  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 +108 -333
  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 +47 -299
  98. package/dist/irdevice/camera.js.map +1 -1
  99. package/dist/irdevice/fan.d.ts +7 -43
  100. package/dist/irdevice/fan.d.ts.map +1 -1
  101. package/dist/irdevice/fan.js +95 -364
  102. package/dist/irdevice/fan.js.map +1 -1
  103. package/dist/irdevice/irdevice.d.ts +46 -0
  104. package/dist/irdevice/irdevice.d.ts.map +1 -0
  105. package/dist/irdevice/irdevice.js +393 -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 +121 -376
  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 +441 -584
  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 +94 -353
  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 +48 -299
  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 +50 -305
  126. package/dist/irdevice/waterheater.js.map +1 -1
  127. package/dist/platform.d.ts +22 -8
  128. package/dist/platform.d.ts.map +1 -1
  129. package/dist/platform.js +342 -191
  130. package/dist/platform.js.map +1 -1
  131. package/dist/settings.d.ts +66 -18
  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 +95 -0
  136. package/dist/utils.d.ts.map +1 -1
  137. package/dist/utils.js +657 -1
  138. package/dist/utils.js.map +1 -1
  139. package/eslint.config.js +96 -0
  140. package/package.json +20 -16
  141. package/src/custom.d.ts +2 -1
  142. package/src/device/blindtilt.ts +488 -937
  143. package/src/device/bot.ts +907 -1016
  144. package/src/device/ceilinglight.ts +330 -798
  145. package/src/device/colorbulb.ts +394 -904
  146. package/src/device/contact.ts +298 -637
  147. package/src/device/curtain.ts +496 -954
  148. package/src/device/device.ts +872 -0
  149. package/src/device/fan.ts +692 -0
  150. package/src/device/hub.ts +338 -671
  151. package/src/device/humidifier.ts +330 -777
  152. package/src/device/iosensor.ts +258 -671
  153. package/src/device/lightstrip.ts +394 -809
  154. package/src/device/lock.ts +345 -700
  155. package/src/device/meter.ts +256 -666
  156. package/src/device/meterplus.ts +248 -672
  157. package/src/device/motion.ts +234 -622
  158. package/src/device/plug.ts +152 -572
  159. package/src/device/robotvacuumcleaner.ts +273 -653
  160. package/src/device/waterdetector.ts +198 -549
  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 +368 -540
  165. package/src/irdevice/airpurifier.ts +134 -369
  166. package/src/irdevice/camera.ts +60 -324
  167. package/src/irdevice/fan.ts +111 -392
  168. package/src/irdevice/irdevice.ts +406 -0
  169. package/src/irdevice/light.ts +159 -425
  170. package/src/irdevice/other.ts +509 -661
  171. package/src/irdevice/tv.ts +123 -388
  172. package/src/irdevice/vacuumcleaner.ts +61 -324
  173. package/src/irdevice/waterheater.ts +63 -333
  174. package/src/platform.ts +395 -259
  175. package/src/settings.ts +120 -610
  176. package/src/utils.ts +661 -1
  177. package/src/device/waterdetector.json +0 -11
@@ -1,100 +1,66 @@
1
- import asyncmqtt from 'async-mqtt';
2
- import { hostname } from 'os';
3
- import { interval } from 'rxjs';
4
- import { request } from 'undici';
5
- import { Devices } from '../settings.js';
6
- import { sleep } from '../utils.js';
1
+ import { deviceBase } from './device.js';
2
+ import { Subject, interval, skipWhile } from 'rxjs';
7
3
  /**
8
4
  * Platform Accessory
9
5
  * An instance of this class is created for each accessory your platform registers
10
6
  * Each accessory may expose multiple services of different service types.
11
7
  */
12
- export class MeterPlus {
8
+ export class MeterPlus extends deviceBase {
13
9
  platform;
14
- accessory;
15
- device;
16
- api;
17
- log;
18
- config;
19
- hap;
20
10
  // Services
21
- batteryService;
22
- humidityService;
23
- temperatureService;
24
- // Characteristic Values
25
- BatteryLevel;
26
- FirmwareRevision;
27
- StatusLowBattery;
28
- CurrentTemperature;
29
- CurrentRelativeHumidity;
30
- // OpenAPI Status
31
- OpenAPI_BatteryLevel;
32
- OpenAPI_FirmwareRevision;
33
- OpenAPI_CurrentTemperature;
34
- OpenAPI_CurrentRelativeHumidity;
35
- // BLE Status
36
- BLE_Celsius;
37
- BLE_Fahrenheit;
38
- BLE_BatteryLevel;
39
- BLE_CurrentTemperature;
40
- BLE_CurrentRelativeHumidity;
41
- // BLE Others
42
- BLE_IsConnected;
43
- //MQTT stuff
44
- mqttClient = null;
45
- // EVE history service handler
46
- historyService;
47
- // Config
48
- scanDuration;
49
- deviceLogging;
50
- deviceRefreshRate;
51
- // Connection
52
- OpenAPI;
53
- BLE;
11
+ Battery;
12
+ HumiditySensor;
13
+ TemperatureSensor;
14
+ // Updates
15
+ meterUpdateInProgress;
16
+ doMeterUpdate;
54
17
  constructor(platform, accessory, device) {
18
+ super(platform, accessory, device);
55
19
  this.platform = platform;
56
- this.accessory = accessory;
57
- this.device = device;
58
- this.api = this.platform.api;
59
- this.log = this.platform.log;
60
- this.config = this.platform.config;
61
- this.hap = this.api.hap;
62
- // Connection
63
- this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
64
- this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
65
- // default placeholders
66
- this.deviceLogs(device);
67
- this.scan(device);
68
- this.refreshRate(device);
69
- this.deviceContext();
70
- this.setupHistoryService(device);
71
- this.setupMqtt(device);
72
- this.deviceConfig(device);
73
- // Retrieve initial values and updateHomekit
74
- this.refreshStatus();
75
- // set accessory information
76
- accessory
77
- .getService(this.hap.Service.AccessoryInformation)
78
- .setCharacteristic(this.hap.Characteristic.Manufacturer, 'SwitchBot')
79
- .setCharacteristic(this.hap.Characteristic.Model, this.model(device))
80
- .setCharacteristic(this.hap.Characteristic.SerialNumber, device.deviceId)
81
- .setCharacteristic(this.hap.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision);
82
- // Temperature Sensor Service
20
+ // this is subject we use to track when we need to POST changes to the SwitchBot API
21
+ this.doMeterUpdate = new Subject();
22
+ this.meterUpdateInProgress = false;
23
+ // Initialize Battery Service
24
+ accessory.context.Battery = accessory.context.Battery ?? {};
25
+ this.Battery = {
26
+ Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
27
+ Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery),
28
+ BatteryLevel: accessory.context.BatteryLevel ?? 100,
29
+ StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
30
+ };
31
+ accessory.context.Battery = this.Battery;
32
+ // Initialize Battery Characteristics
33
+ this.Battery.Service
34
+ .setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
35
+ .setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE)
36
+ .getCharacteristic(this.hap.Characteristic.BatteryLevel)
37
+ .onGet(() => {
38
+ return this.Battery.BatteryLevel;
39
+ });
40
+ this.Battery.Service
41
+ .getCharacteristic(this.hap.Characteristic.StatusLowBattery)
42
+ .onGet(() => {
43
+ return this.Battery.StatusLowBattery;
44
+ });
45
+ // Initialize Temperature Sensor Service
83
46
  if (device.meter?.hide_temperature) {
84
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Temperature Sensor Service`);
85
- this.temperatureService = this.accessory.getService(this.hap.Service.TemperatureSensor);
86
- accessory.removeService(this.temperatureService);
87
- }
88
- else if (!this.temperatureService) {
89
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Temperature Sensor Service`);
90
- const temperatureService = `${accessory.displayName} Temperature Sensor`;
91
- (this.temperatureService = this.accessory.getService(this.hap.Service.TemperatureSensor)
92
- || this.accessory.addService(this.hap.Service.TemperatureSensor)), temperatureService;
93
- this.temperatureService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Temperature Sensor`);
94
- if (!this.temperatureService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
95
- this.temperatureService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Temperature Sensor`);
47
+ if (this.TemperatureSensor) {
48
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Temperature Sensor Service`);
49
+ this.TemperatureSensor.Service = this.accessory.getService(this.hap.Service.TemperatureSensor);
50
+ accessory.removeService(this.TemperatureSensor.Service);
96
51
  }
97
- this.temperatureService
52
+ }
53
+ else {
54
+ accessory.context.TemperatureSensor = accessory.context.TemperatureSensor ?? {};
55
+ this.TemperatureSensor = {
56
+ Name: accessory.context.TemperatureSensor.Name ?? `${accessory.displayName} Temperature Sensor`,
57
+ Service: accessory.getService(this.hap.Service.TemperatureSensor) ?? this.accessory.addService(this.hap.Service.TemperatureSensor),
58
+ CurrentTemperature: accessory.context.CurrentTemperature ?? 30,
59
+ };
60
+ accessory.context.TemperatureSensor = this.TemperatureSensor;
61
+ // Initialize Temperature Sensor Characteristics
62
+ this.TemperatureSensor.Service
63
+ .setCharacteristic(this.hap.Characteristic.Name, this.TemperatureSensor.Name)
98
64
  .getCharacteristic(this.hap.Characteristic.CurrentTemperature)
99
65
  .setProps({
100
66
  unit: "celsius" /* Units['CELSIUS'] */,
@@ -104,158 +70,111 @@ export class MeterPlus {
104
70
  minStep: 0.1,
105
71
  })
106
72
  .onGet(() => {
107
- return this.CurrentTemperature;
73
+ return this.TemperatureSensor.CurrentTemperature;
108
74
  });
109
75
  }
110
- else {
111
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Temperature Sensor Service Not Added`);
112
- }
113
- // Humidity Sensor Service
76
+ // Initialize Humidity Sensor Service
114
77
  if (device.meter?.hide_humidity) {
115
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Humidity Sensor Service`);
116
- this.humidityService = this.accessory.getService(this.hap.Service.HumiditySensor);
117
- accessory.removeService(this.humidityService);
118
- }
119
- else if (!this.humidityService) {
120
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Humidity Sensor Service`);
121
- const humidityService = `${accessory.displayName} Humidity Sensor`;
122
- (this.humidityService = this.accessory.getService(this.hap.Service.HumiditySensor)
123
- || this.accessory.addService(this.hap.Service.HumiditySensor)), humidityService;
124
- this.humidityService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Humidity Sensor`);
125
- if (!this.humidityService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
126
- this.humidityService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Humidity Sensor`);
78
+ if (this.HumiditySensor) {
79
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Humidity Sensor Service`);
80
+ this.HumiditySensor.Service = this.accessory.getService(this.hap.Service.HumiditySensor);
81
+ accessory.removeService(this.HumiditySensor.Service);
127
82
  }
128
- this.humidityService
83
+ }
84
+ else {
85
+ accessory.context.HumiditySensor = accessory.context.HumiditySensor ?? {};
86
+ this.HumiditySensor = {
87
+ Name: accessory.context.HumiditySensor.Name ?? `${accessory.displayName} Humidity Sensor`,
88
+ Service: accessory.getService(this.hap.Service.HumiditySensor) ?? this.accessory.addService(this.hap.Service.HumiditySensor),
89
+ CurrentRelativeHumidity: accessory.context.CurrentRelativeHumidity ?? 50,
90
+ };
91
+ accessory.context.HumiditySensor = this.HumiditySensor;
92
+ // Initialize Humidity Sensor Characteristics
93
+ this.HumiditySensor.Service
94
+ .setCharacteristic(this.hap.Characteristic.Name, this.HumiditySensor.Name)
129
95
  .getCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity)
130
96
  .setProps({
131
97
  minStep: 0.1,
132
98
  })
133
99
  .onGet(() => {
134
- return this.CurrentRelativeHumidity;
100
+ return this.HumiditySensor.CurrentRelativeHumidity;
135
101
  });
136
102
  }
137
- else {
138
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Humidity Sensor Service Not Added`);
139
- }
140
- // Battery Service
141
- const batteryService = `${accessory.displayName} Battery`;
142
- (this.batteryService = this.accessory.getService(this.hap.Service.Battery)
143
- || accessory.addService(this.hap.Service.Battery)), batteryService;
144
- this.batteryService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Battery`);
145
- if (!this.batteryService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
146
- this.batteryService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Battery`);
147
- }
148
- this.batteryService.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
103
+ // Retrieve initial values and updateHomekit
104
+ this.refreshStatus();
149
105
  // Retrieve initial values and updateHomekit
150
106
  this.updateHomeKitCharacteristics();
151
107
  // Start an update interval
152
108
  interval(this.deviceRefreshRate * 1000)
109
+ .pipe(skipWhile(() => this.meterUpdateInProgress))
153
110
  .subscribe(async () => {
154
111
  await this.refreshStatus();
155
112
  });
156
113
  //regisiter webhook event handler
157
- if (this.device.webhook) {
158
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
159
- this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
160
- try {
161
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
162
- if (context.scale === 'CELSIUS') {
163
- const { temperature, humidity } = context;
164
- const { CurrentTemperature, CurrentRelativeHumidity } = this;
165
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
166
- '(temperature, humidity) = ' +
167
- `Webhook:(${temperature}, ${humidity}), ` +
168
- `current:(${CurrentTemperature}, ${CurrentRelativeHumidity})`);
169
- this.CurrentRelativeHumidity = humidity;
170
- this.CurrentTemperature = temperature;
171
- this.updateHomeKitCharacteristics();
172
- }
173
- }
174
- catch (e) {
175
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
176
- + `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
177
- }
178
- };
179
- }
180
- }
181
- /**
182
- * Parse the device status from the SwitchBot api
183
- */
184
- async parseStatus() {
185
- if (!this.device.enableCloudService && this.OpenAPI) {
186
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
187
- }
188
- else if (this.BLE) {
189
- await this.BLEparseStatus();
190
- }
191
- else if (this.OpenAPI && this.platform.config.credentials?.token) {
192
- await this.openAPIparseStatus();
193
- }
194
- else {
195
- await this.offlineOff();
196
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`);
197
- }
114
+ this.registerWebhook(accessory, device);
198
115
  }
199
- async BLEparseStatus() {
116
+ async BLEparseStatus(serviceData) {
200
117
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
201
118
  // Battery
202
- this.BatteryLevel = Number(this.BLE_BatteryLevel);
203
- if (this.BatteryLevel < 15) {
204
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
119
+ this.Battery.BatteryLevel = Number(serviceData.battery);
120
+ if (this.Battery.BatteryLevel < 15) {
121
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
205
122
  }
206
123
  else {
207
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
124
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
208
125
  }
209
- this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
126
+ this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}, StatusLowBattery: ${this.Battery.StatusLowBattery}`);
210
127
  // Humidity
211
128
  if (!this.device.meter?.hide_humidity) {
212
- this.CurrentRelativeHumidity = this.BLE_CurrentRelativeHumidity;
213
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
129
+ this.HumiditySensor.CurrentRelativeHumidity = serviceData.humidity;
130
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
214
131
  }
215
132
  // Current Temperature
216
133
  if (!this.device.meter?.hide_temperature) {
217
- this.BLE_Celsius < 0 ? 0 : this.BLE_Celsius > 100 ? 100 : this.BLE_Celsius;
218
- this.CurrentTemperature = this.BLE_Celsius;
219
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
134
+ const celcius = serviceData.temperature.c < 0 ? 0 : serviceData.temperature.c > 100 ? 100 : serviceData.temperature.c;
135
+ this.TemperatureSensor.CurrentTemperature = celcius;
136
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.TemperatureSensor.CurrentTemperature}°c`);
220
137
  }
221
138
  }
222
- async openAPIparseStatus() {
139
+ async openAPIparseStatus(deviceStatus) {
223
140
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
224
141
  // BatteryLevel
225
- this.BatteryLevel = Number(this.OpenAPI_BatteryLevel);
226
- if (this.BatteryLevel < 15) {
227
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
142
+ this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
143
+ if (this.Battery.BatteryLevel < 10) {
144
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
228
145
  }
229
146
  else {
230
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
147
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
231
148
  }
232
- this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
149
+ if (Number.isNaN(this.Battery.BatteryLevel)) {
150
+ this.Battery.BatteryLevel = 100;
151
+ }
152
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
153
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
233
154
  // CurrentRelativeHumidity
234
155
  if (!this.device.meter?.hide_humidity) {
235
- this.CurrentRelativeHumidity = this.OpenAPI_CurrentRelativeHumidity;
236
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
156
+ this.HumiditySensor.CurrentRelativeHumidity = deviceStatus.body.humidity;
157
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
237
158
  }
238
159
  // CurrentTemperature
239
160
  if (!this.device.meter?.hide_temperature) {
240
- this.CurrentTemperature = this.OpenAPI_CurrentTemperature;
241
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
161
+ this.TemperatureSensor.CurrentTemperature = deviceStatus.body.temperature;
162
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.TemperatureSensor.CurrentTemperature}°c`);
163
+ }
164
+ // Firmware Version
165
+ const version = deviceStatus.body.version?.toString();
166
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
167
+ if (deviceStatus.body.version) {
168
+ const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
169
+ this.accessory
170
+ .getService(this.hap.Service.AccessoryInformation)
171
+ .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
172
+ .setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
173
+ .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
174
+ .updateValue(deviceVersion);
175
+ this.accessory.context.deviceVersion = deviceVersion;
176
+ this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
242
177
  }
243
- // Battery
244
- this.BatteryLevel = Number(this.OpenAPI_BatteryLevel);
245
- if (this.BatteryLevel < 10) {
246
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
247
- }
248
- else {
249
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
250
- }
251
- if (Number.isNaN(this.BatteryLevel)) {
252
- this.BatteryLevel = 100;
253
- }
254
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
255
- + ` StatusLowBattery: ${this.StatusLowBattery}`);
256
- // FirmwareRevision
257
- this.FirmwareRevision = this.OpenAPI_FirmwareRevision;
258
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
259
178
  }
260
179
  /**
261
180
  * Asks the SwitchBot API for the latest device information
@@ -272,135 +191,83 @@ export class MeterPlus {
272
191
  }
273
192
  else {
274
193
  await this.offlineOff();
275
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` +
276
- ` ${this.device.connectionType}, refreshStatus will not happen.`);
194
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
195
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
277
196
  }
278
197
  }
279
198
  async BLERefreshStatus() {
280
199
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
281
- const switchbot = await this.platform.connectBLE();
282
- // Convert to BLE Address
283
- this.device.bleMac = this.device
284
- .deviceId.match(/.{1,2}/g)
285
- .join(':')
286
- .toLowerCase();
287
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
288
- this.getCustomBLEAddress(switchbot);
289
- // Start to monitor advertisement packets
290
- (async () => {
291
- await switchbot.startScan({
292
- model: 'i',
293
- id: this.device.bleMac,
294
- });
295
- // Set an event handler
296
- switchbot.onadvertisement = (ad) => {
297
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
298
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.serviceData.model}`);
299
- if (this.device.bleMac === ad.address && ad.serviceData.model === 'i') {
300
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
301
- this.BLE_CurrentRelativeHumidity = ad.serviceData.humidity < 0 ? 0 : ad.serviceData.humidity > 100 ? 100 : ad.serviceData.humidity;
302
- this.BLE_CurrentTemperature = ad.serviceData.temperature;
303
- this.BLE_Celsius = ad.serviceData.temperature.c;
304
- this.BLE_Fahrenheit = ad.serviceData.temperature.f;
305
- this.BLE_BatteryLevel = ad.serviceData.battery;
200
+ const switchbot = await this.switchbotBLE();
201
+ if (switchbot === undefined) {
202
+ await this.BLERefreshConnection(switchbot);
203
+ }
204
+ else {
205
+ // Start to monitor advertisement packets
206
+ (async () => {
207
+ // Start to monitor advertisement packets
208
+ const serviceData = await this.monitorAdvertisementPackets(switchbot);
209
+ // Update HomeKit
210
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
211
+ await this.BLEparseStatus(serviceData);
212
+ await this.updateHomeKitCharacteristics();
306
213
  }
307
214
  else {
308
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
215
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
216
+ await this.BLERefreshConnection(switchbot);
309
217
  }
310
- };
311
- // Wait 1 seconds
312
- await switchbot.wait(this.scanDuration * 1000);
313
- // Stop to monitor
314
- await switchbot.stopScan();
315
- // Update HomeKit
316
- await this.BLEparseStatus();
317
- await this.updateHomeKitCharacteristics();
318
- })();
319
- /*if (switchbot !== false) {
320
- switchbot
321
- .startScan({
322
- model: 'i',
323
- id: this.device.bleMac,
324
- })
325
- .then(async () => {
326
- // Set an event handler
327
- switchbot.onadvertisement = async (ad: ad) => {
328
- this.debugLog(
329
- `${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
330
- ` BLE Address Found: ${ad.address}`,
331
- );
332
- if (ad.serviceData.humidity! > 0) {
333
- // reject unreliable data
334
- this.BLE_CurrentRelativeHumidity = ad.serviceData.humidity;
335
- }
336
- this.BLE_CurrentTemperature = ad.serviceData.temperature;
337
- this.BLE_Celsius = ad.serviceData.temperature!.c;
338
- this.BLE_Fahrenheit = ad.serviceData.temperature!.f;
339
- this.BLE_BatteryLevel = ad.serviceData.battery;
340
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
341
- this.debugLog(
342
- `${this.device.deviceType}: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, ` +
343
- `temperature: ${JSON.stringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, ` +
344
- `battery: ${ad.serviceData.battery}`,
345
- );
346
-
347
- if (ad.serviceData) {
348
- this.BLE_IsConnected = true;
349
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
350
- await this.stopScanning(switchbot);
351
- } else {
352
- this.BLE_IsConnected = false;
353
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
354
- }
355
- };
356
- // Wait
357
- return await sleep(this.scanDuration * 1000);
358
- })
359
- .then(async () => {
360
- // Stop to monitor
361
- await this.stopScanning(switchbot);
362
- })
363
- .catch(async (e: any) => {
364
- this.apiError(e);
365
- this.errorLog(
366
- `${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
367
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
368
- );
369
- await this.BLERefreshConnection(switchbot);
370
- });
371
- } else {
372
- await this.BLERefreshConnection(switchbot);
373
- }*/
218
+ })();
219
+ }
374
220
  }
375
221
  async openAPIRefreshStatus() {
376
222
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
377
223
  try {
378
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
379
- headers: this.platform.generateHeaders(),
380
- });
381
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
224
+ const { body, statusCode } = await this.deviceRefreshStatus();
382
225
  const deviceStatus = await body.json();
383
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
384
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
226
+ await this.refreshStatusCodes(statusCode, deviceStatus);
227
+ ;
385
228
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
386
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
387
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
388
- this.OpenAPI_CurrentRelativeHumidity = deviceStatus.body.humidity;
389
- this.OpenAPI_CurrentTemperature = deviceStatus.body.temperature;
390
- this.OpenAPI_BatteryLevel = deviceStatus.body.battery;
391
- this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
392
- this.openAPIparseStatus();
393
- this.updateHomeKitCharacteristics();
229
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
230
+ await this.openAPIparseStatus(deviceStatus);
231
+ await this.updateHomeKitCharacteristics();
394
232
  }
395
233
  else {
396
- this.statusCode(statusCode);
397
- this.statusCode(deviceStatus.statusCode);
234
+ await this.statusCodes(statusCode, deviceStatus);
398
235
  }
399
236
  }
400
237
  catch (e) {
401
238
  this.apiError(e);
402
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}` +
403
- ` Connection, Error Message: ${JSON.stringify(e.message)}`);
239
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
240
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
241
+ }
242
+ }
243
+ async registerWebhook(accessory, device) {
244
+ if (device.webhook) {
245
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
246
+ this.platform.webhookEventHandler[device.deviceId] = async (context) => {
247
+ try {
248
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
249
+ if (context.scale === 'CELSIUS') {
250
+ const { temperature, humidity } = context;
251
+ const { CurrentRelativeHumidity } = this.HumiditySensor ?? { CurrentRelativeHumidity: undefined };
252
+ const { CurrentTemperature } = this.TemperatureSensor ?? { CurrentTemperature: undefined };
253
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} (temperature, humidity) = Webhook:(${temperature}, ${humidity}), `
254
+ + `current:(${CurrentTemperature}, ${CurrentRelativeHumidity})`);
255
+ if (!device.meter?.hide_humidity) {
256
+ this.HumiditySensor.CurrentRelativeHumidity = humidity;
257
+ }
258
+ if (!device.meter?.hide_temperature) {
259
+ this.TemperatureSensor.CurrentTemperature = temperature;
260
+ }
261
+ this.updateHomeKitCharacteristics();
262
+ }
263
+ }
264
+ catch (e) {
265
+ this.errorLog(`${device.deviceType}: ${accessory.displayName} failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
266
+ }
267
+ };
268
+ }
269
+ else {
270
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
404
271
  }
405
272
  }
406
273
  /**
@@ -411,149 +278,78 @@ export class MeterPlus {
411
278
  const entry = { time: Math.round(new Date().valueOf() / 1000) };
412
279
  // CurrentRelativeHumidity
413
280
  if (!this.device.meter?.hide_humidity) {
414
- if (this.CurrentRelativeHumidity === undefined) {
415
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
281
+ if (this.HumiditySensor.CurrentRelativeHumidity === undefined) {
282
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
283
+ + ` CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}`);
416
284
  }
417
285
  else {
286
+ this.accessory.context.CurrentRelativeHumidity = this.HumiditySensor.CurrentRelativeHumidity;
287
+ this.HumiditySensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, this.HumiditySensor.CurrentRelativeHumidity);
288
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
289
+ + ` updateCharacteristic CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}`);
418
290
  if (this.device.mqttURL) {
419
- mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
291
+ mqttmessage.push(`"humidity": ${this.HumiditySensor.CurrentRelativeHumidity}`);
420
292
  }
421
293
  if (this.device.history) {
422
- entry['humidity'] = this.CurrentRelativeHumidity;
294
+ entry['humidity'] = this.HumiditySensor.CurrentRelativeHumidity;
423
295
  }
424
- this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidity;
425
- this.humidityService?.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
426
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}` +
427
- ` updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
428
296
  }
429
297
  }
430
298
  // CurrentTemperature
431
299
  if (!this.device.meter?.hide_temperature) {
432
- if (this.CurrentTemperature === undefined) {
433
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
300
+ if (this.TemperatureSensor.CurrentTemperature === undefined) {
301
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`);
434
302
  }
435
303
  else {
304
+ this.accessory.context.CurrentTemperature = this.TemperatureSensor.CurrentTemperature;
305
+ this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.TemperatureSensor.CurrentTemperature);
306
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
307
+ + ` CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`);
436
308
  if (this.device.mqttURL) {
437
- mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
309
+ mqttmessage.push(`"temperature": ${this.TemperatureSensor.CurrentTemperature}`);
438
310
  }
439
311
  if (this.device.history) {
440
- entry['temp'] = this.CurrentTemperature;
312
+ entry['temp'] = this.TemperatureSensor.CurrentTemperature;
441
313
  }
442
- this.accessory.context.CurrentTemperature = this.CurrentTemperature;
443
- this.temperatureService?.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.CurrentTemperature);
444
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
445
314
  }
446
315
  }
447
316
  // BatteryLevel
448
- if (this.BatteryLevel === undefined) {
449
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
317
+ if (this.Battery.BatteryLevel === undefined) {
318
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
450
319
  }
451
320
  else {
321
+ this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
322
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
323
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
452
324
  if (this.device.mqttURL) {
453
- mqttmessage.push(`"battery": ${this.BatteryLevel}`);
325
+ mqttmessage.push(`"battery": ${this.Battery.BatteryLevel}`);
454
326
  }
455
- this.accessory.context.BatteryLevel = this.BatteryLevel;
456
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.BatteryLevel);
457
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
458
327
  }
459
328
  // StatusLowBattery
460
- if (this.StatusLowBattery === undefined) {
461
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
329
+ if (this.Battery.StatusLowBattery === undefined) {
330
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
462
331
  }
463
332
  else {
333
+ this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
334
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
335
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
336
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
464
337
  if (this.device.mqttURL) {
465
- mqttmessage.push(`"lowBattery": ${this.StatusLowBattery}`);
338
+ mqttmessage.push(`"lowBattery": ${this.Battery.StatusLowBattery}`);
466
339
  }
467
- this.accessory.context.StatusLowBattery = this.StatusLowBattery;
468
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.StatusLowBattery);
469
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
470
340
  }
471
- // MQTT
341
+ // MQTT Publish
472
342
  if (this.device.mqttURL) {
473
343
  this.mqttPublish(`{${mqttmessage.join(',')}}`);
474
344
  }
475
- if (Number(this.CurrentRelativeHumidity) > 0) {
345
+ // History Service
346
+ if (!this.device.meter?.hide_humidity && (Number(this.HumiditySensor.CurrentRelativeHumidity) > 0)) {
476
347
  // reject unreliable data
477
348
  if (this.device.history) {
478
349
  this.historyService?.addEntry(entry);
479
350
  }
480
351
  }
481
352
  }
482
- /*
483
- * Publish MQTT message for topics of
484
- * 'homebridge-switchbot/meter/xx:xx:xx:xx:xx:xx'
485
- */
486
- mqttPublish(message) {
487
- const mac = this.device.deviceId
488
- ?.toLowerCase()
489
- .match(/[\s\S]{1,2}/g)
490
- ?.join(':');
491
- const options = this.device.mqttPubOptions || {};
492
- this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
493
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
494
- }
495
- /*
496
- * Setup MQTT hadler if URL is specified.
497
- */
498
- async setupMqtt(device) {
499
- if (device.mqttURL) {
500
- try {
501
- const { connectAsync } = asyncmqtt;
502
- this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
503
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT connection has been established successfully.`);
504
- this.mqttClient.on('error', (e) => {
505
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
506
- });
507
- }
508
- catch (e) {
509
- this.mqttClient = null;
510
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
511
- }
512
- }
513
- }
514
- /*
515
- * Setup EVE history graph feature if enabled.
516
- */
517
- async setupHistoryService(device) {
518
- const mac = this.device
519
- .deviceId.match(/.{1,2}/g)
520
- .join(':')
521
- .toLowerCase();
522
- this.historyService = device.history
523
- ? new this.platform.fakegatoAPI('room', this.accessory, {
524
- log: this.platform.log,
525
- storage: 'fs',
526
- filename: `${hostname().split('.')[0]}_${mac}_persist.json`,
527
- })
528
- : null;
529
- }
530
- async stopScanning(switchbot) {
531
- switchbot.stopScan();
532
- if (this.BLE_IsConnected) {
533
- await this.BLEparseStatus();
534
- await this.updateHomeKitCharacteristics();
535
- }
536
- else {
537
- await this.BLERefreshConnection(switchbot);
538
- }
539
- }
540
- async getCustomBLEAddress(switchbot) {
541
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
542
- (async () => {
543
- // Start to monitor advertisement packets
544
- await switchbot.startScan({
545
- model: 'i',
546
- });
547
- // Set an event handler
548
- switchbot.onadvertisement = (ad) => {
549
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
550
- };
551
- await sleep(10000);
552
- // Stop to monitor
553
- switchbot.stopScan();
554
- })();
555
- }
556
- }
557
353
  async BLERefreshConnection(switchbot) {
558
354
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
559
355
  + ` ${JSON.stringify(switchbot)}`);
@@ -562,250 +358,26 @@ export class MeterPlus {
562
358
  await this.openAPIRefreshStatus();
563
359
  }
564
360
  }
565
- model(device) {
566
- let model;
567
- if (device.deviceType === 'Meter Plus (JP)') {
568
- model = 'W2201500';
569
- }
570
- else {
571
- model = 'W2301500';
572
- }
573
- return model;
574
- }
575
- async scan(device) {
576
- if (device.scanDuration) {
577
- this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
578
- if (this.BLE) {
579
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
580
- }
581
- }
582
- else {
583
- this.scanDuration = this.accessory.context.scanDuration = 1;
584
- if (this.BLE) {
585
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
586
- }
587
- }
588
- }
589
- async statusCode(statusCode) {
590
- switch (statusCode) {
591
- case 151:
592
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
593
- break;
594
- case 152:
595
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
596
- break;
597
- case 160:
598
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
599
- break;
600
- case 161:
601
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
602
- this.offlineOff();
603
- break;
604
- case 171:
605
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
606
- `Hub: ${this.device.hubDeviceId}`);
607
- this.offlineOff();
608
- break;
609
- case 190:
610
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
611
- ` Or command format is invalid, statusCode: ${statusCode}`);
612
- break;
613
- case 100:
614
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
615
- break;
616
- case 200:
617
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
618
- break;
619
- case 400:
620
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
621
- + `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
622
- break;
623
- case 401:
624
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
625
- + `but the request has not been authenticated, statusCode: ${statusCode}`);
626
- break;
627
- case 403:
628
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
629
- + `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
630
- break;
631
- case 404:
632
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
633
- + `statusCode: ${statusCode}`);
634
- break;
635
- case 406:
636
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
637
- + `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
638
- break;
639
- case 415:
640
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
641
- + `header that is not supported by the server, statusCode: ${statusCode}`);
642
- break;
643
- case 422:
644
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
645
- + `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
646
- break;
647
- case 429:
648
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
649
- + `requests allowed for a given time window, statusCode: ${statusCode}`);
650
- break;
651
- case 500:
652
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
653
- + `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
654
- break;
655
- default:
656
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
657
- `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
658
- }
659
- }
660
361
  async offlineOff() {
661
362
  if (this.device.offline) {
662
- await this.deviceContext();
663
- await this.updateHomeKitCharacteristics();
363
+ if (!this.device.meter?.hide_humidity) {
364
+ this.HumiditySensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, 50);
365
+ }
366
+ if (!this.device.meter?.hide_temperature) {
367
+ this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, 30);
368
+ }
369
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, 100);
664
370
  }
665
371
  }
666
372
  async apiError(e) {
667
373
  if (!this.device.meter?.hide_humidity) {
668
- this.humidityService?.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, e);
374
+ this.HumiditySensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, e);
669
375
  }
670
376
  if (!this.device.meter?.hide_temperature) {
671
- this.temperatureService?.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e);
672
- }
673
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
674
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
675
- }
676
- async deviceContext() {
677
- if (this.CurrentRelativeHumidity === undefined) {
678
- this.CurrentRelativeHumidity = 0;
679
- }
680
- else {
681
- this.CurrentRelativeHumidity = this.accessory.context.CurrentRelativeHumidity;
682
- }
683
- if (this.CurrentTemperature === undefined) {
684
- this.CurrentTemperature = 0;
685
- }
686
- else {
687
- this.CurrentTemperature = this.accessory.context.CurrentTemperature;
688
- }
689
- if (this.BatteryLevel === undefined) {
690
- this.BatteryLevel = 100;
691
- }
692
- else {
693
- this.BatteryLevel = this.accessory.context.BatteryLevel;
694
- }
695
- if (this.StatusLowBattery === undefined) {
696
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
697
- this.accessory.context.StatusLowBattery = this.StatusLowBattery;
698
- }
699
- else {
700
- this.StatusLowBattery = this.accessory.context.StatusLowBattery;
377
+ this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e);
701
378
  }
702
- if (this.FirmwareRevision === undefined) {
703
- this.FirmwareRevision = this.platform.version;
704
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
705
- }
706
- }
707
- async refreshRate(device) {
708
- if (device.refreshRate) {
709
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
710
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
711
- }
712
- else if (this.platform.config.options.refreshRate) {
713
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
714
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
715
- }
716
- }
717
- async deviceConfig(device) {
718
- let config = {};
719
- if (device.meter) {
720
- config = device.meter;
721
- }
722
- if (device.connectionType !== undefined) {
723
- config['connectionType'] = device.connectionType;
724
- }
725
- if (device.external !== undefined) {
726
- config['external'] = device.external;
727
- }
728
- if (device.mqttURL !== undefined) {
729
- config['mqttURL'] = device.mqttURL;
730
- }
731
- if (device.logging !== undefined) {
732
- config['logging'] = device.logging;
733
- }
734
- if (device.refreshRate !== undefined) {
735
- config['refreshRate'] = device.refreshRate;
736
- }
737
- if (device.scanDuration !== undefined) {
738
- config['scanDuration'] = device.scanDuration;
739
- }
740
- if (device.webhook !== undefined) {
741
- config['webhook'] = device.webhook;
742
- }
743
- if (Object.entries(config).length !== 0) {
744
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
745
- }
746
- }
747
- async deviceLogs(device) {
748
- if (this.platform.debugMode) {
749
- this.deviceLogging = this.accessory.context.logging = 'debugMode';
750
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
751
- }
752
- else if (device.logging) {
753
- this.deviceLogging = this.accessory.context.logging = device.logging;
754
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
755
- }
756
- else if (this.platform.config.options?.logging) {
757
- this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
758
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
759
- }
760
- else {
761
- this.deviceLogging = this.accessory.context.logging = 'standard';
762
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
763
- }
764
- }
765
- /**
766
- * Logging for Device
767
- */
768
- infoLog(...log) {
769
- if (this.enablingDeviceLogging()) {
770
- this.platform.log.info(String(...log));
771
- }
772
- }
773
- warnLog(...log) {
774
- if (this.enablingDeviceLogging()) {
775
- this.platform.log.warn(String(...log));
776
- }
777
- }
778
- debugWarnLog(...log) {
779
- if (this.enablingDeviceLogging()) {
780
- if (this.deviceLogging?.includes('debug')) {
781
- this.platform.log.warn('[DEBUG]', String(...log));
782
- }
783
- }
784
- }
785
- errorLog(...log) {
786
- if (this.enablingDeviceLogging()) {
787
- this.platform.log.error(String(...log));
788
- }
789
- }
790
- debugErrorLog(...log) {
791
- if (this.enablingDeviceLogging()) {
792
- if (this.deviceLogging?.includes('debug')) {
793
- this.platform.log.error('[DEBUG]', String(...log));
794
- }
795
- }
796
- }
797
- debugLog(...log) {
798
- if (this.enablingDeviceLogging()) {
799
- if (this.deviceLogging === 'debug') {
800
- this.platform.log.info('[DEBUG]', String(...log));
801
- }
802
- else {
803
- this.platform.log.debug(String(...log));
804
- }
805
- }
806
- }
807
- enablingDeviceLogging() {
808
- return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
379
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
380
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
809
381
  }
810
382
  }
811
383
  //# sourceMappingURL=meterplus.js.map