From bcfa3309e9c6eebf1f026c5721a234464b0f7c17 Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Wed, 14 Aug 2024 18:11:53 +0200 Subject: [PATCH] release 5.0.0 --- CHANGELOG.md | 11 ++ README.md | 25 ++-- config.schema.json | 267 +++++++++++++++++++++------------------- index.js | 10 +- package-lock.json | 4 +- package.json | 2 +- src/denon.js | 28 ++--- src/impulsegenerator.js | 34 +++-- src/mainzone.js | 22 ++-- src/surround.js | 22 ++-- src/zone2.js | 22 ++-- src/zone3.js | 22 ++-- 12 files changed, 256 insertions(+), 213 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da47da9..982f8d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Note - after update to 4.7.x buttons, sensors, volume display type need to be configure again using config UI ## Note - after update to 3.15.x need remove the accessory frome Home app and add it again +## [5.0.0] - (14.08.2024) + +## Changes + +### After update to v9.0.0 RESTFull and MQTT config settings need to be updated + +- hide passwords by typing and display in Config UI +- remove return duplicate promises from whole code +- bump dependencies +- cleanup + ## [4.14.0] - (04.08.2024) ## Changes diff --git a/README.md b/README.md index 469aeb9..a69af5a 100644 --- a/README.md +++ b/README.md @@ -117,17 +117,20 @@ Tested Denon AVR-2112CI, AVR-3311CI, AVR-X6300H, AVR-X2700H, AVC-X4800H, Marantz | `disableLogDeviceInfo` | If enabled, add ability to disable log device info by every connections device to the network. | | `disableLogConnectError` | If enabled, disable logging device connect error. | | `enableRestFul` | If enabled, RESTful server will start automatically and respond to any path request. | -| `restFulPort` | Here set the listening `Port` for RESTful server, every zone need own port. | -| `restFulDebug` | If enabled, deep log will be present in homebridge console for RESTFul server. | -| `enableMqtt` | If enabled, MQTT Broker will start automatically and publish all awailable PV installation data. | -| `mqttHost` | Here set the `IP Address` or `Hostname` for MQTT Broker. | -| `mqttPort` | Here set the `Port` for MQTT Broker, default 1883. | -| `mqttClientId` | Here optional set the `Client Id` of MQTT Broker. | -| `mqttPrefix` | Here set the `Prefix` for `Topic` or leave empty. | -| `mqttAuth` | If enabled, MQTT Broker will use authorization credentials. | -| `mqttUser` | Here set the MQTT Broker user. | -| `mqttPasswd` | Here set the MQTT Broker password. | -| `mqttDebug` | If enabled, deep log will be present in homebridge console for MQTT. | +| `restFul` | This is RSTful server. | +| `enable` | If enabled, RESTful server will start automatically and respond to any path request. | +| `port` | Here set the listening `Port` for RESTful server. | +| `debug` | If enabled, deep log will be present in homebridge console for RESTFul server. | +| `mqtt` | This is MQTT Broker. | +| `enable` | If enabled, MQTT Broker will start automatically and publish all awailable PV data. | +| `host` | Here set the `IP Address` or `Hostname` for MQTT Broker. | +| `port` | Here set the `Port` for MQTT Broker, default 1883. | +| `clientId` | Here optional set the `Client Id` of MQTT Broker. | +| `prefix` | Here set the `Prefix` for `Topic` or leave empty. | +| `auth` | If enabled, MQTT Broker will use authorization credentials. | +| `user` | Here set the MQTT Broker user. | +| `passwd` | Here set the MQTT Broker password. | +| `debug` | If enabled, deep log will be present in homebridge console for MQTT. | | `AV Surround Mode` | This extra Accessory will control all functions of Main Zone except `Inputs` and `Buttons`. | ### RESTFul Integration diff --git a/config.schema.json b/config.schema.json index ea7a4ac..2989d17 100644 --- a/config.schema.json +++ b/config.schema.json @@ -6587,120 +6587,131 @@ "description": "This disable logging device connect error.", "required": false }, - "enableRestFul": { - "title": "Enable", - "type": "boolean", - "default": false, - "description": "This enable RESTful server.", - "required": false - }, - "restFulDebug": { - "title": "Debug", - "type": "boolean", - "default": false, - "description": "This enable debug mode for RESTFul.", - "condition": { - "functionBody": "return model.devices[arrayIndices].enableRestFul === true;" - }, - "required": false - }, - "restFulPort": { - "title": "Port", - "type": "integer", - "placeholder": 3000, - "description": "Here set the listening Port for RESTful server, every zone need own port.", - "condition": { - "functionBody": "return model.devices[arrayIndices].enableRestFul === true;" - }, - "required": false - }, - "enableMqtt": { - "title": "Enable", - "type": "boolean", - "default": false, - "description": "This enable MQTT client.", - "required": false - }, - "mqttDebug": { - "title": "Debug", - "type": "boolean", - "default": false, - "description": "This enable debug mode for MQTT.", - "condition": { - "functionBody": "return model.devices[arrayIndices].enableMqtt === true;" - }, - "required": false - }, - "mqttHost": { - "title": "IP/Hostname", - "type": "string", - "placeholder": "ip or hostname", - "format": "hostname", - "description": "Here set the IP/Hostname of MQTT Broker.", - "condition": { - "functionBody": "return model.devices[arrayIndices].enableMqtt === true;" - }, - "required": false - }, - "mqttPort": { - "title": "Port", - "type": "integer", - "placeholder": 1883, - "description": "Here set the port of MQTT Broker.", - "condition": { - "functionBody": "return model.devices[arrayIndices].enableMqtt === true;" - }, - "required": false - }, - "mqttClientId": { - "title": "Client ID", - "type": "string", - "placeholder": "client id", - "description": "Here optional set the Client ID of MQTT Broker.", - "condition": { - "functionBody": "return model.devices[arrayIndices].enableMqtt === true" - }, - "required": false - }, - "mqttPrefix": { - "title": "Prefix", - "type": "string", - "placeholder": "home/openwebif", - "description": "Here set the prefix.", - "condition": { - "functionBody": "return model.devices[arrayIndices].enableMqtt === true;" - }, - "required": false - }, - "mqttAuth": { - "title": "Authorization", - "type": "boolean", - "default": false, - "description": "This enable authorization for MQTT Broker.", - "condition": { - "functionBody": "return model.devices[arrayIndices].enableMqtt === true;" - }, - "required": false - }, - "mqttUser": { - "title": "User", - "type": "string", - "placeholder": "username", - "description": "Here set the user of MQTT Broker.", - "condition": { - "functionBody": "return model.devices[arrayIndices].enableMqtt === true && model.devices[arrayIndices].mqttAuth === true;" - }, - "required": false + "restFul": { + "title": "RESTFul", + "type": "object", + "properties": { + "enable": { + "title": "Enable", + "type": "boolean", + "default": false, + "description": "This enable RESTful server." + }, + "debug": { + "title": "Debug", + "type": "boolean", + "default": false, + "description": "This enable debug mode for RESTFul.", + "condition": { + "functionBody": "return model.devices[arrayIndices].restFul.enable === true;" + }, + "required": false + }, + "port": { + "title": "Port", + "type": "integer", + "placeholder": 3000, + "description": "Here set the listening Port for RESTful server.", + "condition": { + "functionBody": "return model.devices[arrayIndices].restFul.enable === true;" + }, + "required": false + } + } }, - "mqttPasswd": { - "title": "Password", - "type": "string", - "placeholder": "password", - "description": "Here set the password of MQTT Broker.", - "condition": { - "functionBody": "return model.devices[arrayIndices].enableMqtt === true && model.devices[arrayIndices].mqttAuth === true;" - }, - "required": false + "mqtt": { + "title": "MQTT", + "type": "object", + "properties": { + "enable": { + "title": "Enable", + "type": "boolean", + "default": false, + "description": "This enable MQTT client." + }, + "debug": { + "title": "Debug", + "type": "boolean", + "default": false, + "description": "This enable debug mode for MQTT.", + "condition": { + "functionBody": "return model.devices[arrayIndices].mqtt.enable === true;" + }, + "required": false + }, + "host": { + "title": "IP/Hostname", + "type": "string", + "placeholder": "ip or hostname", + "format": "hostname", + "description": "Here set the IP/Hostname of MQTT Broker.", + "condition": { + "functionBody": "return model.devices[arrayIndices].mqtt.enable === true;" + }, + "required": false + }, + "port": { + "title": "Port", + "type": "integer", + "placeholder": 1883, + "description": "Here set the port of MQTT Broker.", + "condition": { + "functionBody": "return model.devices[arrayIndices].mqtt.enable === true;" + }, + "required": false + }, + "clientId": { + "title": "Client ID", + "type": "string", + "placeholder": "client id", + "description": "Here optional set the Client ID of MQTT Broker.", + "condition": { + "functionBody": "return model.devices[arrayIndices].mqtt.enable === true" + }, + "required": false + }, + "prefix": { + "title": "Prefix", + "type": "string", + "placeholder": "home/envoy", + "description": "Here set the prefix.", + "condition": { + "functionBody": "return model.devices[arrayIndices].mqtt.enable === true;" + }, + "required": false + }, + "auth": { + "title": "Authorization", + "type": "boolean", + "default": false, + "description": "This enable authorization for MQTT Broker.", + "condition": { + "functionBody": "return model.devices[arrayIndices].mqtt.enable === true;" + }, + "required": false + }, + "user": { + "title": "User", + "type": "string", + "placeholder": "user", + "description": "Here set the user of MQTT Broker.", + "condition": { + "functionBody": "return model.devices[arrayIndices].mqtt.enable === true && model.devices[arrayIndices].mqtt.auth === true;" + }, + "required": false + }, + "passwd": { + "title": "Password", + "type": "string", + "placeholder": "password", + "description": "Here set the password of MQTT Broker.", + "format": "password", + "condition": { + "functionBody": "return model.devices[arrayIndices].mqtt.enable === true && model.devices[arrayIndices].mqtt.auth === true;" + }, + "required": false + } + } } } } @@ -6943,26 +6954,30 @@ "title": "{{ value.title }}", "items": [ { - "key": "devices[]", + "key": "devices[].restFul", "title": "RESTFul", "items": [ - "devices[].enableRestFul", - "devices[].restFulDebug", - "devices[].restFulPort" + "devices[].restFul.enable", + "devices[].restFul.debug", + "devices[].restFul.port" ] }, { - "key": "devices[]", + "key": "devices[].mqtt", "title": "MQTT", "items": [ - "devices[].enableMqtt", - "devices[].mqttDebug", - "devices[].mqttHost", - "devices[].mqttPort", - "devices[].mqttPrefix", - "devices[].mqttAuth", - "devices[].mqttUser", - "devices[].mqttPasswd" + "devices[].mqtt.enable", + "devices[].mqtt.debug", + "devices[].mqtt.host", + "devices[].mqtt.port", + "devices[].mqtt.clientId", + "devices[].mqtt.prefix", + "devices[].mqtt.auth", + "devices[].mqtt.user", + { + "key": "devices[].mqtt.passwd", + "type": "password" + } ] } ] diff --git a/index.js b/index.js index 2abc235..ed7207c 100644 --- a/index.js +++ b/index.js @@ -37,7 +37,15 @@ class DenonPlatform { //debug config const enableDebugMode = device.enableDebugMode || false; const debug = enableDebugMode ? log(`Device: ${host} ${deviceName}, did finish launching.`) : false; - const debug1 = enableDebugMode ? log(`Device: ${host} ${deviceName}, Config: ${JSON.stringify(device, null, 2)}`) : false; + const config = { + ...device, + mqtt: { + ...device.mqtt, + user: 'removed', + passwd: 'removed' + } + }; + const debug1 = enableDebugMode ? log(`Device: ${host} ${deviceName}, Config: ${JSON.stringify(config, null, 2)}`) : false; //zones const zoneControl = device.zoneControl; diff --git a/package-lock.json b/package-lock.json index 74e8336..ba303b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "homebridge-denon-tv", - "version": "4.14.1", + "version": "5.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "homebridge-denon-tv", - "version": "4.14.1", + "version": "5.0.0", "license": "MIT", "dependencies": { "async-mqtt": "^2.6.3", diff --git a/package.json b/package.json index ee7e88e..a67a19b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "displayName": "Denon TV", "name": "homebridge-denon-tv", - "version": "4.14.2", + "version": "5.0.0", "description": "Homebridge plugin to control Denon/Marantz AV Receivers.", "license": "MIT", "author": "grzegorz914", diff --git a/src/denon.js b/src/denon.js index ddba8aa..39ae8be 100644 --- a/src/denon.js +++ b/src/denon.js @@ -81,17 +81,8 @@ class DENON extends EventEmitter { this.devInfo = {}; const object = {}; - const timers = [ - { name: 'checkDeviceInfo', interval: 30000 }, - { name: 'checkState', interval: refreshInterval }, - ]; - - const impulseGenerator = new ImpulseGenerator(timers); + const impulseGenerator = new ImpulseGenerator(); impulseGenerator.on('checkDeviceInfo', async () => { - if (!this.startPrepareAccessory) { - return; - } - try { //get device info const deviceInfo = await this.axiosInstance(deviceInfoUrl); @@ -228,18 +219,21 @@ class DENON extends EventEmitter { const prepareAccessory = this.startPrepareAccessory ? this.emit('prepareAccessory', allInputs) : false; this.startPrepareAccessory = false; + if (this.startPrepareAccessory) { + return; + } + //check state await new Promise(resolve => setTimeout(resolve, 1500)); - impulseGenerator.emit('checkState') + + //start check state + impulseGenerator.stop(); + impulseGenerator.start([{ timerName: 'checkState', sampling: refreshInterval }]); } catch (error) { const debug = disableLogConnectError ? false : this.emit('error', `Info error: ${error}, reconnect in 15s.`); }; }) .on('checkState', async () => { - if (this.startPrepareAccessory) { - return; - } - try { //get zones status const zoneStateUrl = [CONSTANTS.ApiUrls.MainZoneStatusLite, CONSTANTS.ApiUrls.Zone2StatusLite, CONSTANTS.ApiUrls.Zone3StatusLite, CONSTANTS.ApiUrls.SoundModeStatus][zone]; @@ -317,9 +311,9 @@ class DENON extends EventEmitter { .on('disconnect', () => { this.emit('stateChanged', false, this.reference, this.volume, this.volumeDisplay, this.mute, this.pictureMode); const debug = disableLogConnectError ? false : this.emit('disconnected', 'Disconnected.'); - }); + }).on('state', () => { }); - impulseGenerator.start(); + impulseGenerator.start([{ timerName: 'checkDeviceInfo', sampling: 30000 }]); }; async saveDevInfo(path, devInfo) { diff --git a/src/impulsegenerator.js b/src/impulsegenerator.js index b34fca8..1b09d0d 100644 --- a/src/impulsegenerator.js +++ b/src/impulsegenerator.js @@ -2,27 +2,39 @@ const EventEmitter = require('events'); class ImpulseGenerator extends EventEmitter { - constructor(outputs) { + constructor() { super(); - this.outputs = outputs; - this.timers = []; + this.timersState = false; } - start() { - this.outputs.forEach(({ name, interval }) => { - this.emit(name); - + start(timers) { + this.timers = []; + timers.forEach(({ timerName, sampling }) => { const timer = setInterval(() => { - this.emit(name); - }, interval); - + this.emit(timerName); + }, sampling); this.timers.push(timer); }); + + //update state + this.timersState = true; + this.emit('state', true); } stop() { - this.timers.forEach(timer => clearInterval(timer)); + if (this.timersState) { + this.timers.forEach(timer => clearInterval(timer)); + } + + //update state this.timers = []; + this.timersState = false; + this.emit('state', false); + } + + state() { + this.emit('state', this.timersState); + return this.timersState; } } module.exports = ImpulseGenerator; diff --git a/src/mainzone.js b/src/mainzone.js index 46edb32..fd15d08 100644 --- a/src/mainzone.js +++ b/src/mainzone.js @@ -246,11 +246,11 @@ class MainZone extends EventEmitter { }) .on('prepareAccessory', async (allInputs) => { //RESTFul server - const restFulEnabled = device.enableRestFul || false; + const restFulEnabled = device.restFul.enable || false; if (restFulEnabled) { this.restFul = new RestFul({ - port: device.restFulPort || 3000, - debug: device.restFulDebug || false + port: device.restFul.port || 3000, + debug: device.restFul.debug || false }); this.restFul.on('connected', (message) => { @@ -266,16 +266,16 @@ class MainZone extends EventEmitter { } //mqtt client - const mqttEnabled = device.enableMqtt || false; + const mqttEnabled = device.mqtt.enable || false; if (mqttEnabled) { this.mqtt = new Mqtt({ - host: device.mqttHost, - port: device.mqttPort || 1883, - clientId: device.mqttClientId || `denon_${Math.random().toString(16).slice(3)}`, - prefix: `${device.mqttPrefix}/${device.name}`, - user: device.mqttUser, - passwd: device.mqttPasswd, - debug: device.mqttDebug || false + host: device.mqtt.host, + port: device.mqtt.port || 1883, + clientId: device.mqtt.clientId || `denon_${Math.random().toString(16).slice(3)}`, + prefix: `${device.mqtt.prefix}/${device.name}`, + user: device.mqtt.user, + passwd: device.mqtt.passwd, + debug: device.mqtt.debug || false }); this.mqtt.on('connected', (message) => { diff --git a/src/surround.js b/src/surround.js index ae54db2..3c00bec 100644 --- a/src/surround.js +++ b/src/surround.js @@ -214,11 +214,11 @@ class Surround extends EventEmitter { }) .on('prepareAccessory', async (allInputs) => { //RESTFul server - const restFulEnabled = device.enableRestFul || false; + const restFulEnabled = device.restFul.enable || false; if (restFulEnabled) { this.restFul = new RestFul({ - port: device.restFulPort || 3000, - debug: device.restFulDebug || false + port: device.restFul.port || 3000, + debug: device.restFul.debug || false }); this.restFul.on('connected', (message) => { @@ -234,16 +234,16 @@ class Surround extends EventEmitter { } //mqtt client - const mqttEnabled = device.enableMqtt || false; + const mqttEnabled = device.mqtt.enable || false; if (mqttEnabled) { this.mqtt = new Mqtt({ - host: device.mqttHost, - port: device.mqttPort || 1883, - clientId: device.mqttClientId || `denon_${Math.random().toString(16).slice(3)}`, - prefix: `${device.mqttPrefix}/${device.name}`, - user: device.mqttUser, - passwd: device.mqttPasswd, - debug: device.mqttDebug || false + host: device.mqtt.host, + port: device.mqtt.port || 1883, + clientId: device.mqtt.clientId || `denon_${Math.random().toString(16).slice(3)}`, + prefix: `${device.mqtt.prefix}/${device.name}`, + user: device.mqtt.user, + passwd: device.mqtt.passwd, + debug: device.mqtt.debug || false }); this.mqtt.on('connected', (message) => { diff --git a/src/zone2.js b/src/zone2.js index 5a216e4..c73e293 100644 --- a/src/zone2.js +++ b/src/zone2.js @@ -244,11 +244,11 @@ class Zone2 extends EventEmitter { }) .on('prepareAccessory', async (allInputs) => { //RESTFul server - const restFulEnabled = device.enableRestFul || false; + const restFulEnabled = device.restFul.enable || false; if (restFulEnabled) { this.restFul = new RestFul({ - port: device.restFulPort || 3000, - debug: device.restFulDebug || false + port: device.restFul.port || 3000, + debug: device.restFul.debug || false }); this.restFul.on('connected', (message) => { @@ -264,16 +264,16 @@ class Zone2 extends EventEmitter { } //mqtt client - const mqttEnabled = device.enableMqtt || false; + const mqttEnabled = device.mqtt.enable || false; if (mqttEnabled) { this.mqtt = new Mqtt({ - host: device.mqttHost, - port: device.mqttPort || 1883, - clientId: device.mqttClientId || `denon_${Math.random().toString(16).slice(3)}`, - prefix: `${device.mqttPrefix}/${device.name}`, - user: device.mqttUser, - passwd: device.mqttPasswd, - debug: device.mqttDebug || false + host: device.mqtt.host, + port: device.mqtt.port || 1883, + clientId: device.mqtt.clientId || `denon_${Math.random().toString(16).slice(3)}`, + prefix: `${device.mqtt.prefix}/${device.name}`, + user: device.mqtt.user, + passwd: device.mqtt.passwd, + debug: device.mqtt.debug || false }); this.mqtt.on('connected', (message) => { diff --git a/src/zone3.js b/src/zone3.js index 364dd1e..8ba3c51 100644 --- a/src/zone3.js +++ b/src/zone3.js @@ -244,11 +244,11 @@ class Zone3 extends EventEmitter { }) .on('prepareAccessory', async (allInputs) => { //RESTFul server - const restFulEnabled = device.enableRestFul || false; + const restFulEnabled = device.restFul.enable || false; if (restFulEnabled) { this.restFul = new RestFul({ - port: device.restFulPort || 3000, - debug: device.restFulDebug || false + port: device.restFul.port || 3000, + debug: device.restFul.debug || false }); this.restFul.on('connected', (message) => { @@ -264,16 +264,16 @@ class Zone3 extends EventEmitter { } //mqtt client - const mqttEnabled = device.enableMqtt || false; + const mqttEnabled = device.mqtt.enable || false; if (mqttEnabled) { this.mqtt = new Mqtt({ - host: device.mqttHost, - port: device.mqttPort || 1883, - clientId: device.mqttClientId || `denon_${Math.random().toString(16).slice(3)}`, - prefix: `${device.mqttPrefix}/${device.name}`, - user: device.mqttUser, - passwd: device.mqttPasswd, - debug: device.mqttDebug || false + host: device.mqtt.host, + port: device.mqtt.port || 1883, + clientId: device.mqtt.clientId || `denon_${Math.random().toString(16).slice(3)}`, + prefix: `${device.mqtt.prefix}/${device.name}`, + user: device.mqtt.user, + passwd: device.mqtt.passwd, + debug: device.mqtt.debug || false }); this.mqtt.on('connected', (message) => {