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

Fix: remove groups from hass #23492

Merged
merged 10 commits into from
Aug 4, 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
4 changes: 2 additions & 2 deletions lib/eventBus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ export default class EventBus {
this.on('deviceRenamed', callback, key);
}

public emitDeviceRemoved(data: eventdata.DeviceRemoved): void {
public emitEntityRemoved(data: eventdata.EntityRemoved): void {
this.emitter.emit('deviceRemoved', data);
}
public onDeviceRemoved(key: ListenerKey, callback: (data: eventdata.DeviceRemoved) => void): void {
public onEntityRemoved(key: ListenerKey, callback: (data: eventdata.EntityRemoved) => void): void {
this.on('deviceRemoved', callback, key);
}

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

this.eventBus.onDeviceRemoved(this, (data) => clearTimeout(this.timers[data.ieeeAddr]));
this.eventBus.onEntityRemoved(this, (data) => data.type == 'device' && clearTimeout(this.timers[data.id]));
this.eventBus.onDeviceLeave(this, (data) => clearTimeout(this.timers[data.ieeeAddr]));
this.eventBus.onDeviceAnnounce(this, (data) => this.retrieveState(data.device));
this.eventBus.onLastSeenChanged(this, this.onLastSeenChanged);
Expand Down
5 changes: 3 additions & 2 deletions lib/extension/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,6 @@ export default class Bridge extends Extension {

try {
logger.info(`Removing ${entityType} '${entity.name}'${blockForceLog}`);
const ieeeAddr = entity.isDevice() && entity.ieeeAddr;
const name = entity.name;

if (entity instanceof Device) {
Expand All @@ -641,7 +640,9 @@ export default class Bridge extends Extension {

// Fire event
if (entity instanceof Device) {
this.eventBus.emitDeviceRemoved({ieeeAddr, name});
this.eventBus.emitEntityRemoved({id: entityID, name, type: 'device'});
} else {
this.eventBus.emitEntityRemoved({id: entityID, name, type: 'group'});
}

// Remove from configuration.yaml
Expand Down
12 changes: 6 additions & 6 deletions lib/extension/homeassistant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export default class HomeAssistant extends Extension {
this.discoveryOrigin = {name: 'Zigbee2MQTT', sw: this.zigbee2MQTTVersion, url: 'https://www.zigbee2mqtt.io'};
this.bridge = this.getBridgeEntity(await this.zigbee.getCoordinatorVersion());
this.bridgeIdentifier = this.getDevicePayload(this.bridge).identifiers[0];
this.eventBus.onDeviceRemoved(this, this.onDeviceRemoved);
this.eventBus.onEntityRemoved(this, this.onEntityRemoved);
this.eventBus.onMQTTMessage(this, this.onMQTTMessage);
this.eventBus.onEntityRenamed(this, this.onEntityRenamed);
this.eventBus.onPublishEntityState(this, this.onPublishEntityState);
Expand Down Expand Up @@ -244,8 +244,8 @@ export default class HomeAssistant extends Extension {
this.eventBus.emitPublishAvailability();
}

private getDiscovered(entity: Device | Group | Bridge | string): Discovered {
const ID = typeof entity === 'string' ? entity : entity.ID;
private getDiscovered(entity: Device | Group | Bridge | string | number): Discovered {
const ID = typeof entity === 'string' || typeof entity === 'number' ? entity : entity.ID;
if (!(ID in this.discovered)) {
this.discovered[ID] = {messages: {}, triggers: new Set(), mockProperties: new Set(), discovered: false};
}
Expand Down Expand Up @@ -1194,15 +1194,15 @@ export default class HomeAssistant extends Extension {
return discoveryEntries;
}

@bind async onDeviceRemoved(data: eventdata.DeviceRemoved): Promise<void> {
@bind async onEntityRemoved(data: eventdata.EntityRemoved): Promise<void> {
logger.debug(`Clearing Home Assistant discovery for '${data.name}'`);
const discovered = this.getDiscovered(data.ieeeAddr);
const discovered = this.getDiscovered(data.id);

for (const topic of Object.keys(discovered.messages)) {
await this.mqtt.publish(topic, null, {retain: true, qos: 1}, this.discoveryTopic, false, false);
}

delete this.discovered[data.ieeeAddr];
delete this.discovered[data.id];
}

@bind async onGroupMembersChanged(data: eventdata.GroupMembersChanged): Promise<void> {
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 @@ -295,7 +295,7 @@ export default class BridgeLegacy extends Extension {

const cleanup = async (): Promise<void> => {
// Fire event
this.eventBus.emitDeviceRemoved({ieeeAddr, name});
this.eventBus.emitEntityRemoved({id: ieeeAddr, name: name, type: 'device'});

// Remove from configuration.yaml
settings.removeDevice(entity.ieeeAddr);
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 @@ -73,7 +73,7 @@ declare global {

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

it('Should clear discovery when group is removed', async () => {
MQTT.publish.mockClear();
MQTT.events.message('zigbee2mqtt/bridge/request/group/remove', stringify({id: 'ha_discovery_group'}));
await flushPromises();

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

it('Should refresh discovery when device is renamed', async () => {
await MQTT.events.message(
'homeassistant/device_automation/0x0017880104e45522/action_double/config',
Expand Down