diff --git a/denon-avr-config-schema.coffee b/denon-avr-config-schema.coffee index 9664041..deafe7c 100644 --- a/denon-avr-config-schema.coffee +++ b/denon-avr-config-schema.coffee @@ -7,18 +7,4 @@ module.exports = { description: "Debug mode. Writes debug messages to the pimatic log, if set to true." type: "boolean" default: false - host: - description: "Hostname or IP address of the AVR" - type: "string" - protocol: - description: "The control protocol to be used (HTTP may not work with older receiver models)" - enum: ["TELNET", "HTTP"] - default: "TELNET" - port: - description: """ - AVR control port (inly required for testing). Defaults to port 23 - for TELNET protocol and port 80 for HTTP protocol - """ - type: "number" - required: false } \ No newline at end of file diff --git a/denon-avr.coffee b/denon-avr.coffee index 8ff4690..8e52abe 100644 --- a/denon-avr.coffee +++ b/denon-avr.coffee @@ -48,11 +48,12 @@ module.exports = (env) -> init: (app, @framework, @config) => @debug = @config.debug || false @base = commons.base @, 'Plugin' + ### if @config.protocol is 'HTTP' @protocolHandler = new HttpAppProtocol @config else @protocolHandler = new TelnetAppProtocol @config - + ### # register devices deviceConfigDef = require("./device-config-schema") for device in deviceConfigTemplates @@ -84,7 +85,13 @@ module.exports = (env) -> if not matched process.nextTick @_discoveryCallbackHandler('pimatic-denon-avr', device.name, device) ) - + + getProtocolHandler: (config) -> + if config.protocol is 'HTTP' + return new HttpAppProtocol(config) + else + return new TelnetAppProtocol(config) + _discoveryCallbackHandler: (pluginName, deviceName, deviceConfig) -> return () => @framework.deviceManager.discoveredDevice pluginName, deviceName, deviceConfig diff --git a/device-config-schema.coffee b/device-config-schema.coffee index 3c6aaca..ee14ae3 100644 --- a/device-config-schema.coffee +++ b/device-config-schema.coffee @@ -6,6 +6,25 @@ module.exports = { type: "object" extensions: ["xLink", "xPresentLabel", "xAbsentLabel", "xAttributeOptions"] properties: + debug: + type: "boolean" + description: "Debug mode. Writes debug messages to the pimatic log, if set to true." + default: false + protocol: + description: "The control protocol to be used (HTTP may not work with older receiver models)" + enum: ["TELNET", "HTTP"] + default: "TELNET" + host: + description: "Hostname or IP address of the AVR" + type: "string" + required: true + port: + description: """ + AVR control port (inly required for testing). Defaults to port 23 + for TELNET protocol and port 80 for HTTP protocol + """ + type: "number" + required: false interval: description: """ The time interval in seconds (minimum 2) at which the presence state of the @@ -28,6 +47,25 @@ module.exports = { type: "object" extensions: ["xLink", "xPresentLabel", "xAbsentLabel", "xAttributeOptions"] properties: + debug: + type: "boolean" + description: "Debug mode. Writes debug messages to the pimatic log, if set to true." + default: false + protocol: + description: "The control protocol to be used (HTTP may not work with older receiver models)" + enum: ["TELNET", "HTTP"] + default: "TELNET" + host: + description: "Hostname or IP address of the AVR" + type: "string" + required: true + port: + description: """ + AVR control port (inly required for testing). Defaults to port 23 + for TELNET protocol and port 80 for HTTP protocol + """ + type: "number" + required: false interval: description: """ The time interval in seconds (minimum 2) at which the volume state of the @@ -63,6 +101,25 @@ module.exports = { type: "object" extensions: ["xLink", "xPresentLabel", "xAbsentLabel", "xAttributeOptions"] properties: + debug: + type: "boolean" + description: "Debug mode. Writes debug messages to the pimatic log, if set to true." + default: false + protocol: + description: "The control protocol to be used (HTTP may not work with older receiver models)" + enum: ["TELNET", "HTTP"] + default: "TELNET" + host: + description: "Hostname or IP address of the AVR" + type: "string" + required: true + port: + description: """ + AVR control port (inly required for testing). Defaults to port 23 + for TELNET protocol and port 80 for HTTP protocol + """ + type: "number" + required: false zone: description: """ The zone for which volume shall be controlled. If set to MAIN it is @@ -105,6 +162,25 @@ module.exports = { type: "object" extensions: ["xLink", "xOnLabel", "xOffLabel"] properties: + debug: + type: "boolean" + description: "Debug mode. Writes debug messages to the pimatic log, if set to true." + default: false + protocol: + description: "The control protocol to be used (HTTP may not work with older receiver models)" + enum: ["TELNET", "HTTP"] + default: "TELNET" + host: + description: "Hostname or IP address of the AVR" + type: "string" + required: true + port: + description: """ + AVR control port (inly required for testing). Defaults to port 23 + for TELNET protocol and port 80 for HTTP protocol + """ + type: "number" + required: false interval: description: """ The time interval in seconds (minimum 2) at which the power state @@ -120,6 +196,25 @@ module.exports = { type: "object" extensions: ["xLink", "xOnLabel", "xOffLabel"] properties: + debug: + type: "boolean" + description: "Debug mode. Writes debug messages to the pimatic log, if set to true." + default: false + protocol: + description: "The control protocol to be used (HTTP may not work with older receiver models)" + enum: ["TELNET", "HTTP"] + default: "TELNET" + host: + description: "Hostname or IP address of the AVR" + type: "string" + required: true + port: + description: """ + AVR control port (inly required for testing). Defaults to port 23 + for TELNET protocol and port 80 for HTTP protocol + """ + type: "number" + required: false zone: description: "The zone to be controlled" enum: ["MAIN", "ZONE2", "ZONE3"] @@ -139,6 +234,25 @@ module.exports = { type: "object" extensions: ["xLink", "xOnLabel", "xOffLabel"] properties: + debug: + type: "boolean" + description: "Debug mode. Writes debug messages to the pimatic log, if set to true." + default: false + protocol: + description: "The control protocol to be used (HTTP may not work with older receiver models)" + enum: ["TELNET", "HTTP"] + default: "TELNET" + host: + description: "Hostname or IP address of the AVR" + type: "string" + required: true + port: + description: """ + AVR control port (inly required for testing). Defaults to port 23 + for TELNET protocol and port 80 for HTTP protocol + """ + type: "number" + required: false zone: description: "The zone to be controlled" enum: ["MAIN", "ZONE2", "ZONE3"] @@ -158,6 +272,25 @@ module.exports = { type: "object" extensions: ["xLink", "xOnLabel", "xOffLabel"] properties: + debug: + type: "boolean" + description: "Debug mode. Writes debug messages to the pimatic log, if set to true." + default: false + protocol: + description: "The control protocol to be used (HTTP may not work with older receiver models)" + enum: ["TELNET", "HTTP"] + default: "TELNET" + host: + description: "Hostname or IP address of the AVR" + type: "string" + required: true + port: + description: """ + AVR control port (inly required for testing). Defaults to port 23 + for TELNET protocol and port 80 for HTTP protocol + """ + type: "number" + required: false zone: description: "The zone to be controlled" enum: ["MAIN", "ZONE2", "ZONE3"] diff --git a/devices/denon-avr-input-selector.coffee b/devices/denon-avr-input-selector.coffee index 3ba6d8d..5e5c1de 100644 --- a/devices/denon-avr-input-selector.coffee +++ b/devices/denon-avr-input-selector.coffee @@ -27,21 +27,24 @@ module.exports = (env) -> @debug = @plugin.debug || false for b in @config.buttons b.text = b.id unless b.text? + + @protocolHandler = @plugin.getProtocolHandler(@config) + @responseHandler = @_createResponseHandler() - @plugin.protocolHandler.on 'response', @responseHandler + @protocolHandler.on 'response', @responseHandler super(@config) process.nextTick () => @_requestUpdate true destroy: () -> @_base.cancelUpdate() - @plugin.protocolHandler.removeListener 'response', @responseHandler + @protocolHandler.removeListener 'response', @responseHandler super() _requestUpdate: (immediate=false) -> @_base.cancelUpdate() @_base.debug "Requesting update" - @plugin.protocolHandler.sendRequest @zoneCmd, '?', immediate + @protocolHandler.sendRequest @zoneCmd, '?', immediate .catch (error) => @_base.error "Error:", error .finally () => @@ -60,7 +63,7 @@ module.exports = (env) -> if b.id is buttonId @_lastPressedButton = b.id @emit 'button', b.id - return @plugin.protocolHandler.sendRequest(@zoneCmd, b.id).then => + return @protocolHandler.sendRequest(@zoneCmd, b.id).then => @_requestUpdate() .catch (err) => @_base.rejectWithErrorString Promise.reject, err diff --git a/devices/denon-avr-master-volume.coffee b/devices/denon-avr-master-volume.coffee index bdeed8b..09e99bd 100644 --- a/devices/denon-avr-master-volume.coffee +++ b/devices/denon-avr-master-volume.coffee @@ -20,8 +20,11 @@ module.exports = (env) -> @volumeLimit = @_base.normalize @config.volumeLimit, 0, 99 @maxAbsoluteVolume = @_base.normalize @config.maxAbsoluteVolume, 0, 99 @debug = @plugin.debug || false + + @protocolHandler = @plugin.getProtocolHandler(@config) + @responseHandler = @_createResponseHandler() - @plugin.protocolHandler.on 'response', @responseHandler + @protocolHandler.on 'response', @responseHandler @attributes = _.cloneDeep(@attributes) @attributes.volume = { description: "Volume" @@ -38,13 +41,13 @@ module.exports = (env) -> destroy: () -> @_base.cancelUpdate() - @plugin.protocolHandler.removeListener 'response', @responseHandler + @protocolHandler.removeListener 'response', @responseHandler super() _requestUpdate: (immediate=false) -> @_base.cancelUpdate() @_base.debug "Requesting update" - @plugin.protocolHandler.sendRequest 'MV', '?', immediate + @protocolHandler.sendRequest 'MV', '?', immediate .catch (error) => @_base.error "Error:", error .finally () => @@ -88,7 +91,7 @@ module.exports = (env) -> if @volumeLimit > 0 and newLevel > @volumeLimit newLevel = @volumeLimit - @plugin.protocolHandler.sendRequest('MV', @_levelToVolumeParam(newLevel)).then => + @protocolHandler.sendRequest('MV', @_levelToVolumeParam(newLevel)).then => @_setDimlevel newLevel @_requestUpdate() resolve() diff --git a/devices/denon-avr-mute-switch.coffee b/devices/denon-avr-mute-switch.coffee index 6aeb4dd..c9e8465 100644 --- a/devices/denon-avr-mute-switch.coffee +++ b/devices/denon-avr-mute-switch.coffee @@ -26,8 +26,11 @@ module.exports = (env) -> @lastPowerState=null @interval = @_base.normalize @config.interval, 2 @debug = @plugin.debug || false + + @protocolHandler = @plugin.getProtocolHandler(@config) + @responseHandler = @_createResponseHandler() - @plugin.protocolHandler.on 'response', @responseHandler + @protocolHandler.on 'response', @responseHandler super() @_state = false process.nextTick () => @@ -35,13 +38,13 @@ module.exports = (env) -> destroy: () -> @_base.cancelUpdate() - @plugin.protocolHandler.removeListener 'response', @responseHandler + @protocolHandler.removeListener 'response', @responseHandler super() _requestUpdate: (immediate=false) -> @_base.cancelUpdate() @_base.debug "Requesting update" - @plugin.protocolHandler.sendRequest @zoneCmd, '?', immediate + @protocolHandler.sendRequest @zoneCmd, '?', immediate .catch (error) => @_base.error "Error:", error .finally () => @@ -63,7 +66,7 @@ module.exports = (env) -> changeStateTo: (newState) -> return new Promise (resolve, reject) => - @plugin.protocolHandler.sendRequest(@zoneCmd, if newState then 'ON' else 'OFF').then => + @protocolHandler.sendRequest(@zoneCmd, if newState then 'ON' else 'OFF').then => @_setState newState @_requestUpdate() resolve() diff --git a/devices/denon-avr-power-switch.coffee b/devices/denon-avr-power-switch.coffee index f230294..de38a44 100644 --- a/devices/denon-avr-power-switch.coffee +++ b/devices/denon-avr-power-switch.coffee @@ -17,8 +17,11 @@ module.exports = (env) -> @name = @config.name @interval = @_base.normalize @config.interval, 2 @debug = @plugin.debug || false + + @protocolHandler = @plugin.getProtocolHandler(@config) + @responseHandler = @_createResponseHandler() - @plugin.protocolHandler.on 'response', @responseHandler + @protocolHandler.on 'response', @responseHandler @_state = false super() process.nextTick () => @@ -26,13 +29,13 @@ module.exports = (env) -> destroy: () -> @_base.cancelUpdate() - @plugin.protocolHandler.removeListener 'response', @responseHandler + @protocolHandler.removeListener 'response', @responseHandler super() _requestUpdate: (immediate=false) -> @_base.cancelUpdate() @_base.debug "Requesting update" - @plugin.protocolHandler.sendRequest 'PW', '?', immediate + @protocolHandler.sendRequest 'PW', '?', immediate .catch (error) => @_base.error "Error:", error .finally () => @@ -46,7 +49,7 @@ module.exports = (env) -> changeStateTo: (newState) -> return new Promise (resolve, reject) => - @plugin.protocolHandler.sendRequest('PW', if newState then 'ON' else 'STANDBY').then => + @protocolHandler.sendRequest('PW', if newState then 'ON' else 'STANDBY').then => @_setState newState @_requestUpdate() resolve() diff --git a/devices/denon-avr-presence-sensor.coffee b/devices/denon-avr-presence-sensor.coffee index 1fb51c9..580d524 100644 --- a/devices/denon-avr-presence-sensor.coffee +++ b/devices/denon-avr-presence-sensor.coffee @@ -19,8 +19,11 @@ module.exports = (env) -> @interval = @_base.normalize @config.interval, 2 @volumeDecibel = @config.volumeDecibel @debug = @plugin.debug || false + + @protocolHandler = @plugin.getProtocolHandler(@config) + @responseHandler = @_createResponseHandler() - @plugin.protocolHandler.on 'response', @responseHandler + @protocolHandler.on 'response', @responseHandler @attributes = _.cloneDeep(@attributes) @attributes.volume = { description: "Volume" @@ -42,16 +45,16 @@ module.exports = (env) -> destroy: () -> @_base.cancelUpdate() - @plugin.protocolHandler.removeListener 'response', @responseHandler + @protocolHandler.removeListener 'response', @responseHandler super() _requestUpdate: (immediate=false) -> @_base.cancelUpdate() @_base.debug "Requesting update" Promise.all([ - @plugin.protocolHandler.sendRequest 'PW', '?', immediate - @plugin.protocolHandler.sendRequest 'SI', '?', immediate - @plugin.protocolHandler.sendRequest 'MV', '?', immediate + @protocolHandler.sendRequest 'PW', '?', immediate + @protocolHandler.sendRequest 'SI', '?', immediate + @protocolHandler.sendRequest 'MV', '?', immediate ]) .catch (error) => @_base.error "Error:", error diff --git a/devices/denon-avr-zone-switch.coffee b/devices/denon-avr-zone-switch.coffee index f4dd675..3faaa73 100644 --- a/devices/denon-avr-zone-switch.coffee +++ b/devices/denon-avr-zone-switch.coffee @@ -26,8 +26,11 @@ module.exports = (env) -> ) @interval = @_base.normalize @config.interval, 2 @debug = @plugin.debug || false + + @protocolHandler = @plugin.getProtocolHandler(@config) + @responseHandler = @_createResponseHandler() - @plugin.protocolHandler.on 'response', @responseHandler + @protocolHandler.on 'response', @responseHandler @_state = false super() process.nextTick () => @@ -35,13 +38,13 @@ module.exports = (env) -> destroy: () -> @_base.cancelUpdate() - @plugin.protocolHandler.removeListener 'response', @responseHandler + @protocolHandler.removeListener 'response', @responseHandler super() _requestUpdate: (immediate=false) -> @_base.cancelUpdate() @_base.debug "Requesting update" - @plugin.protocolHandler.sendRequest @zoneCmd, '?', immediate + @protocolHandler.sendRequest @zoneCmd, '?', immediate .catch (error) => @_base.error "Error:", error .finally () => @@ -58,7 +61,7 @@ module.exports = (env) -> changeStateTo: (newState) -> return new Promise (resolve, reject) => - @plugin.protocolHandler.sendRequest(@zoneCmd, if newState then 'ON' else 'OFF').then => + @protocolHandler.sendRequest(@zoneCmd, if newState then 'ON' else 'OFF').then => @_setState newState @_requestUpdate() resolve() diff --git a/devices/denon-avr-zone-volume.coffee b/devices/denon-avr-zone-volume.coffee index ebd375f..eeb4d6e 100644 --- a/devices/denon-avr-zone-volume.coffee +++ b/devices/denon-avr-zone-volume.coffee @@ -28,8 +28,11 @@ module.exports = (env) -> @volumeLimit = @_base.normalize @config.volumeLimit, 0, 99 @maxAbsoluteVolume = @_base.normalize @config.maxAbsoluteVolume, 0, 99 @debug = @plugin.debug || false + + @protocolHandler = @plugin.getProtocolHandler(@config) + @responseHandler = @_createResponseHandler() - @plugin.protocolHandler.on 'response', @responseHandler + @protocolHandler.on 'response', @responseHandler @attributes = _.cloneDeep(@attributes) @attributes.volume = { description: "Volume" @@ -46,13 +49,13 @@ module.exports = (env) -> destroy: () -> @_base.cancelUpdate() - @plugin.protocolHandler.removeListener 'response', @responseHandler + @protocolHandler.removeListener 'response', @responseHandler super() _requestUpdate: (immediate=false) -> @_base.cancelUpdate() @_base.debug "Requesting update" - @plugin.protocolHandler.sendRequest @zoneCmd, '?', immediate + @protocolHandler.sendRequest @zoneCmd, '?', immediate .catch (error) => @_base.error "Error:", error .finally () => @@ -96,7 +99,7 @@ module.exports = (env) -> if @volumeLimit > 0 and newLevel > @volumeLimit newLevel = @volumeLimit - @plugin.protocolHandler.sendRequest(@zoneCmd, @_levelToVolumeParam (newLevel)).then => + @protocolHandler.sendRequest(@zoneCmd, @_levelToVolumeParam (newLevel)).then => @_setDimlevel newLevel @_requestUpdate() resolve()