@switchbot/homebridge-switchbot 3.5.0-beta.3 → 3.5.0-beta.30

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 (166) hide show
  1. package/CHANGELOG.md +4 -1
  2. package/config.schema.json +147 -9
  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 +347 -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 +582 -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 +209 -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 +250 -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 +204 -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 +335 -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 +646 -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 +499 -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 +242 -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 +207 -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 +174 -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 +252 -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 +210 -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 +170 -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 +159 -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 +136 -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 +82 -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 +140 -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 +121 -664
  78. package/dist/device/waterdetector.js.map +1 -1
  79. package/dist/index.js +1 -1
  80. package/dist/irdevice/airconditioner.d.ts +8 -48
  81. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  82. package/dist/irdevice/airconditioner.js +309 -419
  83. package/dist/irdevice/airconditioner.js.map +1 -1
  84. package/dist/irdevice/airpurifier.d.ts +7 -38
  85. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  86. package/dist/irdevice/airpurifier.js +72 -304
  87. package/dist/irdevice/airpurifier.js.map +1 -1
  88. package/dist/irdevice/camera.d.ts +6 -35
  89. package/dist/irdevice/camera.d.ts.map +1 -1
  90. package/dist/irdevice/camera.js +34 -278
  91. package/dist/irdevice/camera.js.map +1 -1
  92. package/dist/irdevice/fan.d.ts +6 -39
  93. package/dist/irdevice/fan.d.ts.map +1 -1
  94. package/dist/irdevice/fan.js +67 -311
  95. package/dist/irdevice/fan.js.map +1 -1
  96. package/dist/irdevice/irdevice.d.ts +40 -0
  97. package/dist/irdevice/irdevice.d.ts.map +1 -0
  98. package/dist/irdevice/irdevice.js +509 -0
  99. package/dist/irdevice/irdevice.js.map +1 -0
  100. package/dist/irdevice/light.d.ts +6 -34
  101. package/dist/irdevice/light.d.ts.map +1 -1
  102. package/dist/irdevice/light.js +23 -272
  103. package/dist/irdevice/light.js.map +1 -1
  104. package/dist/irdevice/other.d.ts +18 -47
  105. package/dist/irdevice/other.d.ts.map +1 -1
  106. package/dist/irdevice/other.js +352 -546
  107. package/dist/irdevice/other.js.map +1 -1
  108. package/dist/irdevice/tv.d.ts +7 -39
  109. package/dist/irdevice/tv.d.ts.map +1 -1
  110. package/dist/irdevice/tv.js +82 -321
  111. package/dist/irdevice/tv.js.map +1 -1
  112. package/dist/irdevice/vacuumcleaner.d.ts +6 -35
  113. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  114. package/dist/irdevice/vacuumcleaner.js +41 -284
  115. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  116. package/dist/irdevice/waterheater.d.ts +6 -35
  117. package/dist/irdevice/waterheater.d.ts.map +1 -1
  118. package/dist/irdevice/waterheater.js +42 -287
  119. package/dist/irdevice/waterheater.js.map +1 -1
  120. package/dist/platform.d.ts +14 -1
  121. package/dist/platform.d.ts.map +1 -1
  122. package/dist/platform.js +237 -94
  123. package/dist/platform.js.map +1 -1
  124. package/dist/settings.d.ts +40 -10
  125. package/dist/settings.d.ts.map +1 -1
  126. package/dist/settings.js +0 -552
  127. package/dist/settings.js.map +1 -1
  128. package/dist/utils.d.ts +77 -0
  129. package/dist/utils.d.ts.map +1 -1
  130. package/dist/utils.js +638 -1
  131. package/dist/utils.js.map +1 -1
  132. package/package.json +16 -15
  133. package/src/custom.d.ts +2 -1
  134. package/src/device/blindtilt.ts +373 -782
  135. package/src/device/bot.ts +616 -844
  136. package/src/device/ceilinglight.ts +222 -607
  137. package/src/device/colorbulb.ts +264 -656
  138. package/src/device/contact.ts +229 -553
  139. package/src/device/curtain.ts +355 -810
  140. package/src/device/device.ts +673 -0
  141. package/src/device/fan.ts +548 -0
  142. package/src/device/hub.ts +268 -623
  143. package/src/device/humidifier.ts +237 -618
  144. package/src/device/iosensor.ts +200 -610
  145. package/src/device/lightstrip.ts +273 -596
  146. package/src/device/lock.ts +247 -582
  147. package/src/device/meter.ts +196 -601
  148. package/src/device/meterplus.ts +184 -602
  149. package/src/device/motion.ts +156 -541
  150. package/src/device/plug.ts +92 -480
  151. package/src/device/robotvacuumcleaner.ts +161 -477
  152. package/src/device/waterdetector.ts +139 -689
  153. package/src/index.ts +1 -1
  154. package/src/irdevice/airconditioner.ts +330 -446
  155. package/src/irdevice/airpurifier.ts +89 -321
  156. package/src/irdevice/camera.ts +42 -293
  157. package/src/irdevice/fan.ts +78 -327
  158. package/src/irdevice/irdevice.ts +526 -0
  159. package/src/irdevice/light.ts +32 -287
  160. package/src/irdevice/other.ts +396 -615
  161. package/src/irdevice/tv.ts +100 -339
  162. package/src/irdevice/vacuumcleaner.ts +49 -305
  163. package/src/irdevice/waterheater.ts +50 -310
  164. package/src/platform.ts +247 -102
  165. package/src/settings.ts +56 -565
  166. 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,66 @@ 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;
