Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): show association error in association dialog #3804

Merged
merged 14 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions api/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ import jsonStore from './lib/jsonStore'
import * as loggers from './lib/logger'
import MqttClient from './lib/MqttClient'
import SocketManager from './lib/SocketManager'
import ZWaveClient, {
CallAPIResult,
configManager,
loadManager,
SensorTypeScale,
} from './lib/ZwaveClient'
import ZWaveClient, { CallAPIResult, SensorTypeScale } from './lib/ZwaveClient'
import multer, { diskStorage } from 'multer'
import extract from 'extract-zip'
import { serverVersion } from '@zwave-js/server'
Expand Down Expand Up @@ -49,6 +44,7 @@ import backupManager from './lib/BackupManager'
import { readFile, realpath } from 'fs/promises'
import { generate } from 'selfsigned'
import ZnifferManager, { ZnifferConfig } from './lib/ZnifferManager'
import { getAllNamedScaleGroups, getAllSensors } from '@zwave-js/core'

const createCertificate = promisify(generate)

Expand Down Expand Up @@ -258,7 +254,6 @@ export async function startServer(port: number | string, host?: string) {
setupSocket(server)
setupInterceptor()
await loadSnippets()
await loadManager()
startZniffer(settings.zniffer)
await startGateway(settings)
}
Expand Down Expand Up @@ -1061,15 +1056,15 @@ app.get(
apisLimiter,
isAuthenticated,
async function (req, res) {
const sensorTypes = configManager.sensorTypes
const sensorScalesGroups = configManager.namedScales
const allSensors = getAllSensors()
const namedScaleGroups = getAllNamedScaleGroups()

const scales: SensorTypeScale[] = []

for (const [key, group] of sensorScalesGroups) {
for (const [, scale] of group) {
for (const group of namedScaleGroups) {
for (const scale of Object.values(group.scales)) {
scales.push({
key: key,
key: group.name,
sensor: group.name,
unit: scale.unit,
label: scale.label,
Expand All @@ -1078,8 +1073,8 @@ app.get(
}
}

for (const [, sensor] of sensorTypes) {
for (const [, scale] of sensor.scales) {
for (const sensor of allSensors) {
for (const scale of Object.values(sensor.scales)) {
scales.push({
key: sensor.key,
sensor: sensor.label,
Expand Down
18 changes: 6 additions & 12 deletions api/lib/Constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ConfigManager } from '@zwave-js/config'
import { getMeter, getMeterScale } from '@zwave-js/core'

interface IGenericMap {
[key: number]: string
Expand Down Expand Up @@ -113,19 +113,13 @@ export function productionType(index: number): Record<string, any> {
},
}
}
export function meterType(
ccSpecific: IMeterCCSpecific,
configManager: ConfigManager,
): any {
const meter = configManager.lookupMeter(ccSpecific.meterType)
const scale = configManager.lookupMeterScale(
ccSpecific.meterType,
ccSpecific.scale,
)
export function meterType(ccSpecific: IMeterCCSpecific): any {
const meter = getMeter(ccSpecific.meterType)
const scale = getMeterScale(ccSpecific.meterType, ccSpecific.scale)

const cfg = {
sensor: meter ? meter.name : 'unknown',
objectId: scale ? scale.label : `unknown${ccSpecific.scale}`,
sensor: meter?.name || 'unknown',
objectId: scale?.label || `unknown${ccSpecific.scale}`,
props: {},
}

Expand Down
1 change: 0 additions & 1 deletion api/lib/Gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1566,7 +1566,6 @@ export default class Gateway {
if (valueId.ccSpecific) {
sensor = Constants.meterType(
valueId.ccSpecific as IMeterCCSpecific,
this._zwave.driver.configManager,
)

sensor.objectId += '_' + valueId.property
Expand Down
4 changes: 1 addition & 3 deletions api/lib/ZnifferManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,7 @@ export default class ZnifferManager extends TypedEventEmitter<ZnifferManagerEven

private ccToLogRecord(commandClass: CommandClass): Record<string, any> {
try {
const parsed: Record<string, any> = commandClass.toLogEntry(
this.zniffer as any,
)
const parsed: Record<string, any> = commandClass.toLogEntry()

if (isEncapsulatingCommandClass(commandClass)) {
parsed.encapsulated = [
Expand Down
93 changes: 47 additions & 46 deletions api/lib/ZwaveClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ import {
InclusionUserCallbacks,
InclusionState,
ProvisioningEntryStatus,
AssociationCheckResult,
LinkReliabilityCheckResult,
} from 'zwave-js'
import { getEnumMemberName, parseQRCodeString } from 'zwave-js/Utils'
Expand All @@ -128,11 +129,6 @@ export const configManager = new ConfigManager({
deviceConfigPriorityDir,
})

export async function loadManager() {
await configManager.loadNamedScales()
await configManager.loadSensorTypes()
}

const logger = LogManager.module('Z-Wave')
// eslint-disable-next-line @typescript-eslint/no-var-requires
const loglevels = require('triple-beam').configs.npm.levels
Expand Down Expand Up @@ -162,6 +158,7 @@ export const allowedApis = validateMethods([
'getNodeNeighbors',
'discoverNodeNeighbors',
'getAssociations',
'checkAssociation',
'addAssociations',
'removeAssociations',
'removeAllAssociations',
Expand Down Expand Up @@ -1763,6 +1760,21 @@ class ZwaveClient extends TypedEventEmitter<ZwaveClientEventCallbacks> {
return toReturn
}

/**
* Check if a given association is allowed
*/
checkAssociation(
source: AssociationAddress,
groupId: number,
association: AssociationAddress,
) {
return this.driver.controller.checkAssociation(
source,
groupId,
association,
)
}

/**
* Add a node to the array of specified [associations](https://zwave-js.github.io/node-zwave-js/#/api/controller?id=association-interface)
*/
Expand All @@ -1778,53 +1790,41 @@ class ZwaveClient extends TypedEventEmitter<ZwaveClientEventCallbacks> {
(source.endpoint ? ' Endpoint ' + source.endpoint : '')
}`

if (zwaveNode) {
try {
for (const a of associations) {
if (
this._driver.controller.isAssociationAllowed(
source,
groupId,
a,
)
) {
this.logNode(
zwaveNode,
'info',
`Adding Node ${a.nodeId} to Group ${groupId} of ${sourceMsg}`,
)
if (!zwaveNode) {
throw new Error(`Node ${source.nodeId} not found`)
}

await this._driver.controller.addAssociations(
source,
groupId,
[a],
)
const result: AssociationCheckResult[] = []

return true
} else {
this.logNode(
zwaveNode,
'warn',
`Unable to add Node ${a.nodeId} to Group ${groupId} of ${sourceMsg}, association not allowed`,
)
}
}
} catch (error) {
for (const a of associations) {
const checkResult = this._driver.controller.checkAssociation(
source,
groupId,
a,
)

result.push(checkResult)

if (checkResult === AssociationCheckResult.OK) {
this.logNode(
zwaveNode,
'info',
`Adding Node ${a.nodeId} to Group ${groupId} of ${sourceMsg}`,
)

await this._driver.controller.addAssociations(source, groupId, [
a,
])
} else {
this.logNode(
zwaveNode,
'warn',
`Error while adding associations to ${sourceMsg}: ${error.message}`,
`Unable to add Node ${a.nodeId} to Group ${groupId} of ${sourceMsg}: ${getEnumMemberName(AssociationCheckResult, checkResult)}`,
)
}
} else {
this.logNode(
zwaveNode,
'warn',
`Error while adding associations to ${sourceMsg}, node not found`,
)
}

return false
return result
}

/**
Expand Down Expand Up @@ -4631,7 +4631,8 @@ class ZwaveClient extends TypedEventEmitter<ZwaveClientEventCallbacks> {
}
}

private _onInclusionStarted(secure: boolean) {
private _onInclusionStarted(strategy: InclusionStrategy) {
const secure = strategy !== InclusionStrategy.Insecure
const message = `${secure ? 'Secure' : 'Non-secure'} inclusion started`
this._updateControllerStatus(message)
this.emit('event', EventSource.CONTROLLER, 'inclusion started', secure)
Expand Down Expand Up @@ -5612,7 +5613,7 @@ class ZwaveClient extends TypedEventEmitter<ZwaveClientEventCallbacks> {
this.logNode(
endpoint.nodeId,
'error',
`Notification received but node doesn't exists`,
`Notification received but node doesn't exist`,
)

return
Expand Down Expand Up @@ -6026,7 +6027,7 @@ class ZwaveClient extends TypedEventEmitter<ZwaveClientEventCallbacks> {
node.keepAwake = zwaveNode.keepAwake
node.maxDataRate = zwaveNode.maxDataRate
node.deviceClass = {
basic: zwaveNode.deviceClass?.basic.key,
basic: zwaveNode.deviceClass?.basic,
generic: zwaveNode.deviceClass?.generic.key,
specific: zwaveNode.deviceClass?.specific.key,
}
Expand Down
Loading
Loading