@switchbot/homebridge-switchbot 3.5.1-beta.4 → 3.5.1-beta.6

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/src/platform.ts CHANGED
@@ -34,23 +34,24 @@ import { AirConditioner } from './irdevice/airconditioner.js';
34
34
  import { Buffer } from 'buffer';
35
35
  import { request } from 'undici';
36
36
  import asyncmqtt from 'async-mqtt';
37
- import { isBlindTiltDevice, isCurtainDevice, sleep } from './utils.js';
38
37
  import { createServer } from 'http';
39
38
  import { queueScheduler } from 'rxjs';
40
39
  import fakegato from 'fakegato-history';
41
40
  import crypto, { randomUUID } from 'crypto';
42
41
  import { readFileSync, writeFileSync } from 'fs';
43
42
  import { EveHomeKitTypes } from 'homebridge-lib/EveHomeKitTypes';
43
+ import { isBlindTiltDevice, isCurtainDevice, sleep } from './utils.js';
44
44
  import { PLATFORM_NAME, PLUGIN_NAME, Devices, setupWebhook, updateWebhook, deleteWebhook, queryWebhook } from './settings.js';
45
45
 
46
46
  import type { UrlObject } from 'url';
47
47
  import type { MqttClient } from 'mqtt';
48
48
  import type { Dispatcher } from 'undici';
49
+ import type { irdevice } from './types/irdevicelist.js';
49
50
  import type { Server, IncomingMessage, ServerResponse } from 'http';
51
+ import type { deviceWebhook } from './types/devicewebhookstatus.js';
52
+ import type { blindTilt, curtain, curtain3, device } from './types/devicelist.js';
50
53
  import type { API, DynamicPlatformPlugin, Logging, PlatformAccessory } from 'homebridge';
51
54
  import type { SwitchBotPlatformConfig, devicesConfig, irDevicesConfig } from './settings.js';
52
- import type { irdevice } from './types/irdevicelist.js';
53
- import type { blindTilt, curtain, curtain3, device } from './types/devicelist.js';
54
55
 