209
+ }
210
+ if (Number.isNaN(this.Battery.BatteryLevel)) {
211
+ this.Battery.BatteryLevel = 100;
252
212
  }
253
- this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
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`);
224
+ this.TemperatureSensor!.CurrentTemperature = deviceStatus.body.temperature!;
225
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.TemperatureSensor!.CurrentTemperature}°c`);
265
226
  }
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;
273
- }
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
+ this.accessory.context.FirmwareRevision = deviceStatus.body.version;
229
+ this.accessory
230
+ .getService(this.hap.Service.AccessoryInformation)!
231
+ .setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.accessory.context.FirmwareRevision)
232
+ .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
233
+ .updateValue(this.accessory.context.FirmwareRevision);
283
234
  }
284
235
 
285
236
  /**
@@ -313,108 +264,44 @@ export class MeterPlus {
313
264
  this.getCustomBLEAddress(switchbot);
314
265
  // Start to monitor advertisement packets
315
266
  (async () => {
316
- await switchbot.startScan({
317
- model: 'i',
318
- id: this.device.bleMac,
319
- });
267
+ // Start to monitor advertisement packets
268
+ await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
320
269
  // Set an event handler
321
270
  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') {
271
+ if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
272
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
273
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
325
274
  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
275
  } else {
332
276
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
333
277
  }
334
278
  };
335
- // Wait 1 seconds
279
+ // Wait 10 seconds
336
280
  await switchbot.wait(this.scanDuration * 1000);
337
281
  // Stop to monitor
338
282
  await switchbot.stopScan();
339
283
  // Update HomeKit
340
- await this.BLEparseStatus();
284
+ await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
341
285
  await this.updateHomeKitCharacteristics();
342
286
  })();
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 {
287
+ if (switchbot === undefined) {
396
288
  await this.BLERefreshConnection(switchbot);
397
- }*/
289
+ }
398
290
  }
399
291
 
400
292
  async openAPIRefreshStatus(): Promise<void> {
401
293
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
402
294
  try {
403
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
404
- headers: this.platform.generateHeaders(),
405
- });
295
+ const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
296
+ `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
406
297
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
407
298
  const deviceStatus: any = await body.json();
408
299
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
409
300
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
410
301
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
411
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
302
+ this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
412
303
  + `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();
304
+ this.openAPIparseStatus(deviceStatus);
418
305
  this.updateHomeKitCharacteristics();
419
306
  } else {
420
307
  this.statusCode(statusCode);
@@ -438,67 +325,73 @@ export class MeterPlus {
438
325
 
439
326
  // CurrentRelativeHumidity
440
327
  if (!this.device.meter?.hide_humidity) {
441
- if (this.CurrentRelativeHumidity === undefined) {
442
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
328
+ if (this.HumiditySensor!.CurrentRelativeHumidity === undefined) {
329
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
330
+ + ` CurrentRelativeHumidity: ${this.HumiditySensor!.CurrentRelativeHumidity}`);
443
331
  } else {
332
+ this.accessory.context.CurrentRelativeHumidity = this.HumiditySensor!.CurrentRelativeHumidity;
333
+ this.HumiditySensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity,
334
+ this.HumiditySensor!.CurrentRelativeHumidity);
335
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
336
+ + ` updateCharacteristic CurrentRelativeHumidity: ${this.HumiditySensor!.CurrentRelativeHumidity}`);
444
337
  if (this.device.mqttURL) {
445
- mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
338
+ mqttmessage.push(`"humidity": ${this.HumiditySensor!.CurrentRelativeHumidity}`);
446
339
  }
447
340
  if (this.device.history) {
448
- entry['humidity'] = this.CurrentRelativeHumidity;
341
+ entry['humidity'] = this.HumiditySensor!.CurrentRelativeHumidity;
449
342
  }
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
343
  }
457
344
  }
