Skip to content

Commit c5c884a

Browse files
committed
Fix PropertyValueService DI error — use exported ChannelsPropertiesService
PropertyValueService is a provider in DevicesModule but NOT in its exports list, so it's unavailable for injection in other modules. NestJS threw UnknownDependenciesException at startup. Replaced with channelsPropertiesService.update() which IS exported and matches the pattern used by the Z2M plugin for writing property values. This also triggers the proper WebSocket events for real-time UI updates. https://claude.ai/code/session_014bjB9Cn1WKASNLBeCuSbom
1 parent 1488b0f commit c5c884a

1 file changed

Lines changed: 26 additions & 17 deletions

File tree

apps/backend/src/plugins/devices-zigbee-herdsman/services/zigbee-herdsman.service.ts

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22
import { Injectable } from '@nestjs/common';
33

44
import { ExtensionLoggerService, createExtensionLogger } from '../../../common/logger';
5+
import { toInstance } from '../../../common/utils/transform.utils';
56
import { ConfigService } from '../../../modules/config/services/config.service';
67
import { ConnectionState } from '../../../modules/devices/devices.constants';
7-
import { ChannelPropertyEntity } from '../../../modules/devices/entities/devices.entity';
88
import { ChannelsPropertiesService } from '../../../modules/devices/services/channels.properties.service';
99
import { DeviceConnectivityService } from '../../../modules/devices/services/device-connectivity.service';
1010
import { DevicesService } from '../../../modules/devices/services/devices.service';
11-
import { PropertyValueService } from '../../../modules/devices/services/property-value.service';
1211
import {
1312
ConfigChangeResult,
1413
IManagedPluginService,
@@ -18,6 +17,8 @@ import {
1817
DEVICES_ZIGBEE_HERDSMAN_PLUGIN_NAME,
1918
DEVICES_ZIGBEE_HERDSMAN_TYPE,
2019
} from '../devices-zigbee-herdsman.constants';
20+
import { UpdateZigbeeHerdsmanChannelPropertyDto } from '../dto/update-channel-property.dto';
21+
import { ZigbeeHerdsmanChannelPropertyEntity } from '../entities/devices-zigbee-herdsman.entity';
2122
import { ZhDiscoveredDevice } from '../interfaces/zigbee-herdsman.interface';
2223
import { ZigbeeHerdsmanConfigModel } from '../models/config.model';
2324

@@ -44,7 +45,6 @@ export class ZigbeeHerdsmanService implements IManagedPluginService {
4445
private readonly configValidator: ZigbeeHerdsmanConfigValidatorService,
4546
private readonly devicesService: DevicesService,
4647
private readonly channelsPropertiesService: ChannelsPropertiesService,
47-
private readonly propertyValueService: PropertyValueService,
4848
private readonly deviceConnectivityService: DeviceConnectivityService,
4949
private readonly zhConnectivityService: ZhDeviceConnectivityService,
5050
) {}
@@ -265,20 +265,20 @@ export class ZigbeeHerdsmanService implements IManagedPluginService {
265265
return;
266266
}
267267

268-
// Write converted values to matching channel properties
269-
// Property identifiers are set to zigbee expose names during adoption
270-
const allProperties = await this.channelsPropertiesService.findAll<ChannelPropertyEntity>(
271-
undefined,
268+
// Write converted values to matching channel properties.
269+
// Property identifiers are set to zigbee expose names during adoption.
270+
// Use channelsPropertiesService.update() (exported from DevicesModule)
271+
// to persist values — this also triggers WebSocket events.
272+
const deviceChannelIds = device.channels?.map((c) => c.id) ?? [];
273+
if (deviceChannelIds.length === 0) {
274+
return;
275+
}
276+
277+
const deviceProperties = await this.channelsPropertiesService.findAll<ZigbeeHerdsmanChannelPropertyEntity>(
278+
deviceChannelIds,
272279
DEVICES_ZIGBEE_HERDSMAN_TYPE,
273280
);
274281

275-
// Filter to properties belonging to this device's channels
276-
const deviceChannelIds = new Set(device.channels?.map((c) => c.id) ?? []);
277-
const deviceProperties = allProperties.filter((p) => {
278-
const channelId = typeof p.channel === 'string' ? p.channel : p.channel?.id;
279-
return channelId && deviceChannelIds.has(channelId);
280-
});
281-
282282
for (const property of deviceProperties) {
283283
const stateKey = property.identifier;
284284
if (!stateKey || !(stateKey in convertedState)) {
@@ -291,10 +291,19 @@ export class ZigbeeHerdsmanService implements IManagedPluginService {
291291
}
292292

293293
try {
294-
const writeValue = typeof value === 'object' ? JSON.stringify(value) : (value as string | number | boolean);
295-
await this.propertyValueService.write(property, writeValue);
294+
const writeValue = typeof value === 'object' ? JSON.stringify(value) : value;
295+
await this.channelsPropertiesService.update<
296+
ZigbeeHerdsmanChannelPropertyEntity,
297+
UpdateZigbeeHerdsmanChannelPropertyDto
298+
>(
299+
property.id,
300+
toInstance(UpdateZigbeeHerdsmanChannelPropertyDto, {
301+
type: DEVICES_ZIGBEE_HERDSMAN_TYPE,
302+
value: writeValue,
303+
}),
304+
);
296305
} catch {
297-
// Non-critical — individual property write failures are logged by PropertyValueService
306+
// Non-critical — individual property write failures
298307
}
299308
}
300309
} catch (error) {

0 commit comments

Comments
 (0)