55
56
  /**
56
57
  * HomebridgePlatform
@@ -76,7 +77,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
76
77
 
77
78
  public readonly fakegatoAPI: any;
78
79
  public readonly eve: any;
79
- public readonly webhookEventHandler;
80
+ public readonly webhookEventHandler!: deviceWebhook;
80
81
 
81
82
  constructor(
82
83
  log: Logging,
@@ -154,27 +155,27 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
154
155
  try {
155
156
  const { connectAsync } = asyncmqtt;
156
157
  this.mqttClient = await connectAsync(this.config.options?.mqttURL, this.config.options.mqttOptions || {});
157
- this.debugLog('MQTT connection has been established successfully.');
158
- this.mqttClient.on('error', (e: Error) => {
159
- this.errorLog(`Failed to publish MQTT messages. ${e}`);
158
+ await this.debugLog('MQTT connection has been established successfully.');
159
+ this.mqttClient.on('error', async (e: Error) => {
160
+ await this.errorLog(`Failed to publish MQTT messages. ${e}`);
160
161
  });
161
162
  if (!this.config.options?.webhookURL) {
162
163
  // receive webhook events via MQTT
163
- this.infoLog(`Webhook is configured to be received through ${this.config.options.mqttURL}/homebridge-switchbot/webhook.`);
164
+ await this.infoLog(`Webhook is configured to be received through ${this.config.options.mqttURL}/homebridge-switchbot/webhook.`);
164
165
  this.mqttClient.subscribe('homebridge-switchbot/webhook/+');
165
166
  this.mqttClient.on('message', async (topic: string, message) => {
166
167
  try {
167
- this.debugLog(`Received Webhook via MQTT: ${topic}=${message}`);
168
+ await this.debugLog(`Received Webhook via MQTT: ${topic}=${message}`);
168
169
  const context = JSON.parse(message.toString());
169
170
  this.webhookEventHandler[context.deviceMac]?.(context);
170
171
  } catch (e: any) {
171
- this.errorLog(`Failed to handle webhook event. Error:${e}`);
172
+ await this.errorLog(`Failed to handle webhook event. Error:${e}`);
172
173
  }
173
174
  });
174
175
  }
175
176
  } catch (e) {
176
177
  this.mqttClient = null;
177
- this.errorLog(`Failed to establish MQTT connection. ${e}`);
178
+ await this.errorLog(`Failed to establish MQTT connection. ${e}`);
178
179
  }
179
180
  }
180
181
  }
@@ -298,9 +299,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
298
299
  }),
299
300
  });
300
301
  const response: any = await body.json();
301
- this.debugLog(`deleteWebhook: url:${url}`);
302
- this.debugLog(`deleteWebhook: body:${JSON.stringify(response)}`);
303
- this.debugLog(`deleteWebhook: statusCode:${statusCode}`);
302
+ this.debugLog(`deleteWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
304
303
  if (statusCode !== 200 || response?.statusCode !== 100) {
305
304
  this.errorLog(`Failed to delete webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
306
305
  } else {
@@ -2660,67 +2659,67 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2660
2659
  async statusCode(statusCode: number): Promise<void> {
2661
2660
  switch (statusCode) {
2662
2661
  case 151:
2663
- this.errorLog(`Command not supported by this device type, statusCode: ${statusCode}, Submit Feature Request Here: ` +
2662
+ await this.errorLog(`Command not supported by this device type, statusCode: ${statusCode}, Submit Feature Request Here: ` +
2664
2663
  'https://tinyurl.com/SwitchBotFeatureRequest');
2665
2664
  break;
2666
2665
  case 152:
2667
- this.errorLog(`Device not found, statusCode: ${statusCode}`);
2666
+ await this.errorLog(`Device not found, statusCode: ${statusCode}`);
2668
2667
  break;
2669
2668
  case 160:
2670
- this.errorLog(`Command is not supported, statusCode: ${statusCode}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`);
2669
+ await this.errorLog(`Command is not supported, statusCode: ${statusCode}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`);
2671
2670
  break;
2672
2671
  case 161:
2673
- this.errorLog(`Device is offline, statusCode: ${statusCode}`);
2672
+ await this.errorLog(`Device is offline, statusCode: ${statusCode}`);
2674
2673
  break;
2675
2674
  case 171:
2676
- this.errorLog(`is offline, statusCode: ${statusCode}`);
2675
+ await this.errorLog(`is offline, statusCode: ${statusCode}`);
2677
2676
  break;
2678
2677
  case 190:
2679
- this.errorLog(`Requests reached the daily limit, statusCode: ${statusCode}`);
2678
+ await this.errorLog(`Requests reached the daily limit, statusCode: ${statusCode}`);
2680
2679
  break;
2681
2680
  case 100:
2682
- this.debugLog(`Command successfully sent, statusCode: ${statusCode}`);
2681
+ await this.debugLog(`Command successfully sent, statusCode: ${statusCode}`);
2683
2682
  break;
2684
2683
  case 200:
2685
- this.debugLog(`Request successful, statusCode: ${statusCode}`);
2684
+ await this.debugLog(`Request successful, statusCode: ${statusCode}`);
2686
2685
  break;
2687
2686
  case 400:
2688
- this.errorLog('Bad Request, The client has issued an invalid request. This is commonly used to specify validation errors in a request '
2687
+ await this.errorLog('Bad Request, The client has issued an invalid request. This is commonly used to specify validation errors in a request '
2689
2688
  + `payload, statusCode: ${statusCode}`);
2690
2689
  break;
2691
2690
  case 401:
2692
- this.errorLog('Unauthorized, Authorization for the API is required, but the request has not been authenticated, '
2691
+ await this.errorLog('Unauthorized, Authorization for the API is required, but the request has not been authenticated, '
2693
2692
  + `statusCode: ${statusCode}`);
2694
2693
  break;
2695
2694
  case 403:
2696
- this.errorLog('Forbidden, The request has been authenticated but does not have appropriate permissions, or a requested resource is not '
2695
+ await this.errorLog('Forbidden, The request has been authenticated but does not have appropriate permissions, or a requested resource is not '
2697
2696
  + `found, statusCode: ${statusCode}`);
2698
2697
  break;
2699
2698
  case 404:
2700
- this.errorLog(`Not Found, Specifies the requested path does not exist, statusCode: ${statusCode}`);
2699
+ await this.errorLog(`Not Found, Specifies the requested path does not exist, statusCode: ${statusCode}`);
2701
2700
  break;
2702
2701
  case 406:
2703
- this.errorLog('Not Acceptable, The client has requested a MIME type via the Accept header for a value not supported by the server, '
2702
+ await this.errorLog('Not Acceptable, The client has requested a MIME type via the Accept header for a value not supported by the server, '
2704
2703
  + `statusCode: ${statusCode}`);
2705
2704
  break;
2706
2705
  case 415:
2707
- this.errorLog('Unsupported Media Type, The client has defined a contentType header that is not supported by the server, '
2706
+ await this.errorLog('Unsupported Media Type, The client has defined a contentType header that is not supported by the server, '
2708
2707
  + `statusCode: ${statusCode}`);
2709
2708
  break;
2710
2709
  case 422:
2711
- this.errorLog('Unprocessable Entity, The client has made a valid request, but the server cannot process it. This is often used for '
2710
+ await this.errorLog('Unprocessable Entity, The client has made a valid request, but the server cannot process it. This is often used for '
2712
2711
  + `APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
2713
2712
  break;
2714
2713
  case 429:
2715
- this.errorLog('Too Many Requests, The client has exceeded the number of requests allowed for a given time window, '
2714
+ await this.errorLog('Too Many Requests, The client has exceeded the number of requests allowed for a given time window, '
2716
2715
  + `statusCode: ${statusCode}`);
2717
2716
  break;
2718
2717
  case 500:
2719
- this.errorLog('Internal Server Error, An unexpected error on the SmartThings servers has occurred. These errors should be rare, '
2718
+ await this.errorLog('Internal Server Error, An unexpected error on the SmartThings servers has occurred. These errors should be rare, '
2720
2719
  + `statusCode: ${statusCode}`);
2721
2720
  break;
2722
2721
  default:
2723
- this.errorLog(`Unknown statusCode, statusCode: ${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
2722
+ await this.errorLog(`Unknown statusCode, statusCode: ${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
2724
2723
  }
2725
2724
  }
2726
2725
 
@@ -2736,13 +2735,13 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2736
2735
  if (statusCode === 200 || statusCode === 100) {
2737
2736
  return { body, statusCode };
2738
2737
  } else {
2739
- this.debugLog(`Received status code: ${statusCode}`);
2738
+ await this.debugLog(`Received status code: ${statusCode}`);
2740
2739
  }
2741
2740
  } catch (error: any) {
2742
- this.errorLog(`Error making request: ${error.message}`);
2741
+ await this.errorLog(`Error making request: ${error.message}`);
2743
2742
  }
2744
2743
  retryCount++;
2745
- this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`);
2744
+ await this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`);
2746
2745
  await sleep(delayBetweenRetries);
2747
2746
  }
2748
2747
  return { body: null, statusCode: -1 };
@@ -2754,9 +2753,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2754
2753
  try {
2755
2754
  const SwitchBot = (await import('node-switchbot')).SwitchBot;
2756
2755
  queueScheduler.schedule(() => (switchbot = new SwitchBot()));
2756
+ await this.debugLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${switchbot}`);
2757
2757
  } catch (e: any) {
2758
2758
  switchbot = false;
2759
- this.errorLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${switchbot}, Error: ${e}`);
2759
+ await this.errorLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${switchbot}, Error: ${e}`);
2760
2760
  }
2761
2761
  return switchbot;
2762
2762
  }
@@ -2768,7 +2768,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2768
2768
  'utf-8',
2769
2769
  ),
2770
2770
  );
2771
- this.debugLog(`Plugin Version: ${json.version}`);
2771
+ await this.debugLog(`Plugin Version: ${json.version}`);
2772
2772
  this.version = json.version;
2773
2773
  }
2774
2774
 
@@ -2804,7 +2804,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2804
2804
  platformConfig.delayBetweenRetries = this.delayBetweenRetries / 1000;
2805
2805
  }
2806
2806
  if (Object.entries(platformConfig).length !== 0) {
2807
- this.debugLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
2807
+ await this.debugLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
2808
2808
  }
2809
2809
  this.platformConfig = platformConfig;
2810
2810
  }
@@ -2814,13 +2814,13 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2814
2814
  this.debugMode = process.argv.includes('-D') || process.argv.includes('--debug');
2815
2815
  if (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard' || this.config.options?.logging === 'none') {
2816
2816
  this.platformLogging = this.config.options.logging;
2817
- this.debugWarnLog(`Using Config Logging: ${this.platformLogging}`);
2817
+ await this.debugWarnLog(`Using Config Logging: ${this.platformLogging}`);
2818
2818
  } else if (this.debugMode) {
2819
2819
  this.platformLogging = 'debugMode';
2820
- this.debugWarnLog(`Using ${this.platformLogging} Logging`);
2820
+ await this.debugWarnLog(`Using ${this.platformLogging} Logging`);
2821
2821
  } else {
2822
2822
  this.platformLogging = 'standard';
2823
- this.debugWarnLog(`Using ${this.platformLogging} Logging`);
2823
+ await this.debugWarnLog(`Using ${this.platformLogging} Logging`);
2824
2824
  }
2825
2825
  }
2826
2826
 
@@ -2828,56 +2828,56 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2828
2828
  * If device level logging is turned on, log to log.warn
2829
2829
  * Otherwise send debug logs to log.debug
2830
2830
  */
