@switchbot/homebridge-switchbot 4.0.1-beta.5 → 4.1.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.
@@ -1,6 +1,6 @@
1
1
  import type { IClientOptions } from 'async-mqtt';
2
2
  import type { PlatformConfig } from 'homebridge';
3
- import type { device, irdevice, SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName } from 'node-switchbot';
3
+ import type { device, irdevice, SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName, SwitchBotModel } from 'node-switchbot';
4
4
  /**
5
5
  * This is the name of the platform that users will use to register the plugin in the Homebridge config.json
6
6
  */
@@ -49,7 +49,7 @@ export interface options {
49
49
  export type devicesConfig = botConfig | meterConfig | indoorOutdoorSensorConfig | humidifierConfig | curtainConfig | blindTiltConfig | contactConfig | motionConfig | waterDetectorConfig | plugConfig | colorBulbConfig | stripLightConfig | ceilingLightConfig | lockConfig | hubConfig;
50
50
  export interface BaseDeviceConfig extends device {
51
51
  bleMac?: string;
52
- model: string;
52
+ model: SwitchBotModel;
53
53
  bleModel: SwitchBotBLEModel;
54
54
  bleModelName: SwitchBotBLEModelName;
55
55
  bleModelFriednlyName: SwitchBotBLEModelFriendlyName;
@@ -87,7 +87,7 @@ export interface botConfig extends BaseDeviceConfig {
87
87
  multiPress?: boolean;
88
88
  }
89
89
  export interface meterConfig extends BaseDeviceConfig {
90
- configDeviceType: 'Meter' | 'MeterPlus';
90
+ configDeviceType: 'Meter' | 'MeterPlus' | 'Meter Pro' | 'Meter Pro CO2';
91
91
  hide_temperature?: boolean;
92
92
  convertUnitTo?: string;
93
93
  hide_humidity?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@switchbot/homebridge-switchbot",
3
3
  "displayName": "SwitchBot",
4
4
  "type": "module",
5
- "version": "4.0.1-beta.5",
5
+ "version": "4.1.1-beta.0",
6
6
  "description": "The SwitchBot plugin allows you to access your SwitchBot device(s) from HomeKit.",
7
7
  "author": "SwitchBot <support@wondertechlabs.com> (https://github.com/SwitchBot)",
8
8
  "contributors": [
@@ -81,7 +81,7 @@
81
81
  "async-mqtt": "^2.6.3",
82
82
  "fakegato-history": "^0.6.5",
83
83
  "homebridge-lib": "^7.0.9",
84
- "node-switchbot": "^3.1.2-beta.5",
84
+ "node-switchbot": "^3.2.2-beta.0",
85
85
  "rxjs": "^7.8.1"
86
86
  },
87
87
  "devDependencies": {
@@ -90,7 +90,7 @@
90
90
  "@types/debug": "^4.1.12",
91
91
  "@types/fs-extra": "^11.0.4",
92
92
  "@types/mdast": "^4.0.4",
93
- "@types/node": "^22.7.7",
93
+ "@types/node": "^22.7.8",
94
94
  "@types/semver": "^7.5.8",
95
95
  "@types/source-map-support": "^0.5.10",
96
96
  "@vitest/coverage-v8": "^2.1.3",
package/src/device/bot.ts CHANGED
@@ -498,7 +498,7 @@ export class Bot extends deviceBase {
498
498
  await this.debugLog(`Bot Mode: ${this.botMode}`)
499
499
  if (this.botMode === 'press') {
500
500
  switchBotBLE
501
- .discover({ model: 'H', quick: true, id: this.device.bleMac })
501
+ .discover({ model: this.device.bleModel, quick: true, id: this.device.bleMac })
502
502
  .then(async (device_list: SwitchbotDevice[]) => {
503
503
  const deviceList = device_list as unknown as WoHand[]
504
504
  await this.infoLog(`On: ${this.On}`)
@@ -343,9 +343,6 @@ export abstract class deviceBase {
343
343
  this.debugLog(`address: ${ad.address}, model: ${ad.serviceData.model}`)
344
344
  this.debugLog(`serviceData: ${JSON.stringify(ad.serviceData)}`)
345
345
  serviceData = ad.serviceData
346
- } else {
347
- serviceData = { model: '', modelName: '', modelFriendlyName: '' } as unknown as ad['serviceData']
348
- this.debugLog(`serviceData: ${JSON.stringify(ad.serviceData)}`)
349
346
  }
350
347
  }
351
348
  // Wait
@@ -481,6 +478,18 @@ export abstract class deviceBase {
481
478
  bleModelName: SwitchBotBLEModelName.MeterPlus,
482
479
  bleModelFriendlyName: SwitchBotBLEModelFriendlyName.MeterPlus,
483
480
  },
481
+ 'Meter Pro': {
482
+ model: SwitchBotModel.MeterPro,
483
+ bleModel: SwitchBotBLEModel.MeterPro,
484
+ bleModelName: SwitchBotBLEModelName.MeterPro,
485
+ bleModelFriendlyName: SwitchBotBLEModelFriendlyName.MeterPro,
486
+ },
487
+ 'Meter Pro CO2': {
488
+ model: SwitchBotModel.MeterProCO2,
489
+ bleModel: SwitchBotBLEModel.MeterPro,
490
+ bleModelName: SwitchBotBLEModelName.MeterPro,
491
+ bleModelFriendlyName: SwitchBotBLEModelFriendlyName.MeterPro,
492
+ },
484
493
  'WoIOSensor': {
485
494
  model: SwitchBotModel.OutdoorMeter,
486
495
  bleModel: SwitchBotBLEModel.OutdoorMeter,
@@ -0,0 +1,417 @@
1
+ /* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
+ *
3
+ * MeterPro.ts: @switchbot/homebridge-switchbot.
4
+ */
5
+ import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
+ import type { device, meterProServiceData, meterProStatus, meterProWebhookContext } from 'node-switchbot'
7
+
8
+ import type { SwitchBotPlatform } from '../platform.js'
9
+ import type { devicesConfig, meterConfig } from '../settings.js'
10
+
11
+ import { Units } from 'homebridge'
12
+ /*
13
+ * For Testing Locally:
14
+ * import { SwitchBotBLEModel, SwitchBotBLEModelName } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
15
+ */
16
+ import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot'
17
+ import { interval, skipWhile, Subject } from 'rxjs'
18
+
19
+ import { convertUnits, formatDeviceIdAsMac, validHumidity } from '../utils.js'
20
+ import { deviceBase } from './device.js'
21
+
22
+ /**
23
+ * Platform Accessory
24
+ * An instance of this class is created for each accessory your platform registers
25
+ * Each accessory may expose multiple services of different service types.
26
+ */
27
+ export class MeterPro extends deviceBase {
28
+ // Services
29
+ private Battery: {
30
+ Name: CharacteristicValue
31
+ Service: Service
32
+ BatteryLevel: CharacteristicValue
33
+ StatusLowBattery: CharacteristicValue
34
+ }
35
+
36
+ private HumiditySensor?: {
37
+ Name: CharacteristicValue
38
+ Service: Service
39
+ CurrentRelativeHumidity: CharacteristicValue
40
+ }
41
+
42
+ private TemperatureSensor?: {
43
+ Name: CharacteristicValue
44
+ Service: Service
45
+ CurrentTemperature: CharacteristicValue
46
+ }
47
+
48
+ // OpenAPI
49
+ deviceStatus!: meterProStatus
50
+
51
+ // Webhook
52
+ webhookContext!: meterProWebhookContext
53
+
54
+ // BLE
55
+ serviceData!: meterProServiceData
56
+
57
+ // Updates
58
+ meterUpdateInProgress!: boolean
59
+ doMeterUpdate: Subject<void>
60
+
61
+ constructor(
62
+ readonly platform: SwitchBotPlatform,
63
+ accessory: PlatformAccessory,
64
+ device: device & devicesConfig,
65
+ ) {
66
+ super(platform, accessory, device)
67
+ // Set category
68
+ accessory.category = this.hap.Categories.SENSOR
69
+
70
+ // this is subject we use to track when we need to POST changes to the SwitchBot API
71
+ this.doMeterUpdate = new Subject()
72
+ this.meterUpdateInProgress = false
73
+
74
+ // Initialize Battery Service
75
+ accessory.context.Battery = accessory.context.Battery ?? {}
76
+ this.Battery = {
77
+ Name: `${accessory.displayName} Battery`,
78
+ Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
79
+ BatteryLevel: accessory.context.BatteryLevel ?? 100,
80
+ StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
81
+ }
82
+ accessory.context.Battery = this.Battery as object
83
+
84
+ // Initialize Battery Characteristics
85
+ this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name).setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE).getCharacteristic(this.hap.Characteristic.BatteryLevel).onGet(() => {
86
+ return this.Battery.BatteryLevel
87
+ })
88
+
89
+ this.Battery.Service.getCharacteristic(this.hap.Characteristic.StatusLowBattery).onGet(() => {
90
+ return this.Battery.StatusLowBattery
91
+ })
92
+
93
+ // Initialize Temperature Sensor Service
94
+ if ((device as meterConfig).hide_temperature) {
95
+ if (this.TemperatureSensor) {
96
+ this.debugLog('Removing Temperature Sensor Service')
97
+ this.TemperatureSensor.Service = this.accessory.getService(this.hap.Service.TemperatureSensor) as Service
98
+ accessory.removeService(this.TemperatureSensor.Service)
99
+ }
100
+ } else {
101
+ accessory.context.TemperatureSensor = accessory.context.TemperatureSensor ?? {}
102
+ this.TemperatureSensor = {
103
+ Name: `${accessory.displayName} Temperature Sensor`,
104
+ Service: accessory.getService(this.hap.Service.TemperatureSensor) ?? this.accessory.addService(this.hap.Service.TemperatureSensor) as Service,
105
+ CurrentTemperature: accessory.context.CurrentTemperature ?? 30,
106
+ }
107
+ accessory.context.TemperatureSensor = this.TemperatureSensor as object
108
+
109
+ // Initialize Temperature Sensor Characteristics
110
+ this.TemperatureSensor.Service.setCharacteristic(this.hap.Characteristic.Name, this.TemperatureSensor.Name).getCharacteristic(this.hap.Characteristic.CurrentTemperature).setProps({
111
+ unit: Units.CELSIUS,
112
+ validValueRanges: [-273.15, 100],
113
+ minValue: -273.15,
114
+ maxValue: 100,
115
+ minStep: 0.1,
116
+ }).onGet(() => {
117
+ return this.TemperatureSensor!.CurrentTemperature!
118
+ })
119
+ }
120
+ // Initialize Humidity Sensor Service
121
+ if ((device as meterConfig).hide_humidity) {
122
+ if (this.HumiditySensor) {
123
+ this.debugLog('Removing Humidity Sensor Service')
124
+ this.HumiditySensor.Service = this.accessory.getService(this.hap.Service.HumiditySensor) as Service
125
+ accessory.removeService(this.HumiditySensor.Service)
126
+ }
127
+ } else {
128
+ accessory.context.HumiditySensor = accessory.context.HumiditySensor ?? {}
129
+ this.HumiditySensor = {
130
+ Name: `${accessory.displayName} Humidity Sensor`,
131
+ Service: accessory.getService(this.hap.Service.HumiditySensor) ?? this.accessory.addService(this.hap.Service.HumiditySensor) as Service,
132
+ CurrentRelativeHumidity: accessory.context.CurrentRelativeHumidity ?? 50,
133
+ }
134
+ accessory.context.HumiditySensor = this.HumiditySensor as object
135
+
136
+ // Initialize Humidity Sensor Characteristics
137
+ this.HumiditySensor.Service.setCharacteristic(this.hap.Characteristic.Name, this.HumiditySensor.Name).getCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity).setProps({
138
+ minStep: 0.1,
139
+ }).onGet(() => {
140
+ return this.HumiditySensor!.CurrentRelativeHumidity!
141
+ })
142
+ }
143
+
144
+ // Retrieve initial values and updateHomekit
145
+ try {
146
+ this.debugLog('Retrieve initial values and update Homekit')
147
+ this.refreshStatus()
148
+ } catch (e: any) {
149
+ this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e.message ?? e}`)
150
+ }
151
+
152
+ // regisiter webhook event handler if enabled
153
+ try {
154
+ this.debugLog('Registering Webhook Event Handler')
155
+ this.registerWebhook()
156
+ } catch (e: any) {
157
+ this.errorLog(`failed to registerWebhook, Error: ${e.message ?? e}`)
158
+ }
159
+
160
+ // regisiter platform BLE event handler if enabled
161
+ try {
162
+ this.debugLog('Registering Platform BLE Event Handler')
163
+ this.registerPlatformBLE()
164
+ } catch (e: any) {
165
+ this.errorLog(`failed to registerPlatformBLE, Error: ${e.message ?? e}`)
166
+ }
167
+
168
+ // Start an update interval
169
+ interval(this.deviceRefreshRate * 1000)
170
+ .pipe(skipWhile(() => this.meterUpdateInProgress))
171
+ .subscribe(async () => {
172
+ await this.refreshStatus()
173
+ })
174
+ }
175
+
176
+ async BLEparseStatus(): Promise<void> {
177
+ await this.debugLog('BLEparseStatus')
178
+ await this.debugLog(`(temperature, humidity) = BLE:(${this.serviceData.celsius}, ${this.serviceData.humidity}), current:(${this.TemperatureSensor?.CurrentTemperature}, ${this.HumiditySensor?.CurrentRelativeHumidity})`)
179
+
180
+ // CurrentRelativeHumidity
181
+ if (!(this.device as meterConfig).hide_humidity && this.HumiditySensor?.Service) {
182
+ this.HumiditySensor.CurrentRelativeHumidity = validHumidity(this.serviceData.humidity, 0, 100)
183
+ await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`)
184
+ }
185
+ // Current Temperature
186
+ if (!(this.device as meterConfig).hide_temperature && this.TemperatureSensor?.Service) {
187
+ const CELSIUS = this.serviceData.celsius < 0 ? 0 : this.serviceData.celsius > 100 ? 100 : this.serviceData.celsius
188
+ this.TemperatureSensor.CurrentTemperature = CELSIUS
189
+ await this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}°c`)
190
+ }
191
+ // BatteryLevel
192
+ this.Battery.BatteryLevel = this.serviceData.battery
193
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
194
+ // StatusLowBattery
195
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
196
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
197
+ : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
198
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
199
+ }
200
+
201
+ async openAPIparseStatus(): Promise<void> {
202
+ await this.debugLog('openAPIparseStatus')
203
+ await this.debugLog(`(temperature, humidity) = OpenAPI:(${this.deviceStatus.temperature}, ${this.deviceStatus.humidity}), current:(${this.TemperatureSensor?.CurrentTemperature}, ${this.HumiditySensor?.CurrentRelativeHumidity})`)
204
+
205
+ // CurrentRelativeHumidity
206
+ if (!(this.device as meterConfig).hide_humidity && this.HumiditySensor?.Service) {
207
+ this.HumiditySensor.CurrentRelativeHumidity = this.deviceStatus.humidity
208
+ await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`)
209
+ }
210
+
211
+ // CurrentTemperature
212
+ if (!(this.device as meterConfig).hide_temperature && this.TemperatureSensor?.Service) {
213
+ this.TemperatureSensor.CurrentTemperature = this.deviceStatus.temperature
214
+ await this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}°c`)
215
+ }
216
+
217
+ // BatteryLevel
218
+ this.Battery.BatteryLevel = this.deviceStatus.battery
219
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
220
+
221
+ // StatusLowBattery
222
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
223
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
224
+ : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
225
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
226
+
227
+ // FirmwareVersion
228
+ if (this.deviceStatus.version) {
229
+ const version = this.deviceStatus.version.toString()
230
+ this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`)
231
+ const deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0'
232
+ this.accessory
233
+ .getService(this.hap.Service.AccessoryInformation)!
234
+ .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
235
+ .setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
236
+ .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
237
+ .updateValue(deviceVersion)
238
+ this.accessory.context.version = deviceVersion
239
+ this.debugSuccessLog(`v: ${this.accessory.context.version}`)
240
+ }
241
+ }
242
+
243
+ async parseStatusWebhook(): Promise<void> {
244
+ await this.debugLog('parseStatusWebhook')
245
+ await this.debugLog(`(scale, temperature, humidity) = Webhook:(${this.webhookContext.scale}, ${convertUnits(this.webhookContext.temperature, this.webhookContext.scale, (this.device as meterConfig).convertUnitTo)}, ${this.webhookContext.humidity}) current:(${this.TemperatureSensor?.CurrentTemperature}, ${this.HumiditySensor?.CurrentRelativeHumidity})`)
246
+ // Check if the scale is not CELSIUS
247
+ if (this.webhookContext.scale !== 'CELSIUS' && (this.device as meterConfig).convertUnitTo === undefined) {
248
+ await this.warnLog(`received a non-CELSIUS Webhook scale: ${this.webhookContext.scale}, Use the *convertUnitsTo* config under Hub settings, if displaying incorrectly in HomeKit.`)
249
+ }
250
+
251
+ // CurrentRelativeHumidity
252
+ if (!(this.device as meterConfig).hide_humidity && this.HumiditySensor?.Service) {
253
+ this.HumiditySensor.CurrentRelativeHumidity = this.webhookContext.humidity
254
+ await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}`)
255
+ }
256
+
257
+ // CurrentTemperature
258
+ if (!(this.device as meterConfig).hide_temperature && this.TemperatureSensor?.Service) {
259
+ this.TemperatureSensor.CurrentTemperature = convertUnits(this.webhookContext.temperature, this.webhookContext.scale, (this.device as meterConfig).convertUnitTo)
260
+ await this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`)
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Asks the SwitchBot API for the latest device information
266
+ */
267
+ async refreshStatus(): Promise<void> {
268
+ if (!this.device.enableCloudService && this.OpenAPI) {
269
+ await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`)
270
+ } else if (this.BLE) {
271
+ await this.BLERefreshStatus()
272
+ } else if (this.OpenAPI && this.platform.config.credentials?.token) {
273
+ await this.openAPIRefreshStatus()
274
+ } else {
275
+ await this.offlineOff()
276
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`)
277
+ }
278
+ }
279
+
280
+ async BLERefreshStatus(): Promise<void> {
281
+ await this.debugLog('BLERefreshStatus')
282
+ const switchBotBLE = await this.switchbotBLE()
283
+ if (switchBotBLE === undefined) {
284
+ await this.BLERefreshConnection(switchBotBLE)
285
+ } else {
286
+ // Start to monitor advertisement packets
287
+ (async () => {
288
+ // Start to monitor advertisement packets
289
+ const serviceData = await this.monitorAdvertisementPackets(switchBotBLE) as meterProServiceData
290
+ // Update HomeKit
291
+ if (serviceData.model === SwitchBotBLEModel.MeterPro && serviceData.modelName === SwitchBotBLEModelName.MeterPro) {
292
+ this.serviceData = serviceData
293
+ await this.BLEparseStatus()
294
+ await this.updateHomeKitCharacteristics()
295
+ } else {
296
+ await this.errorLog(`failed to get serviceData, serviceData: ${JSON.stringify(serviceData)}`)
297
+ await this.BLERefreshConnection(switchBotBLE)
298
+ }
299
+ })()
300
+ }
301
+ }
302
+
303
+ async registerPlatformBLE(): Promise<void> {
304
+ await this.debugLog('registerPlatformBLE')
305
+ if (this.config.options?.BLE) {
306
+ await this.debugLog('is listening to Platform BLE.')
307
+ try {
308
+ const formattedDeviceId = formatDeviceIdAsMac(this.device.deviceId)
309
+ this.device.bleMac = formattedDeviceId
310
+ await this.debugLog(`bleMac: ${this.device.bleMac}`)
311
+ this.platform.bleEventHandler[this.device.bleMac] = async (context: meterProServiceData) => {
312
+ try {
313
+ await this.debugLog(`received BLE: ${JSON.stringify(context)}`)
314
+ this.serviceData = context
315
+ await this.BLEparseStatus()
316
+ await this.updateHomeKitCharacteristics()
317
+ } catch (e: any) {
318
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e.message ?? e}`)
319
+ }
320
+ }
321
+ } catch (error) {
322
+ await this.errorLog(`failed to format device ID as MAC, Error: ${error}`)
323
+ }
324
+ } else {
325
+ await this.debugLog('is not listening to Platform BLE')
326
+ }
327
+ }
328
+
329
+ async openAPIRefreshStatus(): Promise<void> {
330
+ await this.debugLog('openAPIRefreshStatus')
331
+ try {
332
+ const { body } = await this.deviceRefreshStatus()
333
+ const deviceStatus: any = await body
334
+ await this.debugLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
335
+ if (await this.successfulStatusCodes(deviceStatus)) {
336
+ await this.debugSuccessLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
337
+ this.deviceStatus = deviceStatus.body
338
+ await this.openAPIparseStatus()
339
+ await this.updateHomeKitCharacteristics()
340
+ } else {
341
+ await this.debugWarnLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
342
+ await this.debugWarnLog(deviceStatus)
343
+ }
344
+ } catch (e: any) {
345
+ await this.apiError(e)
346
+ await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
347
+ }
348
+ }
349
+
350
+ async registerWebhook() {
351
+ if (this.device.webhook) {
352
+ await this.debugLog('is listening webhook.')
353
+ this.platform.webhookEventHandler[this.device.deviceId] = async (context: meterProWebhookContext) => {
354
+ try {
355
+ await this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
356
+ this.webhookContext = context
357
+ await this.parseStatusWebhook()
358
+ await this.updateHomeKitCharacteristics()
359
+ } catch (e: any) {
360
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e.message ?? e}`)
361
+ }
362
+ }
363
+ } else {
364
+ await this.debugLog('is not listening webhook.')
365
+ }
366
+ }
367
+
368
+ /**
369
+ * Updates the status for each of the HomeKit Characteristics
370
+ */
371
+ async updateHomeKitCharacteristics(): Promise<void> {
372
+ // CurrentRelativeHumidity
373
+ if (!(this.device as meterConfig).hide_humidity && this.HumiditySensor?.Service) {
374
+ await this.updateCharacteristic(this.HumiditySensor.Service, this.hap.Characteristic.CurrentRelativeHumidity, this.HumiditySensor.CurrentRelativeHumidity, 'CurrentRelativeHumidity')
375
+ }
376
+ // CurrentTemperature
377
+ if (!(this.device as meterConfig).hide_temperature && this.TemperatureSensor?.Service) {
378
+ await this.updateCharacteristic(this.TemperatureSensor.Service, this.hap.Characteristic.CurrentTemperature, this.TemperatureSensor.CurrentTemperature, 'CurrentTemperature')
379
+ }
380
+ // BatteryLevel
381
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel, 'BatteryLevel')
382
+ // StatusLowBattery
383
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery, 'StatusLowBattery')
384
+ }
385
+
386
+ async BLERefreshConnection(switchbot: any): Promise<void> {
387
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
388
+ if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
389
+ await this.warnLog('Using OpenAPI Connection to Refresh Status')
390
+ await this.openAPIRefreshStatus()
391
+ }
392
+ }
393
+
394
+ async offlineOff(): Promise<void> {
395
+ if (this.device.offline) {
396
+ if (!(this.device as meterConfig).hide_humidity && this.HumiditySensor?.Service) {
397
+ this.HumiditySensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, 50)
398
+ }
399
+ if (!(this.device as meterConfig).hide_temperature && this.TemperatureSensor?.Service) {
400
+ this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, 30)
401
+ }
402
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, 100)
403
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL)
404
+ }
405
+ }
406
+
407
+ async apiError(e: any): Promise<void> {
408
+ if (!(this.device as meterConfig).hide_humidity && this.HumiditySensor?.Service) {
409
+ this.HumiditySensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, e)
410
+ }
411
+ if (!(this.device as meterConfig).hide_temperature && this.TemperatureSensor?.Service) {
412
+ this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e)
413
+ }
414
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e)
415
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e)
416
+ }
417
+ }
package/src/platform.ts CHANGED
@@ -39,6 +39,7 @@ import { StripLight } from './device/lightstrip.js'
39
39
  import { Lock } from './device/lock.js'
