@switchbot/homebridge-switchbot 3.5.0-beta.4 → 3.5.0-beta.40

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