Skip to content

Commit

Permalink
Support homeassistant_rename for groups. #10672
Browse files Browse the repository at this point in the history
  • Loading branch information
Koenkk committed Jan 9, 2022
1 parent 6ac8a62 commit ee6b035
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 16 deletions.
4 changes: 2 additions & 2 deletions lib/eventBus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ export default class EventBus {
this.on('permitJoinChanged', callback, key);
}

public emitDeviceRenamed(data: eventdata.DeviceRenamed): void {
public emitEntityRenamed(data: eventdata.EntityRenamed): void {
this.emitter.emit('deviceRenamed', data);
}
public onDeviceRenamed(key: ListenerKey, callback: (data: eventdata.DeviceRenamed) => void): void {
public onEntityRenamed(key: ListenerKey, callback: (data: eventdata.EntityRenamed) => void): void {
this.on('deviceRenamed', callback, key);
}

Expand Down
3 changes: 2 additions & 1 deletion lib/extension/availability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ export default class Availability extends Extension {
}

override async start(): Promise<void> {
this.eventBus.onDeviceRenamed(this, (data) => this.publishAvailability(data.device, false, true));
this.eventBus.onEntityRenamed(this, (data) =>
data.entity.isDevice() && this.publishAvailability(data.entity, false, true));
this.eventBus.onDeviceRemoved(this, (data) => clearTimeout(this.timers[data.ieeeAddr]));
this.eventBus.onDeviceLeave(this, (data) => clearTimeout(this.timers[data.ieeeAddr]));
this.eventBus.onDeviceAnnounce(this, (data) => this.retrieveState(data.device));
Expand Down
5 changes: 3 additions & 2 deletions lib/extension/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default class Bridge extends Extension {
this.zigbee2mqttVersion = await utils.getZigbee2MQTTVersion();
this.coordinatorVersion = await this.zigbee.getCoordinatorVersion();

this.eventBus.onDeviceRenamed(this, () => this.publishInfo());
this.eventBus.onEntityRenamed(this, () => this.publishInfo());
this.eventBus.onGroupMembersChanged(this, () => this.publishGroups());
this.eventBus.onDevicesChanged(this, () => this.publishDevices() && this.publishInfo());
this.eventBus.onPermitJoinChanged(this, () => !this.zigbee.isStopping() && this.publishInfo());
Expand Down Expand Up @@ -455,9 +455,10 @@ export default class Bridge extends Extension {
// Clear retained messages
this.mqtt.publish(oldFriendlyName, '', {retain: true});

this.eventBus.emitEntityRenamed({entity: entity, homeAssisantRename, from: oldFriendlyName, to});

if (entity instanceof Device) {
this.publishDevices();
this.eventBus.emitDeviceRenamed({device: entity, homeAssisantRename, from: oldFriendlyName, to});
} else {
this.publishGroups();
this.publishInfo();
Expand Down
18 changes: 9 additions & 9 deletions lib/extension/homeassistant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export default class HomeAssistant extends Extension {

this.eventBus.onDeviceRemoved(this, this.onDeviceRemoved);
this.eventBus.onMQTTMessage(this, this.onMQTTMessage);
this.eventBus.onDeviceRenamed(this, this.onDeviceRenamed);
this.eventBus.onEntityRenamed(this, this.onEntityRenamed);
this.eventBus.onPublishEntityState(this, this.onPublishEntityState);
this.eventBus.onGroupMembersChanged(this, this.onGroupMembersChanged);
this.eventBus.onDeviceAnnounce(this, this.onZigbeeEvent);
Expand Down Expand Up @@ -858,25 +858,25 @@ export default class HomeAssistant extends Extension {
}
}

@bind onDeviceRenamed(data: eventdata.DeviceRenamed): void {
logger.debug(`Refreshing Home Assistant discovery topic for '${data.device.ieeeAddr}'`);
@bind onEntityRenamed(data: eventdata.EntityRenamed): void {
logger.debug(`Refreshing Home Assistant discovery topic for '${data.entity.name}'`);

// Clear before rename so Home Assistant uses new friendly_name
// https://github.com/Koenkk/zigbee2mqtt/issues/4096#issuecomment-674044916
if (data.homeAssisantRename) {
for (const config of this.getConfigs(data.device)) {
const topic = this.getDiscoveryTopic(config, data.device);
for (const config of this.getConfigs(data.entity)) {
const topic = this.getDiscoveryTopic(config, data.entity);
this.mqtt.publish(topic, null, {retain: true, qos: 0}, this.discoveryTopic, false, false);
}
}

this.discover(data.device, true);
this.discover(data.entity, true);

if (this.discoveredTriggers[data.device.ieeeAddr]) {
for (const config of this.discoveredTriggers[data.device.ieeeAddr]) {
if (data.entity.isDevice() && this.discoveredTriggers[data.entity.ieeeAddr]) {
for (const config of this.discoveredTriggers[data.entity.ieeeAddr]) {
const key = config.substring(0, config.indexOf('_'));
const value = config.substring(config.indexOf('_') + 1);
this.publishDeviceTriggerDiscover(data.device, key, value, true);
this.publishDeviceTriggerDiscover(data.entity, key, value, true);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/extension/legacy/bridgeLegacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export default class BridgeLegacy extends Extension {
logger.info(`Successfully renamed - ${from} to ${to} `);
const entity = this.zigbee.resolveEntity(to);
if (entity.isDevice()) {
this.eventBus.emitDeviceRenamed({homeAssisantRename: false, from, to, device: entity});
this.eventBus.emitEntityRenamed({homeAssisantRename: false, from, to, entity});
}

this.mqtt.publish(
Expand Down
2 changes: 1 addition & 1 deletion lib/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ declare global {
}

namespace eventdata {
type DeviceRenamed = { device: Device, homeAssisantRename: boolean, from: string, to: string };
type EntityRenamed = { entity: Device | Group, homeAssisantRename: boolean, from: string, to: string };
type DeviceRemoved = { ieeeAddr: string, name: string };
type MQTTMessage = { topic: string, message: string };
type MQTTMessagePublished = { topic: string, payload: string, options: {retain: boolean, qos: number} };
Expand Down
44 changes: 44 additions & 0 deletions test/homeassistant.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,50 @@ describe('HomeAssistant extension', () => {
);
});

it('Should refresh discovery when group is renamed', async () => {
MQTT.publish.mockClear();
MQTT.events.message('zigbee2mqtt/bridge/request/group/rename', stringify({"from": "ha_discovery_group", "to": "ha_discovery_group_new","homeassistant_rename":true}));
await flushPromises();

const payload = {
"availability":[{"topic":"zigbee2mqtt/bridge/state"}],
"brightness":true,
"brightness_scale":254,
"color_mode":true,
"command_topic":"zigbee2mqtt/ha_discovery_group_new/set",
"device":{
"identifiers":["zigbee2mqtt_1221051039810110150109113116116_9"],
"name":"ha_discovery_group_new",
"sw_version": version,
},
"json_attributes_topic":"zigbee2mqtt/ha_discovery_group_new",
"max_mireds": 454,
"min_mireds": 250,
"name":"ha_discovery_group_new",
"schema":"json",
"state_topic":"zigbee2mqtt/ha_discovery_group_new",
"supported_color_modes":[
"xy",
"color_temp"
],
"unique_id":"9_light_zigbee2mqtt"
};

expect(MQTT.publish).toHaveBeenCalledWith(
'homeassistant/light/1221051039810110150109113116116_9/light/config',
stringify(payload),
{ retain: true, qos: 0 },
expect.any(Function),
);

expect(MQTT.publish).toHaveBeenCalledWith(
'homeassistant/light/1221051039810110150109113116116_9/light/config',
null,
{ retain: true, qos: 0 },
expect.any(Function),
);
});

it('Shouldnt refresh discovery when device is renamed and homeassistant_rename is false', async () => {
MQTT.publish.mockClear();
MQTT.events.message('zigbee2mqtt/bridge/request/device/rename', stringify({"from": "weather_sensor", "to": "weather_sensor_renamed","homeassistant_rename":false}));
Expand Down

0 comments on commit ee6b035

Please sign in to comment.