homebridge-blueair-purifier 0.1.0 → 0.2.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAK5H,OAAsB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGzE,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,qBAAa,eAAgB,SAAQ,YAAa,YAAW,qBAAqB;aAW9D,GAAG,EAAE,MAAM;aACX,MAAM,EAAE,cAAc;aACtB,GAAG,EAAE,GAAG;IAZ1B,SAAgB,OAAO,EAAE,OAAO,OAAO,CAAwB;IAC/D,SAAgB,cAAc,EAAE,OAAO,cAAc,CAA+B;IAGpF,SAAgB,WAAW,EAAE,iBAAiB,EAAE,CAAM;IAEtD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;gBAGzB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,GAAG;IA2B1B,kBAAkB,CAAC,SAAS,EAAE,iBAAiB;IAOzC,sBAAsB;IAmB5B,SAAS,CAAC,MAAM,EAAE,mBAAmB;CAsBtC"}
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAK5H,OAAsB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGzE,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,qBAAa,eAAgB,SAAQ,YAAa,YAAW,qBAAqB;aAgB9D,GAAG,EAAE,MAAM;aACX,MAAM,EAAE,cAAc;aACtB,GAAG,EAAE,GAAG;IAjB1B,SAAgB,OAAO,EAAE,OAAO,OAAO,CAAwB;IAC/D,SAAgB,cAAc,EAAE,OAAO,cAAc,CAA+B;IAGpF,SAAgB,WAAW,EAAE,iBAAiB,EAAE,CAAM;IAEtD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAE3C,OAAO,CAAC,aAAa,CAAgB;IAErC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,OAAO,CAA+B;gBAG5B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,GAAG;IAqB1B,kBAAkB,CAAC,SAAS,EAAE,iBAAiB;IAKzC,qBAAqB;IAmBrB,sBAAsB;IAuBtB,SAAS,CAAC,MAAM,EAAE,mBAAmB;CA0C5C"}
package/dist/platform.js CHANGED
@@ -21,6 +21,9 @@ class BlueAirPlatform extends events_1.default {
21
21
  this.Characteristic = this.api.hap.Characteristic;
22
22
  // this is used to track restored cached accessories
23
23
  this.accessories = [];
24
+ this.existingUuids = [];
25
+ this.devices = [];
26
+ this.polling = null;
24
27
  this.platformConfig = (0, lodash_1.defaultsDeep)(config, platformUtils_1.defaultConfig);
25
28
  if (!this.platformConfig.username || !this.platformConfig.password || !this.platformConfig.accountUuid) {
26
29
  this.log.error('Missing required configuration options! Please do the device discovery in the configuration UI and/or check your\
@@ -29,48 +32,81 @@ class BlueAirPlatform extends events_1.default {
29
32
  this.blueAirApi = new BlueAirAwsApi_1.default(this.platformConfig.username, this.platformConfig.password, this.platformConfig.region, log);
30
33
  this.api.on('didFinishLaunching', async () => {
31
34
  await this.getInitialDeviceStates();
32
- });
33
- this.on('setState', async ({ id, state, value }) => {
34
- this.log.info(`[${id}] Setting state: ${state} = ${value}`);
35
- try {
36
- await this.blueAirApi.setDeviceStatus(id, state, value);
37
- }
38
- catch (error) {
39
- this.log.error(`[${id}] Error setting state: ${state} = ${value}`, error);
40
- }
35
+ this.polling = setInterval(this.getValidDevicesStatus.bind(this), this.platformConfig.pollingInterval);
41
36
  });
42
37
  }
43
38
  configureAccessory(accessory) {
44
39
  this.log.info('Loading accessory from cache:', accessory.displayName);
45
- // add the restored accessory to the accessories cache so we can track if it has already been registered
46
40
  this.accessories.push(accessory);
47
41
  }
42
+ async getValidDevicesStatus() {
43
+ this.log.debug('Updating devices states...');
44
+ try {
45
+ const devices = await this.blueAirApi.getDeviceStatus(this.platformConfig.accountUuid, this.existingUuids);
46
+ for (const device of devices) {
47
+ const blueAirDevice = this.devices.find((d) => d.id === device.id);
48
+ if (!blueAirDevice) {
49
+ this.log.error(`[${device.name}] Device not found in cache!`);
50
+ continue;
51
+ }
52
+ this.log.debug(`[${device.name}] Updating device state...`);
53
+ blueAirDevice.emit('update', device);
54
+ }
55
+ this.log.debug('Devices states updated!');
56
+ }
57
+ catch (error) {
58
+ this.log.error('Error getting valid devices status:', error);
59
+ }
60
+ }
48
61
  async getInitialDeviceStates() {
62
+ this.log.info('Getting initial device states...');
49
63
  try {
50
64
  await this.blueAirApi.login();
51
- let uuids = this.platformConfig.devices.map(device => device.id);
65
+ let uuids = this.platformConfig.devices.map((device) => device.id);
52
66
  const devices = await this.blueAirApi.getDeviceStatus(this.platformConfig.accountUuid, uuids);
53
67
  for (const device of devices) {
54
68
  this.addDevice(device);
55
- uuids = uuids.filter(uuid => uuid !== device.id);
69
+ uuids = uuids.filter((uuid) => uuid !== device.id);
56
70
  }
57
71
  for (const uuid of uuids) {
58
- this.log.warn(`[${uuid}] Device not found in AWS API response!`);
72
+ const device = this.platformConfig.devices.find((device) => device.id === uuid);
73
+ this.log.warn(`[${device.name}] Device not found in AWS API response!`);
59
74
  }
75
+ this.log.info('All configured devices have been added!');
60
76
  }
61
77
  catch (error) {
62
78
  this.log.error('Error getting initial device states:', error);
63
79
  }
64
80
  }
65
- addDevice(device) {
81
+ async addDevice(device) {
66
82
  const uuid = this.api.hap.uuid.generate(device.id);
67
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
68
- const deviceConfig = this.platformConfig.devices.find(config => config.id === device.id);
83
+ const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
84
+ const deviceConfig = this.platformConfig.devices.find((config) => config.id === device.id);
85
+ this.existingUuids.push(device.id);
69
86
  if (!deviceConfig) {
70
- this.log.error(`[${device.id}] Device configuration not found!`);
87
+ this.log.error(`[${device.name}] Device configuration not found!`);
71
88
  return;
72
89
  }
73
- const blueAirDevice = new BlueAirDevice_1.BlueAirDevice(device.id);
90
+ const blueAirDevice = new BlueAirDevice_1.BlueAirDevice(device);
91
+ this.devices.push(blueAirDevice);
92
+ blueAirDevice.on('setState', async ({ id, name, attribute, value }) => {
93
+ // this.log.info(`[${name}] Setting state: ${attribute} = ${value}`);
94
+ // Clear polling to avoid conflicts
95
+ this.polling && clearInterval(this.polling);
96
+ let success = false;
97
+ try {
98
+ await this.blueAirApi.setDeviceStatus(id, attribute, value);
99
+ success = true;
100
+ }
101
+ catch (error) {
102
+ this.log.error(`[${name}] Error setting state: ${attribute} = ${value}`, error);
103
+ }
104
+ finally {
105
+ blueAirDevice.emit('setStateDone', success);
106
+ // Restart polling
107
+ this.polling = setInterval(this.getValidDevicesStatus.bind(this), this.platformConfig.pollingInterval);
108
+ }
109
+ });
74
110
  if (existingAccessory) {
75
111
  this.log.info(`[${deviceConfig.name}] Restoring existing accessory from cache: ${existingAccessory.displayName}`);
76
112
  new AirPurifierAccessory_1.AirPurifierAccessory(this, existingAccessory, blueAirDevice, deviceConfig);
@@ -1 +1 @@
1
- {"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,17 @@
1
1
  export type Config = {
2
- verboseLogging: boolean;
3
- uiDebug: boolean;
4
2
  username: string;
5
3
  password: string;
6
- accountUuid: string;
7
4
  region: Region;
5
+ accountUuid: string;
6
+ verboseLogging: boolean;
7
+ uiDebug: boolean;
8
+ pollingInterval: number;
8
9
  devices: DeviceConfig[];
9
10
  };
10
11
  export type DeviceConfig = {
11
12
  id: string;
12
13
  name: string;
14
+ filterChangeLevel: number;
13
15
  led: boolean;
14
16
  airQualitySensor: boolean;
15
17
  co2Sensor: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"platformUtils.d.ts","sourceRoot":"","sources":["../src/platformUtils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,oBAAY,MAAM;IAChB,EAAE,gCAAgC;IAClC,EAAE,cAAc;IAChB,EAAE,UAAU;IACZ,EAAE,WAAW;IACb,EAAE,QAAQ;CACX;AAED,eAAO,MAAM,SAAS;;;;;;CAMrB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAQ3B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,YAUjC,CAAC"}
1
+ {"version":3,"file":"platformUtils.d.ts","sourceRoot":"","sources":["../src/platformUtils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,GAAG,EAAE,OAAO,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,oBAAY,MAAM;IAChB,EAAE,gCAAgC;IAClC,EAAE,cAAc;IAChB,EAAE,UAAU;IACZ,EAAE,WAAW;IACb,EAAE,QAAQ;CACX;AAED,eAAO,MAAM,SAAS;;;;;;CAMrB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAS3B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,YAWjC,CAAC"}
@@ -23,11 +23,13 @@ exports.defaultConfig = {
23
23
  password: '',
24
24
  accountUuid: '',
25
25
  region: Region.EU,
26
+ pollingInterval: 5000,
26
27
  devices: [],
27
28
  };
28
29
  exports.defaultDeviceConfig = {
29
30
  id: '',
30
31
  name: '',
32
+ filterChangeLevel: 90,
31
33
  led: false,
32
34
  airQualitySensor: false,
33
35
  co2Sensor: false,
@@ -1 +1 @@
1
- {"version":3,"file":"platformUtils.js","sourceRoot":"","sources":["../src/platformUtils.ts"],"names":[],"mappings":";;;AAsBA,IAAY,MAMX;AAND,WAAY,MAAM;IAChB,4CAAkC,CAAA;IAClC,0BAAgB,CAAA;IAChB,sBAAY,CAAA;IACZ,uBAAa,CAAA;IACb,oBAAU,CAAA;AACZ,CAAC,EANW,MAAM,sBAAN,MAAM,QAMjB;AAEY,QAAA,SAAS,GAAG;IACvB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI;IACjB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI;IACjB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI;IACjB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI;IACjB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI;CAClB,CAAC;AAEW,QAAA,aAAa,GAAW;IACnC,OAAO,EAAE,KAAK;IACd,cAAc,EAAE,KAAK;IACrB,QAAQ,EAAE,EAAE;IACZ,QAAQ,EAAE,EAAE;IACZ,WAAW,EAAE,EAAE;IACf,MAAM,EAAE,MAAM,CAAC,EAAE;IACjB,OAAO,EAAE,EAAE;CACZ,CAAC;AAEW,QAAA,mBAAmB,GAAiB;IAC/C,EAAE,EAAE,EAAE;IACN,IAAI,EAAE,EAAE;IACR,GAAG,EAAE,KAAK;IACV,gBAAgB,EAAE,KAAK;IACvB,SAAS,EAAE,KAAK;IAChB,iBAAiB,EAAE,KAAK;IACxB,cAAc,EAAE,KAAK;IACrB,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,KAAK;CACjB,CAAC"}
1
+ {"version":3,"file":"platformUtils.js","sourceRoot":"","sources":["../src/platformUtils.ts"],"names":[],"mappings":";;;AAwBA,IAAY,MAMX;AAND,WAAY,MAAM;IAChB,4CAAkC,CAAA;IAClC,0BAAgB,CAAA;IAChB,sBAAY,CAAA;IACZ,uBAAa,CAAA;IACb,oBAAU,CAAA;AACZ,CAAC,EANW,MAAM,sBAAN,MAAM,QAMjB;AAEY,QAAA,SAAS,GAAG;IACvB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI;IACjB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI;IACjB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI;IACjB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI;IACjB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI;CAClB,CAAC;AAEW,QAAA,aAAa,GAAW;IACnC,OAAO,EAAE,KAAK;IACd,cAAc,EAAE,KAAK;IACrB,QAAQ,EAAE,EAAE;IACZ,QAAQ,EAAE,EAAE;IACZ,WAAW,EAAE,EAAE;IACf,MAAM,EAAE,MAAM,CAAC,EAAE;IACjB,eAAe,EAAE,IAAI;IACrB,OAAO,EAAE,EAAE;CACZ,CAAC;AAEW,QAAA,mBAAmB,GAAiB;IAC/C,EAAE,EAAE,EAAE;IACN,IAAI,EAAE,EAAE;IACR,iBAAiB,EAAE,EAAE;IACrB,GAAG,EAAE,KAAK;IACV,gBAAgB,EAAE,KAAK;IACvB,SAAS,EAAE,KAAK;IAChB,iBAAiB,EAAE,KAAK;IACxB,cAAc,EAAE,KAAK;IACrB,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,KAAK;CACjB,CAAC"}
@@ -33,6 +33,7 @@
33
33
  <option value="China">China</option>
34
34
  <option value="Russia">Russia</option>
35
35
  <option value="USA">USA</option>
36
+ </select>
36
37
  </div>
37
38
  <button class="btn btn-primary btn-login" type="submit" id="discoverBtn" style="border: 0;">
38
39
  Discover Devices on account
@@ -42,9 +43,9 @@
42
43
  <table class="table table-sm" id="discoverTable">
43
44
  <thead>
44
45
  <tr>
46
+ <th scope="col">Name</th>
45
47
  <th scope="col">Id</th>
46
48
  <th scope="col">Mac</th>
47
- <th scope="col">Account UUID</th>
48
49
  <th scope="col">Add&nbsp;/&nbsp;Update</th>
49
50
  </tr>
50
51
  </thead>
@@ -180,7 +181,7 @@
180
181
 
181
182
  console.info(`Request login...`);
182
183
  try {
183
- const devices = await homebridge.request('/disover', { username, password, region });
184
+ const devices = await homebridge.request('/discover', { username, password, region });
184
185
  debugLog(`Discovered devices:\n${JSON.stringify(devices, null, 2)}`);
185
186
  const table = document.getElementById('discoverTable').getElementsByTagName('tbody')[0];
186
187
  table.innerHTML = '';
@@ -206,11 +207,11 @@
206
207
  const state = initialStates.find((s) => s.id === device.uuid);
207
208
  const tr = table.insertRow();
208
209
  const td = tr.insertCell();
209
- td.appendChild(document.createTextNode(device.uuid));
210
+ td.appendChild(document.createTextNode(state.name));
210
211
  td.setAttribute('scope', 'row');
211
212
 
213
+ tr.insertCell().appendChild(document.createTextNode(device.uuid));
212
214
  tr.insertCell().appendChild(document.createTextNode(device.mac));
213
- tr.insertCell().appendChild(document.createTextNode(device.name));
214
215
 
215
216
  const addCell = tr.insertCell();
216
217
  if (currentConfig.devices.find((d) => d.id === device.uuid)) {
@@ -1,6 +1,6 @@
1
1
  const { HomebridgePluginUiServer, RequestError } = require('@homebridge/plugin-ui-utils');
2
2
  const { defaultConfig, defaultDeviceConfig } = require('../dist/platformUtils.js');
3
- const { BlueAirAwsApi } = require('../dist/api/BlueAirAwsApi.js').default;
3
+ const BlueAirAwsApi = require('../dist/api/BlueAirAwsApi.js').default;
4
4
 
5
5
  var _ = require('lodash');
6
6
 
@@ -96,6 +96,7 @@ class UiServer extends HomebridgePluginUiServer {
96
96
  return devices;
97
97
  } catch (e) {
98
98
  const msg = e instanceof Error ? e.stack : e;
99
+ this.logger.error(`Device discovery failed:\n${msg}`);
99
100
  throw new RequestError(`Device discovery failed:\n${msg}`);
100
101
  }
101
102
  });
@@ -105,6 +106,7 @@ class UiServer extends HomebridgePluginUiServer {
105
106
  return await this.api.getDeviceStatus(accountUuid, uuids);
106
107
  } catch (e) {
107
108
  const msg = e instanceof Error ? e.stack : e;
109
+ this.logger.error(`Failed to get initial device states:\n${msg}`);
108
110
  throw new RequestError(`Failed to get initial device states:\n${msg}`);
109
111
  }
110
112
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "Homebridge BlueAir Platform",
3
3
  "name": "homebridge-blueair-purifier",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "description": "Homebridge plugin for BlueAir purifiers",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -11,19 +11,39 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/kovapatrik/homebridge-blueair-purifier/issues"
13
13
  },
14
+ "funding": [
15
+ {
16
+ "type": "github",
17
+ "url": "https://github.com/sponsors/kovapatrik"
18
+ },
19
+ {
20
+ "type": "buymeacoffee",
21
+ "url": "https://www.buymeacoffee.com/kovapatrik"
22
+ }
23
+ ],
14
24
  "engines": {
15
25
  "node": "^18.17.0 || ^20.9.0",
16
26
  "homebridge": "^1.6.0"
17
27
  },
18
28
  "main": "dist/index.js",
19
29
  "scripts": {
20
- "lint": "eslint src/**/*.ts --max-warnings=0",
30
+ "lint": "eslint . --cache --ext .ts",
21
31
  "watch": "npm run build && npm link && nodemon",
22
32
  "build": "rimraf ./dist && tsc",
23
- "prepublishOnly": "npm run lint && npm run build"
33
+ "prepublishOnly": "npm run lint && npm run build",
34
+ "format": "prettier --log-level warn --write \"**/*.ts\" && npm run lint -- --fix"
35
+ },
36
+ "lint-staged": {
37
+ "*.ts": [
38
+ "prettier --write",
39
+ "eslint --fix"
40
+ ]
24
41
  },
25
42
  "keywords": [
26
- "homebridge-plugin"
43
+ "homebridge-plugin",
44
+ "blueair",
45
+ "purifier",
46
+ "air purifier"
27
47
  ],
28
48
  "devDependencies": {
29
49
  "@types/lodash": "^4.17.0",
@@ -31,15 +51,18 @@
31
51
  "@typescript-eslint/eslint-plugin": "^7.5.0",
32
52
  "@typescript-eslint/parser": "^7.5.0",
33
53
  "eslint": "^8.57.0",
34
- "homebridge": "^1.7.0",
54
+ "eslint-config-prettier": "^9.1.0",
55
+ "eslint-plugin-prettier": "^5.1.3",
56
+ "homebridge": "^1.8.1",
35
57
  "nodemon": "^3.1.0",
58
+ "prettier": "^3.2.5",
36
59
  "rimraf": "^5.0.5",
37
60
  "ts-node": "^10.9.2",
38
61
  "typescript": "^5.4.4"
39
62
  },
40
63
  "dependencies": {
41
64
  "@homebridge/plugin-ui-utils": "^1.0.3",
42
- "axios": "^1.6.8",
43
- "lodash": "^4.17.21"
65
+ "lodash": "^4.17.21",
66
+ "semaphore-promise": "^1.4.2"
44
67
  }
45
68
  }