{"version":3,"sources":["jsdelivr-header.js","/npm/roon-extension-arcam@0.0.6/app.js"],"names":[],"mappings":"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","file":"/npm/roon-extension-arcam@0.0.6/app.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/roon-extension-arcam@0.0.6/app.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","'use strict';\n\nconst debug                = require('debug')('roon-extension-arcam'),\n      debug_keepalive      = require('debug')('roon-extension-arcam:keepalive'),\n      Promise              = require('bluebird'),\n      Arcam                = require('./arcam_client'),\n      RoonApi              = require('node-roon-api'),\n      RoonApiSettings      = require('node-roon-api-settings'),\n      RoonApiStatus        = require('node-roon-api-status'),\n      RoonApiVolumeControl = require('node-roon-api-volume-control');\n\nvar arcam = {};\nvar roon = new RoonApi({\n    extension_id:        'org.pruessmann.roon.arcam',\n    display_name:        'Arcam AVR390/550/850/AV860/SR250',\n    display_version:     '0.0.6',\n    publisher:           'Doc Bobo',\n    email:               'boris@pruessmann.org',\n    website:             'https://github.com/docbobo/roon-extension-arcam',\n});\n\nvar mysettings = roon.load_config(\"settings\") || {\n    hostname: \"\",\n    keepalive: 60000\n};\n\nfunction make_layout(settings) {\n    var l = {\n        values:    settings,\n        layout:    [],\n        has_error: false\n    };\n\n    l.layout.push({\n        type:      \"string\",\n        title:     \"Host name or IP Address\",\n        subtitle:  \"The IP address or hostname of the Arcam receiver.\",\n        maxlength: 256,\n        setting:   \"hostname\",\n    });\n\n    return l;\n}\n\nvar svc_settings = new RoonApiSettings(roon, {\n    get_settings: function(cb) {\n        cb(make_layout(mysettings));\n    },\n    save_settings: function(req, isdryrun, settings) {\n        let l = make_layout(settings.values);\n        req.send_complete(l.has_error ? \"NotValid\" : \"Success\", { settings: l });\n\n        if (!isdryrun && !l.has_error) {\n            var old_hostname = mysettings.hostname;\n            mysettings = l.values;\n            svc_settings.update_settings(l);\n            if (old_hostname != mysettings.hostname) setup_arcam_connection(mysettings.hostname, mysettings.keepalive);\n            roon.save_config(\"settings\", mysettings);\n        }\n    }\n});\n\nvar svc_status = new RoonApiStatus(roon);\nvar svc_volume_control = new RoonApiVolumeControl(roon);\n\nroon.init_services({\n    provided_services: [ svc_status, svc_settings, svc_volume_control ]\n});\n\nfunction setup_arcam_connection(host, keepalive) {\n    debug(\"setup_arcam_connection (\" + host + \")\");\n\n    if (arcam.keepalive) { clearInterval(arcam.keepalive); arcam.keepalive = null; }\n    if (arcam.client) { arcam.client.disconnect(); delete(arcam.client); }\n\n    if (!host) {\n        svc_status.set_status(\"Not configured, please check settings.\", true);\n    } else {\n        debug(\"Connecting to receiver...\");\n        svc_status.set_status(\"Connecting to '\" + host + \"'...\", false);\n\n        arcam.client = new Arcam.ArcamClient(host);\n        arcam.client.socket.setTimeout(0);\n        arcam.client.socket.setKeepAlive(true, 10000);\n\n        arcam.client.socket.on('error', (error) => {\n            // Handler for debugging purposes. No need to reconnect since the event will be followed by a close event,\n            // according to documentation.\n            debug('Received onError(%O)', error);\n        });\n\n        arcam.client.socket.on('timeout', () => {\n            debug('Received onTimeout(): Closing connection...');\n            arcam.client.disconnect();\n        });\n\n        arcam.client.on('close', (had_error) => {\n            debug('Received onClose(%O): Reconnecting...', had_error);\n            svc_status.set_status(\"Connection closed. Reconnecting...\", true);\n\n            if (!arcam.reconnect) {\n                arcam.reconnect = setTimeout(() => {\n                    debug(\"Attempting to reconnect\");\n                    arcam.client.connect().then(() => {\n                        arcam.reconnect = null;\n                        svc_status.set_status(\"Connected to receiver\", false);\n                    });\n                }, 1000);\n            }\n        });\n\n        arcam.client.connect().then(() => {\n            create_volume_control(arcam).then(() => {\n                svc_status.set_status(\"Connected to '\" + host + \"'\", false);\n            });\n        }).catch((error) => {\n            debug(\"setup_arcam_connection: Error during setup. Retrying...\");\n\n            // TODO: Fix error message\n            console.log(error);\n            svc_status.set_status(\"Could not connect receiver: \" + error, true);\n        });\n\n        arcam.keepalive = setInterval(() => {\n            // Make regular calls to heartbeat for keep-alive.\n            arcam.client.heartbeat().then((val) => {\n                debug_keepalive(\"Keep-Alive: heartbeat == %s\", val);\n            });\n        }, keepalive);\n    }\n}\n\nfunction create_volume_control(arcam) {\n    debug(\"create_volume_control: volume_control=%o\", arcam.volume_control)\n\n    var result = arcam.client;\n    if (!arcam.volume_control) {\n        arcam.state = {\n            control_key: 1,\n            display_name: \"Main Zone\",\n            volume_type:  \"number\",\n            volume_min:   0,\n            volume_max:   99,\n            volume_step:  1,\n        };\n\n        var device = {\n            state: arcam.state,\n\n            set_volume: function (req, mode, value) {\n                debug(\"set_volume: mode=%s value=%d\", mode, value);\n\n                let newvol = mode == \"absolute\" ? value : (state.volume_value + value);\n                if      (newvol < this.state.volume_min) newvol = this.state.volume_min;\n                else if (newvol > this.state.volume_max) newvol = this.state.volume_max;\n\n                arcam.client.setVolume(newvol).then(() => {\n                    debug(\"set_volume: Succeeded.\");\n                    req.send_complete(\"Success\");\n                }).catch((error) => {\n                    debug(\"set_volume: Failed with error.\");\n\n                    console.log(error);\n                    req.send_complete(\"Failed\");\n                });\n            },\n\n            set_mute: function (req, inAction) {\n                debug(\"set_mute: action=%s\", inAction);\n\n                const action = !this.state.is_muted ? \"on\" : \"off\";\n                arcam.client.setMute(action === \"on\" ? Arcam.Options.MuteOptions.On : Arcam.Options.MuteOptions.Off).then(() => {\n                    debug(\"set_mute: Succeeded.\");\n                    req.send_complete(\"Success\");\n                }).catch((error) => {\n                    debug(\"set_mute: Failed.\");\n\n                    console.log(error);\n                    req.send_complete(\"Failed\");\n                });\n            }\n        };\n\n        result = Promise.join(arcam.client.getVolume(), arcam.client.getMute(), function(volume, is_muted) {\n            arcam.state.volume_value = volume;\n            arcam.state.is_muted = (is_muted === Arcam.Options.MuteOptions.On);\n\n            debug(\"Registering volume control extension\");\n            arcam.volume_control = svc_volume_control.new_device(device);\n        }).catch((error) => {\n            console.log(error);\n        });\n    }\n\n    return result.then(() => {\n        debug(\"Subscribing to events from receiver\");\n\n        arcam.client.on('muteChanged', (val) => {\n            debug(\"muteChanged: val=%s\", val);\n\n            let old_is_muted = arcam.state.is_muted;\n            arcam.state.is_muted = val === Arcam.Options.MuteOptions.On;\n            if (old_is_muted != arcam.state.is_muted) {\n                debug(\"mute differs - updating\");\n                arcam.volume_control.update_state({ is_muted: arcam.state.is_muted });\n            }\n        });\n\n        arcam.client.on('masterVolumeChanged', (val) => {\n            debug(\"masterVolumeChanged: val=%s\", val);\n\n            let old_volume_value = arcam.state.volume_value;\n            arcam.state.volume_value = val;\n            if (old_volume_value != arcam.state.volume_value) {\n                debug(\"masterVolume differs - updating\");\n                arcam.volume_control.update_state({ volume_value: arcam.state.volume_value });\n            }\n        });\n    });\n}\n\nsetup_arcam_connection(mysettings.hostname, mysettings.keepalive);\n\nroon.start_discovery();\n"]}