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

master
David Kebler 2020-07-11 11:27:29 -07:00
parent a59aac5c0e
commit 7c24aa3634
2 changed files with 56 additions and 39 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@uci/ha", "name": "@uci/ha",
"version": "0.0.7", "version": "0.0.9",
"description": "websocket api access to home assistant", "description": "websocket api access to home assistant",
"main": "./src/homeassistant.js", "main": "./src/homeassistant.js",
"scripts": { "scripts": {
@ -17,7 +17,7 @@
"better-try-catch": "^0.6.2", "better-try-catch": "^0.6.2",
"delay": "^4.3.0", "delay": "^4.3.0",
"faye-websocket": "^0.11.3", "faye-websocket": "^0.11.3",
"is-plain-object": "^3.0.0" "is-plain-object": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"esm": "^3.2.25", "esm": "^3.2.25",

View File

@ -29,6 +29,7 @@ class HomeAssistant extends EventEmitter {
this.cmdId = 1 this.cmdId = 1
this.eventBusId = null this.eventBusId = null
this._watchLists = {} this._watchLists = {}
this._watchList=[]
this._silence = [] this._silence = []
this.connected=false this.connected=false
this.ready=false this.ready=false
@ -36,6 +37,16 @@ class HomeAssistant extends EventEmitter {
this.on('error',msg=> log.error(msg)) 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 () { async connect () {
this.opts.retriesLeft = this.opts.retryCount this.opts.retriesLeft = this.opts.retryCount
let [err,socket] = await to(createSocket(this.url,this.opts)) 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) } isSilent(id) { return this._silence.includes(id) }
silence(id) { if (id) this._silence.push(id) } silence(id) { if (id) this._silence.push(id) }
hear(id) { if (id) this._silence = this._silence.filter(ent=> ent!==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() { async _listen() {
this.socket.on('message', (ev) => { 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}) this.emit('error',{msg:'failed json parse of event data', event:ev.data, error:err})
} else { } else {
log.debug('incoming message packet from server', packet.id, packet.type) log.debug('incoming message packet from server', packet.id, packet.type)
// event // console.log('ws event packet',packet)
if (packet.type === 'event') { if (packet.type === 'event') {
// this.emit(packet.id,packet.event) if(this._watchList.includes(packet.event.data.entity_id)) {
this.emit('event', packet) // console.log('emitting',packet.event.data.entity_id, packet.event.event_type)
if (packet.event.event_type === 'state_changed') { // this.emit('event', packet)
this.emit('state_changed',packet.event.data) if (packet.event.event_type === 'state_changed') {
if (!this.isSilent(packet.event.data.entity_id)) this.emit(packet.event.data.entity_id,packet.event.data.new_state) this.emit('state_changed',packet.event.data)
// else console.log(packet.event.data.entity_id, 'was silent, not emitting') // 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 return
} }
@ -158,6 +143,38 @@ class HomeAssistant extends EventEmitter {
} // end listen } // 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') { async getEntities (ents='all',type='obj') {
let single = false let single = false
if (typeof ents ==='string') { if (typeof ents ==='string') {