@switchbot/homebridge-switchbot 4.1.6-beta.1 → 4.1.6-beta.11

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 (52) hide show
  1. package/README.md +1 -0
  2. package/config.schema.json +42 -29
  3. package/dist/device/colorbulb.js +19 -19
  4. package/dist/device/colorbulb.js.map +1 -1
  5. package/dist/device/curtain.d.ts.map +1 -1
  6. package/dist/device/curtain.js +4 -5
  7. package/dist/device/curtain.js.map +1 -1
  8. package/dist/device/device.d.ts +1 -1
  9. package/dist/device/device.d.ts.map +1 -1
  10. package/dist/device/device.js +9 -1
  11. package/dist/device/device.js.map +1 -1
  12. package/dist/device/fan.d.ts.map +1 -1
  13. package/dist/device/fan.js +2 -3
  14. package/dist/device/fan.js.map +1 -1
  15. package/dist/device/humidifier.d.ts +4 -4
  16. package/dist/device/humidifier.d.ts.map +1 -1
  17. package/dist/device/humidifier.js +1 -2
  18. package/dist/device/humidifier.js.map +1 -1
  19. package/dist/device/lightstrip.js +2 -2
  20. package/dist/device/lightstrip.js.map +1 -1
  21. package/dist/device/lock.d.ts.map +1 -1
  22. package/dist/device/lock.js +2 -2
  23. package/dist/device/lock.js.map +1 -1
  24. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  25. package/dist/device/robotvacuumcleaner.js +2 -3
  26. package/dist/device/robotvacuumcleaner.js.map +1 -1
  27. package/dist/platform.d.ts +1 -1
  28. package/dist/platform.d.ts.map +1 -1
  29. package/dist/platform.js +6 -5
  30. package/dist/platform.js.map +1 -1
  31. package/dist/settings.d.ts +2 -1
  32. package/dist/settings.d.ts.map +1 -1
  33. package/dist/settings.js.map +1 -1
  34. package/dist/utils.d.ts +7 -0
  35. package/dist/utils.d.ts.map +1 -1
  36. package/dist/utils.js +18 -0
  37. package/dist/utils.js.map +1 -1
  38. package/docs/assets/main.js +3 -3
  39. package/docs/assets/style.css +14 -0
  40. package/docs/functions/default.html +1 -1
  41. package/package.json +13 -13
  42. package/src/device/colorbulb.ts +19 -19
  43. package/src/device/curtain.ts +4 -5
  44. package/src/device/device.ts +9 -1
  45. package/src/device/fan.ts +2 -3
  46. package/src/device/humidifier.ts +8 -9
  47. package/src/device/lightstrip.ts +2 -2
  48. package/src/device/lock.ts +3 -3
  49. package/src/device/robotvacuumcleaner.ts +2 -3
  50. package/src/platform.ts +13 -12
  51. package/src/settings.ts +2 -1
  52. package/src/utils.ts +19 -0
@@ -82,25 +82,6 @@ export class ColorBulb extends deviceBase {
82
82
  }
83
83
  accessory.context.LightBulb = this.LightBulb as object
84
84
 
85
- if (this.adaptiveLighting && this.adaptiveLightingShift === -1 && this.LightBulb) {
86
- accessory.removeService(this.LightBulb.Service)
87
- this.LightBulb.Service = accessory.addService(this.hap.Service.Lightbulb)
88
- accessory.context.adaptiveLighting = false
89
- this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`)
90
- } else if (this.adaptiveLighting && this.adaptiveLightingShift >= 0 && this.LightBulb) {
91
- this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.LightBulb.Service, {
92
- controllerMode: this.hap.AdaptiveLightingControllerMode.AUTOMATIC,
93
- customTemperatureAdjustment: this.adaptiveLightingShift,
94
- })
95
- accessory.configureController(this.AdaptiveLightingController)
96
- accessory.context.adaptiveLighting = true
97
- this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}, adaptiveLightingShift: ${this.adaptiveLightingShift}`,
98
- )
99
- } else {
100
- accessory.context.adaptiveLighting = false
101
- this.debugLog(`adaptiveLighting: ${accessory.context.adaptiveLighting}`)
102
- }
103
-
104
85
  // Initialize LightBulb Characteristics