345
+
458
346
  // CurrentTemperature
459
347
  if (!this.device.meter?.hide_temperature) {
460
- if (this.CurrentTemperature === undefined) {
461
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
348
+ if (this.TemperatureSensor!.CurrentTemperature === undefined) {
349
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.TemperatureSensor!.CurrentTemperature}`);
462
350
  } else {
351
+ this.accessory.context.CurrentTemperature = this.TemperatureSensor!.CurrentTemperature;
352
+ this.TemperatureSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.TemperatureSensor!.CurrentTemperature);
353
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
354
+ + ` CurrentTemperature: ${this.TemperatureSensor!.CurrentTemperature}`);
463
355
  if (this.device.mqttURL) {
464
- mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
356
+ mqttmessage.push(`"temperature": ${this.TemperatureSensor!.CurrentTemperature}`);
465
357
  }
466
358
  if (this.device.history) {
467
- entry['temp'] = this.CurrentTemperature;
359
+ entry['temp'] = this.TemperatureSensor!.CurrentTemperature;
468
360
  }
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
361
  }
473
362
  }
363
+
474
364
  // BatteryLevel
475
- if (this.BatteryLevel === undefined) {
476
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
365
+ if (this.Battery.BatteryLevel === undefined) {
366
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
477
367
  } else {
368
+ this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
369
+ this.Battery!.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
370
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
478
371
  if (this.device.mqttURL) {
479
- mqttmessage.push(`"battery": ${this.BatteryLevel}`);
372
+ mqttmessage.push(`"battery": ${this.Battery.BatteryLevel}`);
480
373
  }
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
374
  }
485
375
  // StatusLowBattery
486
- if (this.StatusLowBattery === undefined) {
487
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
376
+ if (this.Battery.StatusLowBattery === undefined) {
377
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
488
378
  } else {
379
+ this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
380
+ this.Battery!.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
381
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
382
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
489
383
  if (this.device.mqttURL) {
490
- mqttmessage.push(`"lowBattery": ${this.StatusLowBattery}`);
384
+ mqttmessage.push(`"lowBattery": ${this.Battery.StatusLowBattery}`);
491
385
  }
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
386
  }
496
387
 
497
- // MQTT
388
+ // MQTT Publish
498
389
  if (this.device.mqttURL) {
499
390
  this.mqttPublish(`{${mqttmessage.join(',')}}`);
500
391
  }
501
- if (Number(this.CurrentRelativeHumidity) > 0) {
392
+
393
+ // History Service
394
+ if (!this.device.meter?.hide_humidity && (Number(this.HumiditySensor!.CurrentRelativeHumidity) > 0)) {
502
395
  // reject unreliable data
503
396
  if (this.device.history) {
504
397
  this.historyService?.addEntry(entry);
@@ -506,84 +399,6 @@ export class MeterPlus {
506
399
  }
507
400
  }
508
401
 
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
402
  async BLERefreshConnection(switchbot: any): Promise<void> {
588
403
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
589
404
  + ` ${JSON.stringify(switchbot)}`);
@@ -593,259 +408,26 @@ export class MeterPlus {
593
408
  }
594
409
  }
595
410
 
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
411
  async offlineOff(): Promise<void> {
699
412
  if (this.device.offline) {
700
- await this.deviceContext();
701
- await this.updateHomeKitCharacteristics();
413
+ if (!this.device.meter?.hide_humidity) {
414
+ this.HumiditySensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, 50);
415
+ }
416
+ if (!this.device.meter?.hide_temperature) {
417
+ this.TemperatureSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, 30);
418
+ }
419
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, 100);
702
420
  }
703
421
  }
704
422
 
705
423
  async apiError(e: any): Promise<void> {
706
424
  if (!this.device.meter?.hide_humidity) {
707
- this.humidityService?.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, e);
425
+ this.HumiditySensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, e);
708
426
  }
709
427
  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;
428
+ this.TemperatureSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e);
767
429
  }
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';
430
+ this.Battery!.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
431
+ this.Battery!.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
850
432
  }
851
433
  }