@switchbot/homebridge-switchbot 5.0.0-beta.33 → 5.0.0-beta.35
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.
- package/config.schema.json +760 -13806
- package/dist/devices-hap/device.d.ts +17 -8
- package/dist/devices-hap/device.d.ts.map +1 -1
- package/dist/devices-hap/device.js +66 -53
- package/dist/devices-hap/device.js.map +1 -1
- package/dist/devices-matter/BaseMatterAccessory.d.ts +4 -0
- package/dist/devices-matter/BaseMatterAccessory.d.ts.map +1 -1
- package/dist/devices-matter/BaseMatterAccessory.js +13 -11
- package/dist/devices-matter/BaseMatterAccessory.js.map +1 -1
- package/dist/platform-hap.d.ts.map +1 -1
- package/dist/platform-hap.js +19 -47
- package/dist/platform-hap.js.map +1 -1
- package/dist/platform-matter.d.ts +1 -2
- package/dist/platform-matter.d.ts.map +1 -1
- package/dist/platform-matter.js +12 -46
- package/dist/platform-matter.js.map +1 -1
- package/dist/settings.d.ts +0 -6
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +21 -5
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +62 -43
- package/dist/utils.js.map +1 -1
- package/docs/variables/default.html +1 -1
- package/package.json +1 -1
- package/src/devices-hap/device.ts +76 -54
- package/src/devices-matter/BaseMatterAccessory.ts +19 -11
- package/src/platform-hap.ts +19 -49
- package/src/platform-matter.ts +12 -46
- package/src/settings.ts +0 -2
- package/src/utils.ts +82 -49
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import type { API, EndpointType, Logger, MatterAccessory } from 'homebridge'
|
|
12
12
|
|
|
13
|
-
import { rgb2hs } from '../utils.js'
|
|
13
|
+
import { deviceLoggingEnabled, deviceLoggingIsDebug, logDeviceStatusCode, rgb2hs } from '../utils.js'
|
|
14
14
|
|
|
15
15
|
export interface BaseMatterAccessoryConfig {
|
|
16
16
|
uuid: string
|
|
@@ -139,20 +139,28 @@ export abstract class BaseMatterAccessory implements MatterAccessory {
|
|
|
139
139
|
*/
|
|
140
140
|
public async loggingIsDebug(): Promise<boolean> {
|
|
141
141
|
const ctx: any = this.context as any
|
|
142
|
-
|
|
143
|
-
// deviceLogging may be a string ('debug', 'debugMode', 'standard') or undefined
|
|
144
|
-
return deviceLogging === 'debugMode' || deviceLogging === 'debug'
|
|
142
|
+
return deviceLoggingIsDebug(ctx?.deviceLogging)
|
|
145
143
|
}
|
|
146
144
|
|
|
147
145
|
public async enablingDeviceLogging(): Promise<boolean> {
|
|
148
146
|
const ctx: any = this.context as any
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
147
|
+
return deviceLoggingEnabled(ctx?.deviceLogging, ctx?.platformLogging)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Status code logging using shared helper
|
|
152
|
+
*/
|
|
153
|
+
public async statusCode(statusCode: number, deviceId?: string, hubDeviceId?: string): Promise<void> {
|
|
154
|
+
await logDeviceStatusCode(
|
|
155
|
+
statusCode,
|
|
156
|
+
{
|
|
157
|
+
debugLog: this.logDebug.bind(this),
|
|
158
|
+
errorLog: this.logError.bind(this),
|
|
159
|
+
infoLog: this.logInfo.bind(this),
|
|
160
|
+
},
|
|
161
|
+
deviceId ?? (this.context as any)?.deviceId,
|
|
162
|
+
hubDeviceId ?? (this.context as any)?.hubDeviceId,
|
|
163
|
+
)
|
|
156
164
|
}
|
|
157
165
|
|
|
158
166
|
/**
|
package/src/platform-hap.ts
CHANGED
|
@@ -55,7 +55,7 @@ import { TV } from './irdevice/tv.js'
|
|
|
55
55
|
import { VacuumCleaner } from './irdevice/vacuumcleaner.js'
|
|
56
56
|
import { WaterHeater } from './irdevice/waterheater.js'
|
|
57
57
|
import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js'
|
|
58
|
-
import { ApiRequestTracker,
|
|
58
|
+
import { ApiRequestTracker, createPlatformLogger, formatDeviceIdAsMac, isBlindTiltDevice, isCurtainDevice, isSuccessfulStatusCode, logStatusCode, mergeByDeviceId, safeStringify, sleep } from './utils.js'
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
61
|
* HomebridgePlatform
|
|
@@ -161,20 +161,8 @@ export class SwitchBotHAPPlatform implements DynamicPlatformPlugin {
|
|
|
161
161
|
// swallow any logging errors — diagnostics are best-effort
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
//
|
|
165
|
-
|
|
166
|
-
if ((this.config as any).options) {
|
|
167
|
-
const cleaned = cleanDeviceConfig((this.config as any).options.deviceConfig)
|
|
168
|
-
if (cleaned) {
|
|
169
|
-
;(this.config as any).options.deviceConfig = cleaned
|
|
170
|
-
} else {
|
|
171
|
-
// remove the empty deviceConfig so downstream checks treat it as absent
|
|
172
|
-
delete (this.config as any).options.deviceConfig
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
} catch (e) {
|
|
176
|
-
this.debugErrorLog(`Failed to clean deviceConfig: ${e}`)
|
|
177
|
-
}
|
|
164
|
+
// Note: deviceConfig and irdeviceConfig have been removed from the platform.
|
|
165
|
+
// All device-specific configuration should be done via options.devices and options.irdevices arrays.
|
|
178
166
|
|
|
179
167
|
// Plugin Configuration
|
|
180
168
|
this.getPlatformLogSettings()
|
|
@@ -552,7 +540,7 @@ export class SwitchBotHAPPlatform implements DynamicPlatformPlugin {
|
|
|
552
540
|
}
|
|
553
541
|
|
|
554
542
|
private async handleDevices(deviceLists: any[]) {
|
|
555
|
-
if (!this.config.options?.devices
|
|
543
|
+
if (!this.config.options?.devices) {
|
|
556
544
|
this.debugLog(`SwitchBot Device Config Not Set: ${JSON.stringify(this.config.options?.devices)}`)
|
|
557
545
|
if (deviceLists.length === 0) {
|
|
558
546
|
this.debugLog('SwitchBot API Has No Devices With Cloud Services Enabled')
|
|
@@ -566,80 +554,62 @@ export class SwitchBotHAPPlatform implements DynamicPlatformPlugin {
|
|
|
566
554
|
}
|
|
567
555
|
}
|
|
568
556
|
}
|
|
569
|
-
} else
|
|
557
|
+
} else {
|
|
570
558
|
this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`)
|
|
571
559
|
|
|
572
|
-
//
|
|
573
|
-
const
|
|
560
|
+
// Check and assign configDeviceType to deviceType if deviceType is not present
|
|
561
|
+
const devicesWithTypeAssigned = deviceLists.map((device) => {
|
|
574
562
|
if (!device.deviceType) {
|
|
575
563
|
device.deviceType = device.configDeviceType !== undefined ? device.configDeviceType : 'Unknown'
|
|
576
564
|
this.warnLog(`API is displaying no deviceType: ${device.deviceType}, So using configDeviceType: ${device.configDeviceType}`)
|
|
577
565
|
}
|
|
578
|
-
|
|
579
|
-
// Retrieve deviceTypeConfig for each device and merge it
|
|
580
|
-
const deviceTypeConfig = this.config.options?.deviceConfig?.[device.deviceType] || {}
|
|
581
|
-
return Object.assign({}, device, deviceTypeConfig)
|
|
566
|
+
return device
|
|
582
567
|
})
|
|
583
568
|
|
|
584
|
-
|
|
585
|
-
const devicesWithTypeConfig = (await Promise.all(devicesWithTypeConfigPromises)).filter(device => device !== null) // Filter out skipped devices
|
|
586
|
-
|
|
587
|
-
const devices = this.mergeByDeviceId(this.config.options.devices ?? [], devicesWithTypeConfig ?? [])
|
|
569
|
+
const devices = this.mergeByDeviceId(this.config.options.devices ?? [], devicesWithTypeAssigned ?? [])
|
|
588
570
|
|
|
589
571
|
this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`)
|
|
590
572
|
|
|
591
573
|
for (const device of devices) {
|
|
592
|
-
const deviceIdConfig = this.config.options?.devices?.[device.deviceId] || {}
|
|
593
|
-
const deviceWithConfig = Object.assign({}, device, deviceIdConfig)
|
|
594
|
-
|
|
595
574
|
if (device.configDeviceName) {
|
|
596
575
|
device.deviceName = device.configDeviceName
|
|
597
576
|
}
|
|
598
|
-
|
|
599
|
-
await this.createDevice(deviceWithConfig)
|
|
577
|
+
await this.createDevice(device)
|
|
600
578
|
}
|
|
601
579
|
}
|
|
602
580
|
}
|
|
603
581
|
|
|
604
582
|
private async handleIRDevices(irDeviceLists: any[]) {
|
|
605
|
-
if (!this.config.options?.irdevices
|
|
583
|
+
if (!this.config.options?.irdevices) {
|
|
606
584
|
this.debugLog(`IR Device Config Not Set: ${JSON.stringify(this.config.options?.irdevices)}`)
|
|
607
585
|
for (const device of irDeviceLists) {
|
|
608
586
|
if (device.remoteType) {
|
|
609
587
|
await this.createIRDevice(device)
|
|
610
588
|
}
|
|
611
589
|
}
|
|
612
|
-
} else
|
|
590
|
+
} else {
|
|
613
591
|
this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`)
|
|
614
592
|
|
|
615
|
-
//
|
|
616
|
-
const
|
|
593
|
+
// Check and assign configRemoteType to remoteType if remoteType is not present
|
|
594
|
+
const devicesWithTypeAssigned = irDeviceLists.map((device) => {
|
|
617
595
|
if (!device.remoteType && device.configRemoteType) {
|
|
618
596
|
device.remoteType = device.configRemoteType
|
|
619
597
|
this.warnLog(`API is displaying no remoteType: ${device.remoteType}, So using configRemoteType: ${device.configRemoteType}`)
|
|
620
598
|
} else if (!device.remoteType && !device.configDeviceName) {
|
|
621
599
|
this.errorLog('No remoteType or configRemoteType for device. No device will be created.')
|
|
622
|
-
return null
|
|
600
|
+
return null
|
|
623
601
|
}
|
|
602
|
+
return device
|
|
603
|
+
}).filter(device => device !== null) // Filter out skipped devices
|
|
624
604
|
|
|
625
|
-
|
|
626
|
-
const remoteTypeConfig = this.config.options?.irdeviceConfig?.[device.remoteType] || {}
|
|
627
|
-
return Object.assign({}, device, remoteTypeConfig)
|
|
628
|
-
})
|
|
629
|
-
// Wait for all promises to resolve
|
|
630
|
-
const devicesWithRemoteTypeConfig = (await Promise.all(devicesWithTypeConfigPromises)).filter(device => device !== null) // Filter out skipped devices
|
|
631
|
-
|
|
632
|
-
const devices = this.mergeByDeviceId(this.config.options.irdevices ?? [], devicesWithRemoteTypeConfig ?? [])
|
|
605
|
+
const devices = this.mergeByDeviceId(this.config.options.irdevices ?? [], devicesWithTypeAssigned ?? [])
|
|
633
606
|
|
|
634
607
|
this.debugLog(`IR Devices: ${JSON.stringify(devices)}`)
|
|
635
608
|
for (const device of devices) {
|
|
636
|
-
const irdeviceIdConfig = this.config.options?.irdevices?.[device.deviceId] || {}
|
|
637
|
-
const irdeviceWithConfig = Object.assign({}, device, irdeviceIdConfig)
|
|
638
|
-
|
|
639
609
|
if (device.configDeviceName) {
|
|
640
610
|
device.deviceName = device.configDeviceName
|
|
641
611
|
}
|
|
642
|
-
await this.createIRDevice(
|
|
612
|
+
await this.createIRDevice(device)
|
|
643
613
|
}
|
|
644
614
|
}
|
|
645
615
|
}
|
package/src/platform-matter.ts
CHANGED
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
WindowBlindAccessory,
|
|
43
43
|
} from './devices-matter/index.js'
|
|
44
44
|
import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js'
|
|
45
|
-
import { ApiRequestTracker,
|
|
45
|
+
import { ApiRequestTracker, createPlatformLogger, formatDeviceIdAsMac, hs2rgb, isSuccessfulStatusCode, makeBLESender, makeOpenAPISender, mergeByDeviceId, normalizeDeviceId, rgb2hs, sleep } from './utils.js'
|
|
46
46
|
|
|
47
47
|
export class SwitchBotMatterPlatform implements DynamicPlatformPlugin {
|
|
48
48
|
// Track restored HAP cached accessories (required for DynamicPlatformPlugin)
|
|
@@ -130,19 +130,8 @@ export class SwitchBotMatterPlatform implements DynamicPlatformPlugin {
|
|
|
130
130
|
|
|
131
131
|
this.debugLog('Finished initializing platform:', this.config.name)
|
|
132
132
|
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
if ((this.config as any).options) {
|
|
136
|
-
const cleaned = cleanDeviceConfig((this.config as any).options.deviceConfig)
|
|
137
|
-
if (cleaned) {
|
|
138
|
-
;(this.config as any).options.deviceConfig = cleaned
|
|
139
|
-
} else {
|
|
140
|
-
delete (this.config as any).options.deviceConfig
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
} catch (e) {
|
|
144
|
-
this.debugLog('Failed to clean deviceConfig: %s', e)
|
|
145
|
-
}
|
|
133
|
+
// Note: deviceConfig and irdeviceConfig have been removed from the platform.
|
|
134
|
+
// All device-specific configuration should be done via options.devices arrays.
|
|
146
135
|
|
|
147
136
|
// Does the user have a version of Homebridge that is compatible with matter?
|
|
148
137
|
if (!this.api.isMatterAvailable?.()) {
|
|
@@ -429,46 +418,27 @@ export class SwitchBotMatterPlatform implements DynamicPlatformPlugin {
|
|
|
429
418
|
}
|
|
430
419
|
|
|
431
420
|
/**
|
|
432
|
-
* Merge discovered devices with
|
|
433
|
-
* from `config.options.devices`, matching the behavior used in platform-hap.
|
|
421
|
+
* Merge discovered devices with per-device overrides from `config.options.devices`
|
|
434
422
|
*/
|
|
435
423
|
private async mergeDiscoveredDevices(discovered: device[]): Promise<any[]> {
|
|
436
|
-
// If there's no
|
|
437
|
-
if (!this.config.options?.devices
|
|
424
|
+
// If there's no per-device config, return discovered as-is
|
|
425
|
+
if (!this.config.options?.devices) {
|
|
438
426
|
return discovered
|
|
439
427
|
}
|
|
440
428
|
|
|
441
|
-
//
|
|
442
|
-
const
|
|
429
|
+
// Assign missing deviceType from configDeviceType if needed
|
|
430
|
+
const devicesWithTypeAssigned = discovered.map((deviceObj) => {
|
|
443
431
|
if (!deviceObj.deviceType) {
|
|
444
432
|
deviceObj.deviceType = (deviceObj as any).configDeviceType !== undefined ? (deviceObj as any).configDeviceType : 'Unknown'
|
|
445
433
|
this.debugLog(`API missing deviceType for ${deviceObj.deviceId}, using configDeviceType: ${(deviceObj as any).configDeviceType}`)
|
|
446
434
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
}))
|
|
435
|
+
return deviceObj
|
|
436
|
+
})
|
|
450
437
|
|
|
451
438
|
// Merge per-device overrides by matching deviceId
|
|
452
|
-
const merged = this.mergeByDeviceId(this.config.options?.devices ?? [],
|
|
453
|
-
|
|
454
|
-
// For any entries in merged (which are based on config.options.devices), ensure final per-device merges include deviceId-specific config
|
|
455
|
-
const final: any[] = []
|
|
456
|
-
for (const device of merged) {
|
|
457
|
-
// Find per-device config entry by deviceId (config.options.devices is an array)
|
|
458
|
-
const deviceIdConfig = (this.config.options?.devices || []).find((d: any) => this.normalizeDeviceId(d.deviceId) === this.normalizeDeviceId(device.deviceId)) || {}
|
|
459
|
-
const deviceWithConfig = Object.assign({}, device, deviceIdConfig)
|
|
460
|
-
final.push(deviceWithConfig)
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// Also include any discovered devices that weren't present in the user devices list
|
|
464
|
-
const userDeviceIds = new Set((this.config.options?.devices || []).map((d: any) => this.normalizeDeviceId(d.deviceId)))
|
|
465
|
-
for (const d of devicesWithTypeConfig) {
|
|
466
|
-
if (!userDeviceIds.has(this.normalizeDeviceId(d.deviceId))) {
|
|
467
|
-
final.push(d)
|
|
468
|
-
}
|
|
469
|
-
}
|
|
439
|
+
const merged = this.mergeByDeviceId(this.config.options?.devices ?? [], devicesWithTypeAssigned ?? [])
|
|
470
440
|
|
|
471
|
-
return
|
|
441
|
+
return merged
|
|
472
442
|
}
|
|
473
443
|
|
|
474
444
|
/**
|
|
@@ -1714,10 +1684,6 @@ export class SwitchBotMatterPlatform implements DynamicPlatformPlugin {
|
|
|
1714
1684
|
* Register all Matter accessories
|
|
1715
1685
|
*/
|
|
1716
1686
|
private async registerMatterAccessories() {
|
|
1717
|
-
this.debugLog('═'.repeat(80))
|
|
1718
|
-
this.infoLog('Homebridge Matter Plugin')
|
|
1719
|
-
this.debugLog('═'.repeat(80))
|
|
1720
|
-
|
|
1721
1687
|
// Remove accessories that are disabled in config
|
|
1722
1688
|
await this.removeDisabledAccessories()
|
|
1723
1689
|
|
package/src/settings.ts
CHANGED
|
@@ -32,9 +32,7 @@ interface credentials {
|
|
|
32
32
|
|
|
33
33
|
export interface options {
|
|
34
34
|
devices?: devicesConfig[]
|
|
35
|
-
deviceConfig?: { [deviceType: string]: devicesConfig }
|
|
36
35
|
irdevices?: irDevicesConfig[]
|
|
37
|
-
irdeviceConfig?: { [remoteType: string]: irDevicesConfig }
|
|
38
36
|
allowInvalidCharacters?: boolean
|
|
39
37
|
// When true, devices declared in config.options.devices that are not
|
|
40
38
|
// discovered via the SwitchBot OpenAPI will still be included (config-only
|
package/src/utils.ts
CHANGED
|
@@ -672,55 +672,6 @@ export function m2hs(m) {
|
|
|
672
672
|
return [Math.round(toReturn[1]), Math.round(toReturn[0])]
|
|
673
673
|
}
|
|
674
674
|
|
|
675
|
-
/**
|
|
676
|
-
* Remove deviceConfig entries that contain only default/empty values.
|
|
677
|
-
* Returns undefined if nothing meaningful remains.
|
|
678
|
-
*/
|
|
679
|
-
export function cleanDeviceConfig(deviceConfig?: Record<string, Record<string, any>>): Record<string, Record<string, any>> | undefined {
|
|
680
|
-
if (!deviceConfig || typeof deviceConfig !== 'object') {
|
|
681
|
-
return undefined
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
const cleaned: Record<string, Record<string, any>> = {}
|
|
685
|
-
|
|
686
|
-
for (const [deviceName, cfg] of Object.entries(deviceConfig)) {
|
|
687
|
-
if (!cfg || typeof cfg !== 'object') {
|
|
688
|
-
continue
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
const hasMeaningful = Object.values(cfg).some((v) => {
|
|
692
|
-
if (v === null || v === undefined) {
|
|
693
|
-
return false
|
|
694
|
-
}
|
|
695
|
-
if (typeof v === 'boolean') {
|
|
696
|
-
return v === true
|
|
697
|
-
}
|
|
698
|
-
if (typeof v === 'string') {
|
|
699
|
-
return v.trim().length > 0
|
|
700
|
-
}
|
|
701
|
-
if (typeof v === 'number') {
|
|
702
|
-
return Number.isFinite(v)
|
|
703
|
-
}
|
|
704
|
-
if (Array.isArray(v)) {
|
|
705
|
-
return v.length > 0
|
|
706
|
-
}
|
|
707
|
-
if (typeof v === 'object') {
|
|
708
|
-
return Object.keys(v).length > 0
|
|
709
|
-
}
|
|
710
|
-
return true
|
|
711
|
-
})
|
|
712
|
-
|
|
713
|
-
if (hasMeaningful) {
|
|
714
|
-
cleaned[deviceName] = cfg
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
if (Object.keys(cleaned).length > 0) {
|
|
719
|
-
return cleaned
|
|
720
|
-
}
|
|
721
|
-
return undefined
|
|
722
|
-
}
|
|
723
|
-
|
|
724
675
|
/**
|
|
725
676
|
* Factory that returns a function to send OpenAPI commands using a retry wrapper.
|
|
726
677
|
*
|
|
@@ -1205,3 +1156,85 @@ export async function logStatusCode(statusCode: number, log: {
|
|
|
1205
1156
|
await log.errorLog(message)
|
|
1206
1157
|
}
|
|
1207
1158
|
}
|
|
1159
|
+
|
|
1160
|
+
/**
|
|
1161
|
+
* Shared device logging helpers
|
|
1162
|
+
*/
|
|
1163
|
+
|
|
1164
|
+
/**
|
|
1165
|
+
* Check if device logging is in debug mode
|
|
1166
|
+
*/
|
|
1167
|
+
export function deviceLoggingIsDebug(deviceLogging?: string): boolean {
|
|
1168
|
+
return deviceLogging === 'debugMode' || deviceLogging === 'debug'
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
/**
|
|
1172
|
+
* Check if device logging is enabled
|
|
1173
|
+
*/
|
|
1174
|
+
export function deviceLoggingEnabled(deviceLogging?: string, platformLogging?: string): boolean {
|
|
1175
|
+
// If deviceLogging isn't provided, fall back to platform-wide flag
|
|
1176
|
+
if (deviceLogging === undefined || deviceLogging === '') {
|
|
1177
|
+
return platformLogging === 'debugMode' || platformLogging === 'debug' || platformLogging === 'standard'
|
|
1178
|
+
}
|
|
1179
|
+
return deviceLogging === 'debugMode' || deviceLogging === 'debug' || deviceLogging === 'standard'
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* Device status code handler with comprehensive messages
|
|
1184
|
+
*/
|
|
1185
|
+
export interface DeviceStatusCodeLogger {
|
|
1186
|
+
debugLog: (...args: any[]) => void | Promise<void>
|
|
1187
|
+
debugErrorLog?: (...args: any[]) => void | Promise<void>
|
|
1188
|
+
errorLog: (...args: any[]) => void | Promise<void>
|
|
1189
|
+
infoLog?: (...args: any[]) => void | Promise<void>
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
export async function logDeviceStatusCode(
|
|
1193
|
+
statusCode: number,
|
|
1194
|
+
log: DeviceStatusCodeLogger,
|
|
1195
|
+
deviceId?: string,
|
|
1196
|
+
hubDeviceId?: string,
|
|
1197
|
+
): Promise<void> {
|
|
1198
|
+
let adjustedStatusCode = statusCode
|
|
1199
|
+
|
|
1200
|
+
// Handle special case where device is its own hub
|
|
1201
|
+
if (statusCode === 171 && hubDeviceId && deviceId && (hubDeviceId === deviceId || hubDeviceId === '000000000000')) {
|
|
1202
|
+
if (log.debugErrorLog) {
|
|
1203
|
+
log.debugErrorLog(`statusCode 171 changed to 161: hubDeviceId ${hubDeviceId} matches deviceId ${deviceId}, device is its own hub.`)
|
|
1204
|
+
}
|
|
1205
|
+
adjustedStatusCode = 161
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
const statusMessages: { [key: number]: string } = {
|
|
1209
|
+
151: 'Command not supported by this device type',
|
|
1210
|
+
152: 'Device not found',
|
|
1211
|
+
160: 'Command is not supported',
|
|
1212
|
+
161: 'Device is offline',
|
|
1213
|
+
171: hubDeviceId ? `Hub Device is offline. Hub: ${hubDeviceId}` : 'Hub Device is offline',
|
|
1214
|
+
190: 'Device internal error due to device states not synchronized with server, or command format is invalid',
|
|
1215
|
+
100: 'Command successfully sent',
|
|
1216
|
+
200: 'Request successful',
|
|
1217
|
+
400: 'Bad Request, an invalid payload request',
|
|
1218
|
+
401: 'Unauthorized, Authorization for the API is required, but the request has not been authenticated',
|
|
1219
|
+
403: 'Forbidden, The request has been authenticated but does not have appropriate permissions, or a requested resource is not found',
|
|
1220
|
+
404: 'Not Found, Specifies the requested path does not exist',
|
|
1221
|
+
406: 'Not Acceptable, a MIME type has been requested via the Accept header for a value not supported by the server',
|
|
1222
|
+
415: 'Unsupported Media Type, a contentType header has been defined that is not supported by the server',
|
|
1223
|
+
422: 'Unprocessable Entity: The server cannot process the request, often due to exceeded API limits.',
|
|
1224
|
+
429: 'Too Many Requests, exceeded the number of requests allowed for a given time window',
|
|
1225
|
+
500: 'Internal Server Error, An unexpected error occurred. These errors should be rare',
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
const logMessage = statusMessages[adjustedStatusCode] || `Unknown statusCode: ${adjustedStatusCode}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`
|
|
1229
|
+
const fullMessage = `${logMessage}, statusCode: ${adjustedStatusCode}`
|
|
1230
|
+
|
|
1231
|
+
if ([100, 200].includes(adjustedStatusCode)) {
|
|
1232
|
+
await log.debugLog(fullMessage)
|
|
1233
|
+
} else if (statusMessages[adjustedStatusCode]) {
|
|
1234
|
+
await log.errorLog(fullMessage)
|
|
1235
|
+
} else if (log.infoLog) {
|
|
1236
|
+
await log.infoLog(fullMessage)
|
|
1237
|
+
} else {
|
|
1238
|
+
await log.errorLog(fullMessage)
|
|
1239
|
+
}
|
|
1240
|
+
}
|