From 7c24aa36341f10af90db1ab98e0f62c88591ee93 Mon Sep 17 00:00:00 2001 From: David Kebler Date: Sat, 11 Jul 2020 11:27:29 -0700 Subject: [PATCH] 0.0.9 add a per entity watch and unwatch instead of using .on listener allow creating a watch list so only watched ha entity events are processed --- package.json | 4 +- src/homeassistant.js | 91 ++++++++++++++++++++++++++------------------ 2 files changed, 56 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index 6983aa7..1613283 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@uci/ha", - "version": "0.0.7", + "version": "0.0.9", "description": "websocket api access to home assistant", "main": "./src/homeassistant.js", "scripts": { @@ -17,7 +17,7 @@ "better-try-catch": "^0.6.2", "delay": "^4.3.0", "faye-websocket": "^0.11.3", - "is-plain-object": "^3.0.0" + "is-plain-object": "^3.0.1" }, "devDependencies": { "esm": "^3.2.25", diff --git a/src/homeassistant.js b/src/homeassistant.js index edc008a..c27a245 100644 --- a/src/homeassistant.js +++ b/src/homeassistant.js @@ -29,6 +29,7 @@ class HomeAssistant extends EventEmitter { this.cmdId = 1 this.eventBusId = null this._watchLists = {} + this._watchList=[] this._silence = [] this.connected=false this.ready=false @@ -36,6 +37,16 @@ class HomeAssistant extends EventEmitter { this.on('error',msg=> log.error(msg)) } + watch (ent,handler) { + this._watchList.push(ent) + this.on(ent,handler) + } + + unWatch(ent) { + this._watchList = this._watchList.filter(e=>e!==ent) + this.removeListener(ent) + } + async connect () { this.opts.retriesLeft = this.opts.retryCount let [err,socket] = await to(createSocket(this.url,this.opts)) @@ -77,36 +88,6 @@ class HomeAssistant extends EventEmitter { isSilent(id) { return this._silence.includes(id) } silence(id) { if (id) this._silence.push(id) } hear(id) { if (id) this._silence = this._silence.filter(ent=> ent!==id) } - send (cmd,options={}) { - return new Promise( (resolve, reject) => { - // if (!this.connected) reject({error:'disconnected', packet:packet}) - let packet = options - if (isPlainObject(cmd)) { packet = cmd } - else { - packet.type = cmd - } - packet.id = packet.id || this.nextId() - // console.log('message to send', packet) - let [err, message] = btc(JSON.stringify)(packet) // try/catch or btc - if (err) { - const error = {msg:'failed to parse message', packet:packet} - this.emit('error',error) - reject(error) - } - this.socket.send(message) - let timeout = setTimeout( ()=>{ - let error = {msg:'failed to get a response in 5 seconds', packet:packet} - reject(error) - this.emit('error',error) - },5000) - this.on(packet.id, (res) => { - log.debug({msg:'reply packet from send', packet:packet, response:res}) - clearTimeout(timeout) - resolve(res) - }) - - }) - } async _listen() { this.socket.on('message', (ev) => { @@ -115,14 +96,18 @@ class HomeAssistant extends EventEmitter { this.emit('error',{msg:'failed json parse of event data', event:ev.data, error:err}) } else { log.debug('incoming message packet from server', packet.id, packet.type) - // event + // console.log('ws event packet',packet) if (packet.type === 'event') { - // this.emit(packet.id,packet.event) - this.emit('event', packet) - if (packet.event.event_type === 'state_changed') { - this.emit('state_changed',packet.event.data) - if (!this.isSilent(packet.event.data.entity_id)) this.emit(packet.event.data.entity_id,packet.event.data.new_state) - // else console.log(packet.event.data.entity_id, 'was silent, not emitting') + if(this._watchList.includes(packet.event.data.entity_id)) { + // console.log('emitting',packet.event.data.entity_id, packet.event.event_type) + // this.emit('event', packet) + if (packet.event.event_type === 'state_changed') { + this.emit('state_changed',packet.event.data) + // console.log('emitting',packet.event.data.entity_id,!this.isSilent(packet.event.data.entity_id)) + if (!this.isSilent(packet.event.data.entity_id)) + this.emit(packet.event.data.entity_id,packet.event.data.new_state) + // else console.log(packet.event.data.entity_id, 'was silent, not emitting') + } } return } @@ -158,6 +143,38 @@ class HomeAssistant extends EventEmitter { } // end listen + send (cmd,options={}) { + return new Promise( (resolve, reject) => { + // if (!this.connected) reject({error:'disconnected', packet:packet}) + let packet = options + if (isPlainObject(cmd)) { packet = cmd } + else { + packet.type = cmd + } + packet.id = packet.id || this.nextId() + // console.log('message to send', packet) + let [err, message] = btc(JSON.stringify)(packet) // try/catch or btc + if (err) { + const error = {msg:'failed to parse message', packet:packet} + this.emit('error',error) + reject(error) + } + this.socket.send(message) + let timeout = setTimeout( ()=>{ + let error = {msg:'failed to get a response in 5 seconds', packet:packet} + reject(error) + this.emit('error',error) + },5000) + this.on(packet.id, (res) => { + log.debug({msg:'reply packet from send', packet:packet, response:res}) + clearTimeout(timeout) + resolve(res) + }) + + }) + } + + async getEntities (ents='all',type='obj') { let single = false if (typeof ents ==='string') {