const rp = require('request-promise') const Promise = require('bluebird') const utils = require('./utils') class Bravia { constructor(ip, secret) { Object.assign(this, {ip, secret, cmd_cache: {}}) } request(options) { options.url = `http://${this.ip}${options.path}` options.headers = options.headers || {} options.headers['X-Auth-PSK'] = this.secret return rp.post(options) } sendIRCC(ircc) { const body = ` ${ircc} ` return this.request({ path: '/sony/IRCC', body, headers: { 'Content-Type': 'text/xml charset=UTF-8', 'SOAPACTION': '"urn:schemas-sony-com:service:IRCC:1#X_SendIRCC"' } }) } sendRPC(endpoint, method, ...params) { // endpoint \in {system, accessControl, encryption, recording, browser, appControl} // "getMethodTypes", "" is a good one to try return this.request({ path: `/sony/${endpoint}`, json: true, body: { method, params, id: 1, version: "1.0" } }) } lookupCommand(cmd, do_lookup = true) { if (this.cmd_cache[cmd]) return Promise.resolve(this.cmd_cache[cmd]) if(do_lookup) return this.sendRPC("system", "getRemoteControllerInfo").then((body) => { body.result[1].forEach(({name, value}) => this.cmd_cache[name] = value) return this.lookupCommand(cmd, false) }) else return Promise.reject("command not found") } sendCommand(cmd) { console.log("sending", cmd) return typeof cmd === 'number' ? Promise.delay(cmd) : Array.isArray(cmd) ? this.sequence(cmd) : this.lookupCommand(cmd).then(ircc => this.sendIRCC(ircc)) } sequence([cmd, ...commands]) { if (cmd == undefined) return Promise.resolve() return this.sendCommand(cmd).then(() => this.sequence(commands)) } delaySequence(cmds, delay=250) { this.sequence(utils.alternate(cmds, 250)) } } module.exports = Bravia