105
86
  this.LightBulb.Service.setCharacteristic(this.hap.Characteristic.Name, this.LightBulb.Name).getCharacteristic(this.hap.Characteristic.On).onGet(() => {
106
87
  return this.LightBulb.On
@@ -139,6 +120,25 @@ export class ColorBulb extends deviceBase {
139
120
  return this.LightBulb.Saturation
140
121
  }).onSet(this.SaturationSet.bind(this))
141
122
 
123
+ if (this.adaptiveLighting && this.adaptiveLightingShift === -1 && this.LightBulb) {
124
+ accessory.removeService(this.LightBulb.Service)
125
+ this.LightBulb.Service = accessory.addService(this.hap.Service.Lightbulb)
126
+ accessory.context.adaptiveLighting = false
127
+ this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`)
128
+ } else if (this.adaptiveLighting && this.adaptiveLightingShift >= 0 && this.LightBulb) {
129
+ this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.LightBulb.Service, {
130
+ controllerMode: this.hap.AdaptiveLightingControllerMode.AUTOMATIC,
131
+ customTemperatureAdjustment: this.adaptiveLightingShift,
132
+ })
133
+ accessory.configureController(this.AdaptiveLightingController)
134
+ accessory.context.adaptiveLighting = true
135
+ this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}, adaptiveLightingShift: ${this.adaptiveLightingShift}`,
136
+ )
137
+ } else {
138
+ accessory.context.adaptiveLighting = false
139
+ this.debugLog(`adaptiveLighting: ${accessory.context.adaptiveLighting}`)
140
+ }
141
+
142
142
  // Retrieve initial values and updateHomekit