40
40
  import { Meter } from './device/meter.js'
41
41
  import { MeterPlus } from './device/meterplus.js'
42
+ import { MeterPro } from './device/meterpro.js'
42
43
  import { Motion } from './device/motion.js'
43
44
  import { Plug } from './device/plug.js'
44
45
  import { RobotVacuumCleaner } from './device/robotvacuumcleaner.js'
@@ -630,6 +631,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
630
631
  'Meter': this.createMeter.bind(this),
631
632
  'MeterPlus': this.createMeterPlus.bind(this),
632
633
  'Meter Plus (JP)': this.createMeterPlus.bind(this),
634
+ 'Meter Pro': this.createMeterPro.bind(this),
633
635
  'WoIOSensor': this.createIOSensor.bind(this),
634
636
  'Water Detector': this.createWaterDetector.bind(this),
635
637
  'Motion Sensor': this.createMotion.bind(this),
@@ -960,6 +962,69 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
960
962
  }
961
963
  }
962
964
 
965
+ private async createMeterPro(device: device & devicesConfig) {
966
+ const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
967
+
968
+ // see if an accessory with the same uuid has already been registered and restored from
969
+ // the cached devices we stored in the `configureAccessory` method above
970
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
971
+
972
+ if (existingAccessory) {
973
+ // the accessory already exists
974
+ if (await this.registerDevice(device)) {
975
+ // console.log("existingAccessory", existingAccessory);
976
+ // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
977
+ existingAccessory.context.device = device
978
+ existingAccessory.context.model = SwitchBotModel.MeterPro ?? SwitchBotModel.MeterProCO2
979
+ existingAccessory.context.deviceId = device.deviceId
980
+ existingAccessory.context.deviceType = device.deviceType
981
+ existingAccessory.displayName = device.configDeviceName
982
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
983
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
984
+ existingAccessory.context.connectionType = await this.connectionType(device)
985
+ existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
986
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
987
+ this.api.updatePlatformAccessories([existingAccessory])
988
+ // create the accessory handler for the restored accessory
989
+ // this is imported from `platformAccessory.ts`
990
+ new MeterPro(this, existingAccessory, device)
991
+ await this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
992
+ } else {
993
+ this.unregisterPlatformAccessories(existingAccessory)
994
+ }
995
+ } else if (await this.registerDevice(device)) {
996
+ // create a new accessory
997
+ const accessory = new this.api.platformAccessory(device.configDeviceName
998
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
999
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1000
+
1001
+ // store a copy of the device object in the `accessory.context`
1002
+ // the `context` property can be used to store any data about the accessory you may need
1003
+ accessory.context.device = device
1004
+ accessory.context.model = SwitchBotModel.MeterPro ?? SwitchBotModel.MeterProCO2
1005
+ accessory.context.deviceId = device.deviceId
1006
+ accessory.context.deviceType = device.deviceType
1007
+ accessory.displayName = device.configDeviceName
1008
+ ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1009
+ : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1010
+ accessory.context.connectionType = await this.connectionType(device)
1011
+ accessory.context.connectionType = await this.connectionType(device)
1012
+ accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1013
+ const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1014
+ await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1015
+ // create the accessory handler for the newly create accessory
1016
+ // this is imported from `platformAccessory.ts`
1017
+ new MeterPro(this, accessory, device)
1018
+ await this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1019
+
1020
+ // publish device externally or link the accessory to your platform
1021
+ this.externalOrPlatform(device, accessory)
1022
+ this.accessories.push(accessory)
1023
+ } else {
1024
+ await this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1025
+ }
1026
+ }
1027
+
963
1028
  private async createHub2(device: device & devicesConfig) {
964
1029
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
965
1030
 
package/src/settings.ts CHANGED
@@ -8,7 +8,7 @@ import type { PlatformConfig } from 'homebridge'
8
8
  * For Testing Locally:
9
9
  * import type { device, irdevice, SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
10
10
  */
11
- import type { device, irdevice, SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName } from 'node-switchbot'
11
+ import type { device, irdevice, SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName, SwitchBotModel } from 'node-switchbot'
12
12
  /**
13
13
  * This is the name of the platform that users will use to register the plugin in the Homebridge config.json
14
14
  */
@@ -57,7 +57,7 @@ export type devicesConfig = botConfig | meterConfig | indoorOutdoorSensorConfig
57
57
 
58
58
  export interface BaseDeviceConfig extends device {
59
59
  bleMac?: string
60
- model: string
60
+ model: SwitchBotModel
61
61
  bleModel: SwitchBotBLEModel
62
62
  bleModelName: SwitchBotBLEModelName
63
63
  bleModelFriednlyName: SwitchBotBLEModelFriendlyName
@@ -97,7 +97,7 @@ export interface botConfig extends BaseDeviceConfig {
97
97
  };
98
98
 
99
99
  export interface meterConfig extends BaseDeviceConfig {
100
- configDeviceType: 'Meter' | 'MeterPlus'
100
+ configDeviceType: 'Meter' | 'MeterPlus' | 'Meter Pro' | 'Meter Pro CO2'
101
101
  hide_temperature?: boolean
102
102
  convertUnitTo?: string
103
103
  hide_humidity?: boolean