Skip to content

Commit

Permalink
fix: keep node name and location in sync (#3592)
Browse files Browse the repository at this point in the history
  • Loading branch information
robertsLando authored Feb 13, 2024
1 parent e72217d commit 697967b
Showing 1 changed file with 79 additions and 32 deletions.
111 changes: 79 additions & 32 deletions api/lib/ZwaveClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,20 @@ const observedCCProps: {
})
},
},
[CommandClasses['Node Naming and Location']]: {
name(node, value) {
this.setNodeName(node.id, value.value).catch((error) => {
logger.error(`Error while setting node name: ${error.message}`)
})
},
location(node, value) {
this.setNodeLocation(node.id, value.value).catch((error) => {
logger.error(
`Error while setting node location: ${error.message}`,
)
})
},
},
}

export type SensorTypeScale = {
Expand Down Expand Up @@ -2462,7 +2476,9 @@ class ZwaveClient extends TypedEventEmitter<ZwaveClientEventCallbacks> {

if (zwaveNode && node) {
node.name = name
zwaveNode.name = name
if (zwaveNode.name !== name) {
zwaveNode.name = name
}
} else {
throw Error('Invalid Node ID')
}
Expand All @@ -2489,7 +2505,9 @@ class ZwaveClient extends TypedEventEmitter<ZwaveClientEventCallbacks> {

if (node) {
node.loc = loc
zwaveNode.location = loc
if (zwaveNode.location !== loc) {
zwaveNode.location = loc
}
} else {
throw Error('Invalid Node ID')
}
Expand Down Expand Up @@ -5350,7 +5368,7 @@ class ZwaveClient extends TypedEventEmitter<ZwaveClientEventCallbacks> {
if (zwaveNode.ready) {
const res = this._addValue(zwaveNode, args)

if (res.valueId) {
if (res?.valueId) {
const node = this._nodes.get(zwaveNode.id)
this.subscribeObservers(node, res.valueId)
}
Expand Down Expand Up @@ -6088,6 +6106,14 @@ class ZwaveClient extends TypedEventEmitter<ZwaveClientEventCallbacks> {
if (!node) {
logger.info(`ValueAdded: no such node: ${zwaveNode.id} error`)
} else {
// ignore node name and location CC, we already show the inputs for it
if (
zwaveValue.commandClass ===
CommandClasses['Node Naming and Location']
) {
return null
}

const zwaveValueMeta = zwaveNode.getValueMetadata(zwaveValue)

const valueId = this._parseValue(
Expand Down Expand Up @@ -6200,42 +6226,63 @@ class ZwaveClient extends TypedEventEmitter<ZwaveClientEventCallbacks> {

const valueId = node.values[vID]

if (valueId) {
// this is set when the updates comes from a write request
if (valueId.toUpdate) {
valueId.toUpdate = false
if (!valueId) {
// node name and location emit a value update but
// there could be no defined valueId as not all nodes
// support that CC but zwave-js does, also we ignore it
// on `_valueAdded`. Ref: (https://github.com/zwave-js/zwave-js-ui/issues/3591)
if (
args.commandClass ===
CommandClasses['Node Naming and Location']
) {
const prop = args.property
const observer =
observedCCProps[
CommandClasses['Node Naming and Location']
]?.[prop]

if (observer) {
observer.call(this, node, {
...args,
value: args.newValue,
})
}
}

let newValue = args.newValue
if (Buffer.isBuffer(newValue)) {
// encode Buffers as HEX strings
newValue = utils.buffer2hex(newValue)
}
return
}

let prevValue = args.prevValue
if (Buffer.isBuffer(prevValue)) {
// encode Buffers as HEX strings
prevValue = utils.buffer2hex(prevValue)
}
// this is set when the updates comes from a write request
if (valueId.toUpdate) {
valueId.toUpdate = false
}

valueId.value = newValue
valueId.stateless = !!args.stateless
let newValue = args.newValue
if (Buffer.isBuffer(newValue)) {
// encode Buffers as HEX strings
newValue = utils.buffer2hex(newValue)
}

if (this.valuesObservers[valueId.id]) {
this.valuesObservers[valueId.id].call(this, node, valueId)
}
let prevValue = args.prevValue
if (Buffer.isBuffer(prevValue)) {
// encode Buffers as HEX strings
prevValue = utils.buffer2hex(prevValue)
}

// ensure duration is never undefined
if (
valueId.type === 'duration' &&
valueId.value === undefined
) {
valueId.value = new Duration(undefined, 'seconds')
}
valueId.value = newValue
valueId.stateless = !!args.stateless

if (!skipUpdate) {
this.emitValueChanged(valueId, node, prevValue !== newValue)
}
if (this.valuesObservers[valueId.id]) {
this.valuesObservers[valueId.id].call(this, node, valueId)
}

// ensure duration is never undefined
if (valueId.type === 'duration' && valueId.value === undefined) {
valueId.value = new Duration(undefined, 'seconds')
}

if (!skipUpdate) {
this.emitValueChanged(valueId, node, prevValue !== newValue)
}

// if valueId is stateless, automatically reset the value after 1 sec
Expand Down

0 comments on commit 697967b

Please sign in to comment.