fix: Improve nested group and device name match (#21521)

This commit is contained in:
Oleksandr Masliuchenko
2024-02-22 19:54:09 +01:00
committed by GitHub
parent 22d33360f6
commit 471902e531
2 changed files with 18 additions and 24 deletions
+6 -13
View File
@@ -10,7 +10,7 @@ import Group from '../model/group';
import Device from '../model/device';
import bind from 'bind-decorator';
const topicGetSetRegex = new RegExp(`^(.+?)(?:/([^/]+))?/(get|set)(?:/(.+))?`);
const topicGetSetRegex = new RegExp(`^(.+?)/(get|set)(?:/(.+))?`);
const stateValues = ['on', 'off', 'toggle', 'open', 'close', 'stop', 'lock', 'unlock'];
const sceneConverterKeys = ['scene_store', 'scene_add', 'scene_remove', 'scene_remove_all', 'scene_rename'];
@@ -56,20 +56,13 @@ export default class Publish extends Extension {
// After it there will be an optional attribute name.
const match = topic.match(topicGetSetRegex);
if (!match) return null;
let deviceName = match[1];
let endpointName = match[2];
const attribute = match[4];
// There can be some ambiguoty between 'device_name/endpoint' and 'device/name/with/slashes' with no endpoint
// Try to ensure the device with one of these names exist
const re = this.zigbee.resolveEntity(deviceName);
if (re == null && endpointName) {
// Possibly the last before get/set is just a continuation of the device name
deviceName = `${deviceName}/${endpointName}`;
endpointName = null;
}
const deviceNameAndEndpoint = match[1];
const attribute = match[3];
return {ID: deviceName, endpoint: endpointName, type: match[3] as 'get' | 'set', attribute: attribute};
// Now parse the device/group name, and endpoint name
const entity = this.zigbee.resolveEntityAndEndpoint(deviceNameAndEndpoint);
return {ID: entity.ID, endpoint: entity.endpointID, type: match[2] as 'get' | 'set', attribute: attribute};
}
parseMessage(parsedTopic: ParsedTopic, data: eventdata.MQTTMessage): KeyValue | null {
+12 -11
View File
@@ -293,19 +293,20 @@ export default class Zigbee {
// device/name (device name with slashes)
// device/name/ep_name (device name with slashes, and endpoint numeric ID or name)
// First split the input token by the latest slash
const match = ID.match(entityIDRegex);
// The function tries to find an exact match first
let entityName = ID;
let deviceOrGroup = this.resolveEntity(ID);
let endpointNameOrID = null;
// Try to match 'device_name/endpoint' pattern
let entityName = match[1];
let deviceOrGroup = this.resolveEntity(match[1]);
let endpointNameOrID = match[2];
// If 'device_name/endpoint' pattern does not match, perhaps this is device name with slashes
// If exact match did not happenc, try matching a device_name/endpoint pattern
if (!deviceOrGroup) {
entityName = ID;
deviceOrGroup = this.resolveEntity(ID);
endpointNameOrID = null;
// First split the input token by the latest slash
const match = ID.match(entityIDRegex);
// Get the resulting IDs from the match
entityName = match[1];
deviceOrGroup = this.resolveEntity(match[1]);
endpointNameOrID = match[2];
}
// If the function returns non-null endpoint name, but the endpoint field is null, then