2831
- infoLog(...log: any[]): void {
2832
- if (this.enablingPlatformLogging()) {
2831
+ async infoLog(...log: any[]): Promise<void> {
2832
+ if (await this.enablingPlatformLogging()) {
2833
2833
  this.log.info(String(...log));
2834
2834
  }
2835
2835
  }
2836
2836
 
2837
- successLog(...log: any[]): void {
2838
- if (this.enablingPlatformLogging()) {
2837
+ async successLog(...log: any[]): Promise<void> {
2838
+ if (await this.enablingPlatformLogging()) {
2839
2839
  this.log.success(String(...log));
2840
2840
  }
2841
2841
  }
2842
2842
 
2843
- debugSuccessLog(...log: any[]): void {
2844
- if (this.enablingPlatformLogging()) {
2843
+ async debugSuccessLog(...log: any[]): Promise<void> {
2844
+ if (await this.enablingPlatformLogging()) {
2845
2845
  if (this.platformLogging?.includes('debug')) {
2846
2846
  this.log.success('[DEBUG]', String(...log));
2847
2847
  }
2848
2848
  }
2849
2849
  }
2850
2850
 
2851
- warnLog(...log: any[]): void {
2852
- if (this.enablingPlatformLogging()) {
2851
+ async warnLog(...log: any[]): Promise<void> {
2852
+ if (await this.enablingPlatformLogging()) {
2853
2853
  this.log.warn(String(...log));
2854
2854
  }
2855
2855
  }
2856
2856
 
2857
- debugWarnLog(...log: any[]): void {
2858
- if (this.enablingPlatformLogging()) {
2857
+ async debugWarnLog(...log: any[]): Promise<void> {
2858
+ if (await this.enablingPlatformLogging()) {
2859
2859
  if (this.platformLogging?.includes('debug')) {
2860
2860
  this.log.warn('[DEBUG]', String(...log));
2861
2861
  }
2862
2862
  }
2863
2863
  }
2864
2864
 
2865
- errorLog(...log: any[]): void {
2866
- if (this.enablingPlatformLogging()) {
2865
+ async errorLog(...log: any[]): Promise<void> {
2866
+ if (await this.enablingPlatformLogging()) {
2867
2867
  this.log.error(String(...log));
2868
2868
  }
2869
2869
  }
2870
2870
 
2871
- debugErrorLog(...log: any[]): void {
2872
- if (this.enablingPlatformLogging()) {
2871
+ async debugErrorLog(...log: any[]): Promise<void> {
2872
+ if (await this.enablingPlatformLogging()) {
2873
2873
  if (this.platformLogging?.includes('debug')) {
2874
2874
  this.log.error('[DEBUG]', String(...log));
2875
2875
  }
2876
2876
  }
2877
2877
  }
2878
2878
 
2879
- debugLog(...log: any[]): void {
2880
- if (this.enablingPlatformLogging()) {
2879
+ async debugLog(...log: any[]): Promise<void> {
2880
+ if (await this.enablingPlatformLogging()) {
2881
2881
  if (this.platformLogging === 'debugMode') {
2882
2882
  this.log.debug(String(...log));
2883
2883
  } else if (this.platformLogging === 'debug') {
@@ -2886,7 +2886,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2886
2886
  }
2887
2887
  }
2888
2888
 
2889
- enablingPlatformLogging(): boolean {
2889
+ async enablingPlatformLogging(): Promise<boolean> {
2890
2890
  return this.platformLogging?.includes('debug') || this.platformLogging === 'standard';
2891
2891
  }
2892
2892
  }
@@ -2,15 +2,13 @@
2
2
  *
3
3
  * devicestatus.ts: @switchbot/homebridge-switchbot platform class.
4
4
  */
5
- export { deviceWebhook };
6
-
7
- type deviceWebhook = {
5
+ export type deviceWebhook = {
8
6
  eventType: string,
9
7
  eventVersion: string,
10
8
  context: deviceWebhookContext
11
9
  };
12
10
 
13
- type deviceWebhookContext = {
11
+ export type deviceWebhookContext = {
14
12
  //properties on all devices
15
13
  deviceMac: string;
16
14
  deviceType: string;