From d07d021103f12e80f8ab359cf1621403c14860ff Mon Sep 17 00:00:00 2001 From: Mark Langovoi Date: Tue, 15 Jan 2019 21:45:13 +0300 Subject: [PATCH] Add excludeUSN option --- Device.js | 24 ++++++++++++++++++++- MediaRenderer1.js | 8 ++----- README.md | 27 ++++++++++++++++++++++- UPnPPlatform.js | 55 ++++++++++++++++++++++++++++++++++++++++------- package.json | 2 +- 5 files changed, 99 insertions(+), 17 deletions(-) diff --git a/Device.js b/Device.js index 0a543e4..af20a41 100644 --- a/Device.js +++ b/Device.js @@ -24,7 +24,7 @@ class Device { return; } - this._client.unsubscribe('RenderingControl', this._handleEvent); + this.stop(); this._client = null; } @@ -50,6 +50,8 @@ class Device { this._updateAccessory(description); } + this.onStart(); + if (accessoryCreated) { this._platform.addDevice(this); this._platform.addAccessory(this.accessory); @@ -61,6 +63,26 @@ class Device { return this._accessory; } + bye() { + if (this._client) { + if(Object.keys(this._client.subscriptions).length !== 0) { + this._client.subscriptions = {}; + this._client.releaseEventingServer(); + } + this._client = null; + } + + this.onBye(); + } + + alive() { + this.onAlive(); + } + + onStart() { + throw new Error('onAlive must be implemented'); + } + onAlive() { throw new Error('onAlive must be implemented'); } diff --git a/MediaRenderer1.js b/MediaRenderer1.js index 2155662..8baeacc 100644 --- a/MediaRenderer1.js +++ b/MediaRenderer1.js @@ -70,7 +70,9 @@ class MediaRenderer1 extends Device { if (description.serialNumber) { informationService.getCharacteristic(homebridge.hap.Characteristic.SerialNumber).updateValue(description.serialNumber); } + } + onStart() { this._client.subscribe('RenderingControl', this._handleEvent); } @@ -95,12 +97,6 @@ class MediaRenderer1 extends Device { } onBye() { - if (this._client) { - this._client.subscriptions = {}; - this._client.releaseEventingServer(); - this._client = null; - } - this.accessory.getService(homebridge.hap.Service.Lightbulb).getCharacteristic(homebridge.hap.Characteristic.On).updateValue(false); } diff --git a/README.md b/README.md index 15fa295..d73f276 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,9 @@ Simply add to your Homebridge config new platform called "UPnP" and restart Home } ``` -Also you can provide custom config for [node-ssdp](https://github.com/diversario/node-ssdp/tree/v4.0.0) by `ssdpClient` and `ssdpServer` options: +### Configure network interfaces + +You can provide custom config for [node-ssdp](https://github.com/diversario/node-ssdp/tree/v4.0.0) by `ssdpClient` and `ssdpServer` options: ```json { @@ -52,3 +54,26 @@ Also you can provide custom config for [node-ssdp](https://github.com/diversario ] } ``` + +### Exclude devices + +Found device's USN. It must be in logs of Homebridge: + +``` +... +[2019-1-15 21:21:15] [UPnP] Add device [TV] Samsung 7 Series (55) (USN: XXXXXXXXX) +... +``` + +Then use `excludeUSN` option: + +```json +{ + "platforms": [ + { + "platform": "UPnP", + "excludeUSN": ["XXXXXXXXX"] + } + ] +} +``` diff --git a/UPnPPlatform.js b/UPnPPlatform.js index 5e9b65f..9a07fd5 100644 --- a/UPnPPlatform.js +++ b/UPnPPlatform.js @@ -5,6 +5,8 @@ class UPnPPlatform { constructor(log, config, api) { this.log = log; + this._config = config; + this._client = new Client({ ...config.ssdpClient, customLogger: this.log.debug.bind(this.log) @@ -14,6 +16,9 @@ class UPnPPlatform { customLogger: this.log.debug.bind(this.log) }); this._devices = []; + this._preparingDevices = []; + this._accessoriesToRemove = []; + this._STToDevice = { 'urn:schemas-upnp-org:device:MediaRenderer:1': require('./MediaRenderer1') }; @@ -31,20 +36,34 @@ class UPnPPlatform { } } + _isUSNExcluded(USN) { + const excluded = this._config.excludeUSN || []; + + return excluded.includes(USN) + } + configureAccessory(accessory) { const Device = this._STToDevice[accessory.context.ST]; - if (Device) { + if (Device && !this._isUSNExcluded(accessory.context.USN)) { const device = new Device(this, accessory.context.USN, accessory); this.addDevice(device); } else { - this.removeAccessory(accessory) + this._accessoriesToRemove.push(accessory); } } _start() { + this.removeAccessories(this._accessoriesToRemove); + + this._accessoriesToRemove = []; + this._client.on('response', (headers) => { + if(this._isUSNExcluded(headers.USN)) { + return; + } + const Device = this._STToDevice[headers.ST]; if(!Device) { @@ -53,14 +72,25 @@ class UPnPPlatform { let device = this._devices.find(device => device.USN === headers.USN); + if(!device) { + device = this._preparingDevices.find(device => device.USN === headers.USN); + } + if(!device) { device = new Device(this, headers.USN); + this._preparingDevices.push(device); } - device.setLocation(headers.LOCATION); + if(!device.hasLocation()) { + device.setLocation(headers.LOCATION); + } }); this._server.on('advertise-alive', (headers) => { + if(this._isUSNExcluded(headers.USN)) { + return; + } + const Device = this._STToDevice[headers.NT]; if (!Device) { @@ -69,12 +99,17 @@ class UPnPPlatform { let device = this._devices.find(device => device.USN === headers.USN); + if(!device) { + device = this._preparingDevices.find(device => device.USN === headers.USN); + } + if(!device) { device = new Device(this, headers.USN); + this._preparingDevices.push(device); } if(device.hasLocation()) { - device.onAlive(); + device.alive(); } else { device.setLocation(headers.LOCATION); } @@ -89,7 +124,7 @@ class UPnPPlatform { const device = this._devices.find(device => device.USN === headers.USN); if(device) { - device.onBye(); + device.bye(); } }); @@ -101,12 +136,16 @@ class UPnPPlatform { this.api.registerPlatformAccessories(require('./package.json').name, 'UPnP', [accessory]); } - removeAccessory(accessory) { - this.api.unregisterPlatformAccessories(require('./package.json').name, 'UPnP', [accessory]); + removeAccessories(accessories) { + this.api.unregisterPlatformAccessories(require('./package.json').name, 'UPnP', accessories); } addDevice(device) { - this.log('Add device', device.accessory.displayName); + if(this._preparingDevices.includes(device)) { + this._preparingDevices.splice(this._preparingDevices.indexOf(device), 1); + } + + this.log('Add device', device.accessory.displayName, `(USN: ${device.accessory.context.USN})`); this._devices.push(device); } diff --git a/package.json b/package.json index 0f23a0f..0edca1f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homebridge-upnp", - "version": "0.1.8", + "version": "0.1.9", "main": "index.js", "author": "Mark Langovoi ", "license": "MIT",