143
143
  try {
144
144
  this.debugLog('Retrieve initial values and update Homekit')
@@ -844,7 +844,6 @@ export class Curtain extends deviceBase {
844
844
  this.hasLoggedStandby = false
845
845
  this.infoLog('Checking Status ...')
846
846
  this.curtainMoving = true
847
- await this.setMinMax()
848
847
  if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition) {
849
848
  this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
850
849
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING
@@ -877,13 +876,13 @@ export class Curtain extends deviceBase {
877
876
 
878
877
  async setMinMax(): Promise<void> {
879
878
  if ((this.device as curtainConfig).set_min) {
880
- if (Number(this.WindowCovering.CurrentPosition) <= (this.device as curtainConfig).set_min!) {
881
- this.WindowCovering.CurrentPosition = 0
879
+ if (Number(this.WindowCovering.CurrentPosition) >= (this.device as curtainConfig).set_min!) {
880
+ this.WindowCovering.CurrentPosition = 100
882
881
  }
883
882
  }
884
883
  if ((this.device as curtainConfig).set_max) {
885
- if (Number(this.WindowCovering.CurrentPosition) >= (this.device as curtainConfig).set_max!) {
886
- this.WindowCovering.CurrentPosition = 100
884
+ if (Number(this.WindowCovering.CurrentPosition) <= (this.device as curtainConfig).set_max!) {
885
+ this.WindowCovering.CurrentPosition = 0
887
886
  }
888
887
  }
889
888
  if (this.device.history) {
@@ -14,7 +14,7 @@ import { hostname } from 'node:os'
14
14
 
15
15
  import { SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName, SwitchBotModel } from 'node-switchbot'
16
16
 
17
- import { formatDeviceIdAsMac, sleep } from '../utils.js'
17
+ import { formatDeviceIdAsMac, safeStringify, sleep } from '../utils.js'
18
18
 
19
19
  export abstract class deviceBase {
20
20
  public readonly api: API
@@ -169,6 +169,7 @@ export abstract class deviceBase {
169
169
  deviceSpecificConfig = device as indoorOutdoorSensorConfig
170
170
  break
171
171
  case 'Humidifier':
172
+ case 'Humidifier2':
172
173
  deviceSpecificConfig = device as humidifierConfig
173
174
  break
174
175
  case 'Curtain':
@@ -315,6 +316,7 @@ export abstract class deviceBase {
315
316
  // Set an event handler
316
317
  let serviceData = { model: this.device.bleModel, modelName: this.device.bleModelName } as ad['serviceData']
317
318
  switchbot.onadvertisement = (ad: ad) => {
319
+ this.debugLog(`ad: ${safeStringify(ad)}`)
318
320
  if (this.device.bleMac === ad.address && ad.serviceData.model === this.device.bleModel) {
319
321
  this.debugLog(`${JSON.stringify(ad, null, ' ')}`)
320
322
  this.debugLog(`address: ${ad.address}, model: ${ad.serviceData.model}`)
@@ -413,6 +415,12 @@ export abstract class deviceBase {
413
415
  bleModelName: SwitchBotBLEModelName.Humidifier,
414
416
  bleModelFriendlyName: SwitchBotBLEModelFriendlyName.Humidifier,
415
417
  },
418
+ 'Humidifier2': {
419
+ model: SwitchBotModel.Humidifier2,
420
+ bleModel: SwitchBotBLEModel.Humidifier2,
421
+ bleModelName: SwitchBotBLEModelName.Humidifier2,
422
+ bleModelFriendlyName: SwitchBotBLEModelFriendlyName.Humidifier2,
423
+ },
416
424
  'Hub Mini': {
417
425
  model: SwitchBotModel.HubMini,
418
426
  bleModel: SwitchBotBLEModel.Unknown,
package/src/device/fan.ts CHANGED
@@ -460,14 +460,13 @@ export class Fan extends deviceBase {
460
460
  switchBotBLE
461
461
  .discover({ model: this.device.bleModel, id: this.device.bleMac })
462
462
  .then(async (device_list: SwitchbotDevice[]) => {
463
- const deviceList = device_list as SwitchbotDevice[]
464
463
  return await this.retryBLE({
465
464
  max: this.maxRetryBLE(),
466
465
  fn: async () => {
467
466
  if (this.Fan.Active) {
468
- return await deviceList[0].turnOn()
467
+ return await (device_list[0] as any).turnOn()
469
468
  } else {
470
- return await deviceList[0].turnOff()
469
+ return await (device_list[0] as any).turnOff()
471
470
  }
472
471
  },
473
472
  })
@@ -3,7 +3,7 @@
3
3
  * humidifier.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
- import type { bodyChange, device, humidifierServiceData, humidifierStatus, humidifierWebhookContext, SwitchbotDevice, WoHumi } from 'node-switchbot'
6
+ import type { bodyChange, device, humidifier2ServiceData, humidifier2Status, humidifier2WebhookContext, humidifierServiceData, humidifierStatus, humidifierWebhookContext, SwitchbotDevice, WoHumi } from 'node-switchbot'
7
7
 
8
8
  import type { SwitchBotPlatform } from '../platform.js'
9
9
  import type { devicesConfig, humidifierConfig } from '../settings.js'
@@ -43,13 +43,13 @@ export class Humidifier extends deviceBase {
43
43
  }
44
44
 
45
45
  // OpenAPI
46
- deviceStatus!: humidifierStatus
46
+ deviceStatus!: humidifierStatus | humidifier2Status
47
47
 
48
48
  // Webhook
49
- webhookContext!: humidifierWebhookContext
49
+ webhookContext!: humidifierWebhookContext | humidifier2WebhookContext
50
50
 
51
51
  // BLE
52
- serviceData!: humidifierServiceData
52
+ serviceData!: humidifierServiceData | humidifier2ServiceData
53
53
 
54
54
  // Updates
55
55
  humidifierUpdateInProgress!: boolean
@@ -324,7 +324,7 @@ export class Humidifier extends deviceBase {
324
324
  // Start to monitor advertisement packets
325
325
  (async () => {
326
326
  // Start to monitor advertisement packets
327
- const serviceData = await this.monitorAdvertisementPackets(switchBotBLE) as humidifierServiceData
327
+ const serviceData = await this.monitorAdvertisementPackets(switchBotBLE) as humidifierServiceData | humidifier2ServiceData
328
328
  // Update HomeKit
329
329
  if (serviceData.model === SwitchBotBLEModel.Humidifier && serviceData.modelName === SwitchBotBLEModelName.Humidifier) {
330
330
  this.serviceData = serviceData
@@ -346,7 +346,7 @@ export class Humidifier extends deviceBase {
346
346
  const formattedDeviceId = formatDeviceIdAsMac(this.device.deviceId)
347
347
  this.device.bleMac = formattedDeviceId
348
348
  this.debugLog(`bleMac: ${this.device.bleMac}`)
349
- this.platform.bleEventHandler[this.device.bleMac] = async (context: humidifierServiceData) => {
349
+ this.platform.bleEventHandler[this.device.bleMac] = async (context: humidifierServiceData | humidifier2ServiceData) => {
350
350
  try {
351
351
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
352
352
  this.serviceData = context
@@ -388,7 +388,7 @@ export class Humidifier extends deviceBase {
388
388
  async registerWebhook() {
389
389
  if (this.device.webhook) {
390
390
  this.debugLog('is listening webhook.')
391
- this.platform.webhookEventHandler[this.device.deviceId] = async (context: humidifierWebhookContext) => {
391
+ this.platform.webhookEventHandler[this.device.deviceId] = async (context: humidifierWebhookContext | humidifier2WebhookContext) => {
392
392
  try {
393
393
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
394
394
  this.webhookContext = context
@@ -438,8 +438,7 @@ export class Humidifier extends deviceBase {
438
438
  switchBotBLE
439
439
  .discover({ model: this.device.bleModel, quick: true, id: this.device.bleMac })
440
440
  .then(async (device_list: SwitchbotDevice[]) => {
441
- const deviceList = device_list as WoHumi[]
442
- return await deviceList[0].percentage(this.HumidifierDehumidifier.RelativeHumidityHumidifierThreshold)
441
+ return await (device_list[0] as WoHumi).percentage(Number(this.HumidifierDehumidifier.RelativeHumidityHumidifierThreshold))
443
442
  })
444
443
  .then(async () => {
445
444
  this.successLog(`RelativeHumidityHumidifierThreshold: ${this.HumidifierDehumidifier.RelativeHumidityHumidifierThreshold} sent over BLE, sent successfully`)
@@ -512,7 +512,7 @@ export class StripLight extends deviceBase {
512
512
  .discover({ model: this.device.bleModel, id: this.device.bleMac })
513
513
  .then(async (device_list: SwitchbotDevice[]) => {
514
514
  this.infoLog(`Brightness: ${this.LightBulb.Brightness}`)
515
- return await device_list[0].setBrightness(this.LightBulb.Brightness)
515
+ return await (device_list[0] as WoStrip).setBrightness(Number(this.LightBulb.Brightness))
516
516
  })
517
517
  .then(async () => {
518
518
  this.successLog(`Brightness: ${this.LightBulb.Brightness} sent over SwitchBot BLE, sent successfully`)
@@ -551,7 +551,7 @@ export class StripLight extends deviceBase {
551
551
  .discover({ model: this.device.bleModel, id: this.device.bleMac })
552
552
  .then(async (device_list: SwitchbotDevice[]) => {
553
553
  this.infoLog(`RGB: ${(this.LightBulb.Brightness, red, green, blue)}`)
554
- return await device_list[0].setRGB(this.LightBulb.Brightness, red, green, blue)
554
+ return await (device_list[0] as WoStrip).setRGB(Number(this.LightBulb.Brightness), red, green, blue)
555
555
  })
556
556
  .then(async () => {
557
557
  this.successLog(`RGB: ${(this.LightBulb.Brightness, red, green, blue)} sent over SwitchBot BLE, sent successfully`)
@@ -3,7 +3,7 @@
3
3
  * lock.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
- import type { bodyChange, device, lockProServiceData, lockProStatus, lockProWebhookContext, lockServiceData, lockStatus, lockWebhookContext, SwitchbotDevice } from 'node-switchbot'
6
+ import type { bodyChange, device, lockProServiceData, lockProStatus, lockProWebhookContext, lockServiceData, lockStatus, lockWebhookContext, SwitchbotDevice, WoSmartLock } from 'node-switchbot'
7
7
 
8
8
  import type { SwitchBotPlatform } from '../platform.js'
9
9
  import type { devicesConfig, lockConfig } from '../settings.js'
@@ -451,9 +451,9 @@ export class Lock extends deviceBase {
451
451
  max: this.maxRetryBLE(),
452
452
  fn: async () => {
453
453
  if (this.LockMechanism.LockTargetState === this.hap.Characteristic.LockTargetState.SECURED) {
454
- return await device_list[0].lock({ id: this.device.bleMac })
454
+ return await (device_list[0] as WoSmartLock).lock()
455
455
  } else {
456
- return await device_list[0].unlock({ id: this.device.bleMac })
456
+ return await (device_list[0] as WoSmartLock).unlock()
457
457
  }
458
458
  },
459
459
  })
@@ -392,15 +392,14 @@ export class RobotVacuumCleaner extends deviceBase {
392
392
  switchBotBLE
393
393
  .discover({ model: this.device.bleModel, id: this.device.bleMac })
394
394
  .then(async (device_list: SwitchbotDevice[]) => {
395
- const deviceList = device_list as SwitchbotDevice[]
396
395
  this.infoLog(`On: ${this.LightBulb.On}`)
397
396
  return await this.retryBLE({
398
397
  max: this.maxRetryBLE(),
399
398
  fn: async () => {
400
399
  if (this.LightBulb.On) {
401
- return await deviceList[0].turnOn()
400
+ return await (device_list[0] as any).turnOn()
402
401
  } else {
403
- return await deviceList[0].turnOff()
402
+ return await (device_list[0] as any).turnOff()
404
403
  }
405
404
  },
406
405
  })
package/src/platform.ts CHANGED
@@ -6,22 +6,22 @@ import type { Server } from 'node:http'
6
6
 
7
7
  import type { API, DynamicPlatformPlugin, Logging, PlatformAccessory } from 'homebridge'
8
8
  import type { MqttClient } from 'mqtt'
9
+ /*
10
+ * For Testing Locally:
11
+ * import type { blindTilt, curtain, curtain3, device, irdevice } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
12
+ * import { LogLevel, SwitchBotBLE, SwitchBotModel, SwitchBotOpenAPI } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
13
+ */
14
+ import type { blindTilt, curtain, curtain3, device, deviceStatus, deviceStatusRequest, irdevice } from 'node-switchbot'
9
15
 
10
16
  import type { blindTiltConfig, curtainConfig, devicesConfig, irDevicesConfig, options, SwitchBotPlatformConfig } from './settings.js'
11
17
 
12
18
  import { readFileSync } from 'node:fs'
19
+ import { hostname } from 'node:os'
13
20
  import process, { argv } from 'node:process'
14
21
 
15
22
  import asyncmqtt from 'async-mqtt'
16
23
  import fakegato from 'fakegato-history'
17
24
  import { EveHomeKitTypes } from 'homebridge-lib/EveHomeKitTypes'
18
- /*
19
- * For Testing Locally:
20
- * import type { blindTilt, curtain, curtain3, device, irdevice } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
21
- * import { LogLevel, SwitchBotBLE, SwitchBotModel, SwitchBotOpenAPI } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
22
- */
23
- import type { blindTilt, curtain, curtain3, device, deviceStatus, deviceStatusRequest, irdevice } from 'node-switchbot'
24
-
25
25
  import { LogLevel, SwitchBotBLE, SwitchBotModel, SwitchBotOpenAPI } from 'node-switchbot'
26
26
  import { queueScheduler } from 'rxjs'
27
27
 
@@ -54,7 +54,7 @@ import { TV } from './irdevice/tv.js'
54
54
  import { VacuumCleaner } from './irdevice/vacuumcleaner.js'
55
55
  import { WaterHeater } from './irdevice/waterheater.js'
56
56
  import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js'
57
- import { formatDeviceIdAsMac, isBlindTiltDevice, isCurtainDevice, sleep } from './utils.js'
57
+ import { formatDeviceIdAsMac, isBlindTiltDevice, isCurtainDevice, safeStringify, sleep } from './utils.js'
58
58
 
59
59
  /**
60
60
  * HomebridgePlatform
@@ -139,7 +139,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
139
139
 
140
140
  // SwitchBot OpenAPI
141
141
  if (this.config.credentials?.token && this.config.credentials?.secret) {
142
- this.switchBotAPI = new SwitchBotOpenAPI(this.config.credentials.token, this.config.credentials.secret)
142
+ this.switchBotAPI = new SwitchBotOpenAPI(this.config.credentials.token, this.config.credentials.secret, this.config.options?.hostname)
143
143
  } else {
144
144
  this.debugErrorLog('Missing SwitchBot API credentials (token or secret).')
145
145
  }
@@ -583,6 +583,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
583
583
  private async createDevice(device: device & devicesConfig) {
584
584
  const deviceTypeHandlers: { [key: string]: (device: device & devicesConfig) => Promise<void> } = {
585
585
  'Humidifier': this.createHumidifier.bind(this),
586
+ 'Humidifier2': this.createHumidifier.bind(this),
586
587
  'Hub 2': this.createHub2.bind(this),
587
588
  'Bot': this.createBot.bind(this),
588
589
  'Meter': this.createMeter.bind(this),
@@ -685,7 +686,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
685
686
  existingAccessory.context.device = device
686
687
  existingAccessory.context.deviceId = device.deviceId
687
688
  existingAccessory.context.deviceType = device.deviceType
688
- existingAccessory.context.model = SwitchBotModel.Humidifier
689
+ existingAccessory.context.model = device.deviceType === 'Humidifier2' ? SwitchBotModel.Humidifier2 : SwitchBotModel.Humidifier
689
690
  existingAccessory.displayName = device.configDeviceName
690
691
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
691
692
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
@@ -711,7 +712,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
711
712
  accessory.context.device = device
712
713
  accessory.context.deviceId = device.deviceId
713
714
  accessory.context.deviceType = device.deviceType
714
- accessory.context.model = SwitchBotModel.Humidifier
715
+ accessory.context.model = device.deviceType === 'Humidifier2' ? SwitchBotModel.Humidifier2 : SwitchBotModel.Humidifier
715
716
  accessory.displayName = device.configDeviceName
716
717
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
717
718
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
@@ -2630,7 +2631,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2630
2631
  async connectBLE(accessory: PlatformAccessory, device: device & devicesConfig): Promise<any> {
2631
2632
  try {
2632
2633
  queueScheduler.schedule(async () => this.switchBotBLE)
2633
- this.debugLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${this.switchBotBLE}`)
2634
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${safeStringify(this.switchBotBLE)}`)
2634
2635
  return this.switchBotBLE
2635
2636
  } catch (e: any) {
2636
2637
  this.errorLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' not found, Error: ${e.message ?? e}`)
package/src/settings.ts CHANGED
@@ -43,6 +43,7 @@ export interface options {
43
43
  discoverBLE?: boolean
44
44
  disableLogsforBLE?: boolean
45
45
  disableLogsforOpenAPI?: boolean
46
+ hostname?: string
46
47
  webhookURL?: string
47
48
  maxRetries?: number
48
49
  delayBetweenRetries?: number
@@ -118,7 +119,7 @@ export interface indoorOutdoorSensorConfig extends BaseDeviceConfig {
118
119
  };
119
120
 
120
121
  export interface humidifierConfig extends BaseDeviceConfig {
121
- configDeviceType: 'Humidifier'
122
+ configDeviceType: 'Humidifier' | 'Humidifier2'
122
123
  hide_temperature?: boolean
123
124
  convertUnitTo?: string
124
125
  set_minStep?: number
package/src/utils.ts CHANGED
@@ -54,6 +54,25 @@ export function convertUnits(value: number, unit: string, convert?: string): num
54
54
  return value
55
55
  }
56
56
 
57
+ /**
58
+ * Safely serializes an object to a JSON string, handling circular references.
59
+ *
60
+ * @param obj - The object to be serialized.
61
+ * @returns The JSON string representation of the object.
62
+ */
63
+ export function safeStringify(obj: any) {
64
+ const seen = new WeakSet()
65
+ return JSON.stringify(obj, (_key, value) => {
66
+ if (typeof value === 'object' && value !== null) {
67
+ if (seen.has(value)) {
68
+ return
69
+ }
70
+ seen.add(value)
71
+ }
72
+ return value
73
+ }, ' ')
74
+ }
75
+
57
76
  /**
58
77
  * Formats a device ID as a MAC address.
59
78
  * Ensures the device ID does not already contain colons.