@smarterhomeapp/homebridge-vantage 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Homebridge Vantage Controls
2
+ [![verified-by-homebridge](https://img.shields.io/badge/homebridge-verified-blueviolet?color=%23491F59&style=flat)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
2
3
 
3
- A [Homebridge](https://homebridge.io/) plugin for Vantage Controls InFusion system.
4
+ A [Homebridge](https://homebridge.io/) plugin for Vantage Controls InFusion system.
5
+ This plugin replaces the one sold on smarterhome.io allowing anyone to download on the platform of their choice.
4
6
 
5
7
  ## Features
6
8
 
@@ -20,7 +22,7 @@ npm install -g homebridge
20
22
 
21
23
  2. Install this plugin:
22
24
  ```bash
23
- npm install -g homebridge-vantage
25
+ npm install -g @smarterhomeapp/homebridge-vantage
24
26
  ```
25
27
 
26
28
  3. Add the platform to your `config.json`:
@@ -74,7 +76,7 @@ npm install -g homebridge-vantage
74
76
 
75
77
  1. Clone the repository:
76
78
  ```bash
77
- git clone https://github.com/yourusername/homebridge-vantage.git
79
+ git clone https://github.com/smarterhomeapp/homebridge-vantage.git
78
80
  cd homebridge-vantage
79
81
  ```
80
82
 
@@ -125,5 +127,5 @@ MIT License - see LICENSE file for details.
125
127
  ## Support
126
128
 
127
129
  For issues and questions:
128
- - [GitHub Issues](https://github.com/yourusername/homebridge-vantage/issues)
129
- - [Homebridge Community](https://github.com/homebridge/homebridge)
130
+ - [GitHub Issues](https://github.com/smarterhomeapp/homebridge-vantage/issues)
131
+ - [Homebridge Community](https://github.com/homebridge/homebridge)
@@ -29,6 +29,10 @@ export declare class VantageInfusion extends EventEmitter {
29
29
  /** XML/config discovery; returns devices (replaces old Discover/DiscoverSSL) */
30
30
  discoverDevices(): Promise<VantageDevice[]>;
31
31
  private processConfigurationXml;
32
+ /** Escape text for XML (same as sanitize in index.js). */
33
+ private static escapeXml;
34
+ /** Build cache XML from readObjects (same structure + sanitization as original index.js). */
35
+ private buildCacheXml;
32
36
  private pullConfigurationXml;
33
37
  setBrightness(vid: string, level: number): Promise<void>;
34
38
  setHue(vid: string, hue: number): Promise<void>;
@@ -48,6 +48,7 @@ const TYPE_THERMO = [
48
48
  'Tekmar.tN4_Gateway_482_Zone_-_Slab_Only_CHILD',
49
49
  'Tekmar.tN4_Gateway_482_Zone_CHILD',
50
50
  'Legrand.MH_HVAC_Control_CHILD',
51
+ 'Vantage.HVAC-IU-Zone_CHILD'
51
52
  ];
52
53
  const TYPE_BLIND = [
53
54
  'Blind',
@@ -294,6 +295,7 @@ class VantageInfusion extends events_1.EventEmitter {
294
295
  const rangeStr = (this.opts.range || '0,999999999').replace(/\s+/g, '');
295
296
  const [minVID, maxVID] = rangeStr.split(',').map((x) => Number.parseInt(x, 10));
296
297
  const blindOpenClose = {};
298
+ const seenNames = new Set();
297
299
  for (const raw of objects) {
298
300
  const key = Object.keys(raw)[0];
299
301
  const it = raw[key];
@@ -310,6 +312,11 @@ class VantageInfusion extends events_1.EventEmitter {
310
312
  if (it.Area && Area[it.Area]?.Name)
311
313
  name = `${Area[it.Area].Name} ${name}`;
312
314
  name = name.replace(/-/g, '') || `VID${vid}`;
315
+ const nameKey = name.toLowerCase();
316
+ if (seenNames.has(nameKey)) {
317
+ name = `${name} VID${vid}`;
318
+ }
319
+ seenNames.add(name.toLowerCase());
313
320
  const pushUnique = (dev) => {
314
321
  if (devices.find((d) => d.vid === vid))
315
322
  return;
@@ -413,6 +420,25 @@ class VantageInfusion extends events_1.EventEmitter {
413
420
  }
414
421
  return filtered;
415
422
  }
423
+ /** Escape text for XML (same as sanitize in index.js). */
424
+ static escapeXml(s) {
425
+ return String(s)
426
+ .replace(/&/g, '&amp;')
427
+ .replace(/</g, '&lt;')
428
+ .replace(/>/g, '&gt;')
429
+ .replace(/"/g, '&quot;')
430
+ .replace(/'/g, '&apos;');
431
+ }
432
+ /** Build cache XML from readObjects (same structure + sanitization as original index.js). */
433
+ buildCacheXml(readObjects) {
434
+ const frag = readObjects.map((o) => {
435
+ const k = Object.keys(o)[0];
436
+ const v = o[k];
437
+ const body = Object.keys(v).map((kk) => `<${kk}>${VantageInfusion.escapeXml(String(v[kk]))}</${kk}>`).join('');
438
+ return `<Object><${k}>${body}</${k}></Object>`;
439
+ }).join('');
440
+ return `<Project><Objects>${frag}</Objects></Project>`;
441
+ }
416
442
  pullConfigurationXml() {
417
443
  return new Promise((resolve) => {
418
444
  const finishOnce = (socket, xml) => {
@@ -456,15 +482,7 @@ class VantageInfusion extends events_1.EventEmitter {
456
482
  return;
457
483
  }
458
484
  if (readObjects.length && Date.now() - lastProgress > 2000) {
459
- // Build minimal XML with what we gathered
460
- const xml = '<Project><Objects>' +
461
- readObjects.map((o) => {
462
- const k = Object.keys(o)[0];
463
- const v = o[k];
464
- const body = Object.keys(v).map((kk) => `<${kk}>${String(v[kk])}</${kk}>`).join('');
465
- return `<Object><${k}>${body}</${k}></Object>`;
466
- }).join('') +
467
- '</Objects></Project>';
485
+ const xml = this.buildCacheXml(readObjects);
468
486
  clearInterval(watchdog);
469
487
  finishOnce(socket, xml);
470
488
  }
@@ -572,14 +590,7 @@ class VantageInfusion extends events_1.EventEmitter {
572
590
  }
573
591
  // ----- END CONDITION -----
574
592
  if (shouldBreak) {
575
- const xml = '<Project><Objects>' +
576
- readObjects.map((o) => {
577
- const k = Object.keys(o)[0];
578
- const v = o[k];
579
- const body = Object.keys(v).map((kk) => `<${kk}>${String(v[kk])}</${kk}>`).join('');
580
- return `<Object><${k}>${body}</${k}></Object>`;
581
- }).join('') +
582
- '</Objects></Project>';
593
+ const xml = this.buildCacheXml(readObjects);
583
594
  clearLoginFallback();
584
595
  clearInterval(watchdog);
585
596
  finishOnce(socket, xml);
@@ -589,14 +600,7 @@ class VantageInfusion extends events_1.EventEmitter {
589
600
  socket.on('end', () => {
590
601
  this.opts.log.info("ending" + shouldBreak);
591
602
  if (!finishOnce._done && readObjects.length) {
592
- const xml = '<Project><Objects>' +
593
- readObjects.map((o) => {
594
- const k = Object.keys(o)[0];
595
- const v = o[k];
596
- const body = Object.keys(v).map((kk) => `<${kk}>${String(v[kk])}</${kk}>`).join('');
597
- return `<Object><${k}>${body}</${k}></Object>`;
598
- }).join('') +
599
- '</Objects></Project>';
603
+ const xml = this.buildCacheXml(readObjects);
600
604
  clearLoginFallback();
601
605
  clearInterval(watchdog);
602
606
  finishOnce(socket, xml);
@@ -605,14 +609,7 @@ class VantageInfusion extends events_1.EventEmitter {
605
609
  socket.on('close', () => {
606
610
  this.opts.log.debug("closing " + shouldBreak);
607
611
  if (!finishOnce._done && readObjects.length) {
608
- const xml = '<Project><Objects>' +
609
- readObjects.map((o) => {
610
- const k = Object.keys(o)[0];
611
- const v = o[k];
612
- const body = Object.keys(v).map((kk) => `<${kk}>${String(v[kk])}</${kk}>`).join('');
613
- return `<Object><${k}>${body}</${k}></Object>`;
614
- }).join('') +
615
- '</Objects></Project>';
612
+ const xml = this.buildCacheXml(readObjects);
616
613
  clearLoginFallback();
617
614
  clearInterval(watchdog);
618
615
  finishOnce(socket, xml);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smarterhomeapp/homebridge-vantage",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Homebridge plugin for Vantage InFusion (dynamic platform, HB 1.6+ / 2.0 ready)",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -15,7 +15,7 @@
15
15
  "homepage": "https://github.com/SmarterHomeApp/homebridge-vantage",
16
16
  "repository": {
17
17
  "type": "git",
18
- "url": "https://github.com/SmarterHomeApp/homebridge-vantage.git"
18
+ "url": "git+https://github.com/SmarterHomeApp/homebridge-vantage.git"
19
19
  },
20
20
  "bugs": {
21
21
  "url": "https://github.com/SmarterHomeApp/homebridge-vantage/issues"
@@ -39,16 +39,16 @@
39
39
  "lint": "eslint 'src/**/*.{ts,tsx}'",
40
40
  "prepublishOnly": "npm run build"
41
41
  },
42
- "dependencies": {
43
- "sprintf-js": "^1.1.3",
44
- "xml2js": "^0.6.2"
45
- },
46
- "devDependencies": {
47
- "@types/xml2js": "^0.4.14",
48
- "homebridge": "^1.11.0",
49
- "typescript": "^5.5.4",
50
- "eslint": "^9.12.0",
51
- "@types/node": "^20.19.11",
52
- "rimraf": "^6.0.1"
53
- }
42
+ "dependencies": {
43
+ "sprintf-js": "^1.1.3",
44
+ "xml2js": "^0.6.2"
45
+ },
46
+ "devDependencies": {
47
+ "@types/xml2js": "^0.4.14",
48
+ "homebridge": "^1.11.0",
49
+ "typescript": "^5.5.4",
50
+ "eslint": "^9.12.0",
51
+ "@types/node": "^20.19.11",
52
+ "rimraf": "^6.0.1"
53
+ }
54
54
  }