mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-08-22 10:39:58 +00:00
Add device icon from converter definition (#7001)
This commit is contained in:
+14
-3
@@ -116,7 +116,7 @@ class Bridge extends Extension {
|
||||
if (data.status === 'successful') {
|
||||
const definition = resolvedEntity.definition;
|
||||
payload.supported = !!definition;
|
||||
payload.definition = this.getDefinitionPayload(definition);
|
||||
payload.definition = this.getDefinitionPayload(definition, resolvedEntity);
|
||||
}
|
||||
} else if (type === 'deviceAnnounce') {
|
||||
payload = {
|
||||
@@ -618,7 +618,7 @@ class Bridge extends Extension {
|
||||
network_address: device.networkAddress,
|
||||
supported: !!definition,
|
||||
friendly_name: resolved.name,
|
||||
definition: this.getDefinitionPayload(definition),
|
||||
definition: this.getDefinitionPayload(definition, resolved),
|
||||
power_source: device.powerSource,
|
||||
software_build_id: device.softwareBuildID,
|
||||
date_code: device.dateCode,
|
||||
@@ -652,14 +652,25 @@ class Bridge extends Extension {
|
||||
'bridge/groups', stringify(groups), {retain: true, qos: 0}, settings.get().mqtt.base_topic, true);
|
||||
}
|
||||
|
||||
getDefinitionPayload(definition) {
|
||||
getDefinitionPayload(definition, resolvedDevice) {
|
||||
if (definition) {
|
||||
let icon = definition.icon;
|
||||
if (icon) {
|
||||
let zigbeeModel = '';
|
||||
/* istanbul ignore else */
|
||||
if (resolvedDevice && resolvedDevice.hasOwnProperty('device')) {
|
||||
zigbeeModel = resolvedDevice.device.modelID;
|
||||
}
|
||||
icon = icon.replace('${zigbeeModel}', utils.sanitizeImageParameter(zigbeeModel));
|
||||
icon = icon.replace('${model}', utils.sanitizeImageParameter(definition.model));
|
||||
}
|
||||
return {
|
||||
model: definition.model,
|
||||
vendor: definition.vendor,
|
||||
description: definition.description,
|
||||
exposes: definition.exposes,
|
||||
supports_ota: !!definition.ota,
|
||||
icon,
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
|
||||
@@ -243,6 +243,13 @@ function sleep(seconds) {
|
||||
return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
|
||||
}
|
||||
|
||||
function sanitizeImageParameter(parameter) {
|
||||
const replaceByDash = [/\?/g, /&/g, /[^a-z\d\- _./:]/gi];
|
||||
let sanitized = parameter;
|
||||
replaceByDash.forEach((r) => sanitized = sanitized.replace(r, '-'));
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
millisecondsToSeconds: (milliseconds) => milliseconds / 1000,
|
||||
secondsToMilliseconds: (seconds) => seconds * 1000,
|
||||
@@ -268,4 +275,5 @@ module.exports = {
|
||||
loadModuleFromFile,
|
||||
loadModuleFromText,
|
||||
getKey,
|
||||
sanitizeImageParameter,
|
||||
};
|
||||
|
||||
+43
-1
@@ -1048,4 +1048,46 @@ describe('Bridge', () => {
|
||||
{retain: false, qos: 0}, expect.any(Function)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('Icon link handling', async () => {
|
||||
const bridge = controller.extensions.find((e) => e.constructor.name === 'Bridge');
|
||||
expect(bridge).not.toBeUndefined();
|
||||
|
||||
const definition = {'model': 'lumi.plug'};
|
||||
const device = zigbeeHerdsman.devices.ZNCZ02LM;
|
||||
const icon_link = 'https://www.zigbee2mqtt.io/images/devices/ZNCZ02LM.jpg';
|
||||
definition.icon = icon_link;
|
||||
let payload = bridge.getDefinitionPayload(definition, {device: device});
|
||||
expect(payload).not.toBeUndefined()
|
||||
expect(payload['icon']).not.toBeUndefined()
|
||||
expect(payload.icon).toBe(icon_link);
|
||||
|
||||
definition.icon = '_${model}_';
|
||||
payload = bridge.getDefinitionPayload(definition, {device: device});
|
||||
expect(payload).not.toBeUndefined()
|
||||
expect(payload['icon']).not.toBeUndefined()
|
||||
expect(payload.icon).toBe('_lumi.plug_');
|
||||
|
||||
definition.icon = '_${model}_${zigbeeModel}_';
|
||||
payload = bridge.getDefinitionPayload(definition, {device: device});
|
||||
expect(payload).not.toBeUndefined()
|
||||
expect(payload['icon']).not.toBeUndefined()
|
||||
expect(payload.icon).toBe('_lumi.plug_lumi.plug_');
|
||||
|
||||
const svg_icon = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDo';
|
||||
definition.icon = svg_icon;
|
||||
payload = bridge.getDefinitionPayload(definition, {device: device});
|
||||
expect(payload).not.toBeUndefined()
|
||||
expect(payload['icon']).not.toBeUndefined()
|
||||
expect(payload.icon).toBe(svg_icon);
|
||||
|
||||
|
||||
device.modelID = '?._Z\\NC+Z02*LM';
|
||||
definition.model = '&&&&*+';
|
||||
definition.icon = '_${model}_${zigbeeModel}_';
|
||||
payload = bridge.getDefinitionPayload(definition, {device: device});
|
||||
expect(payload).not.toBeUndefined()
|
||||
expect(payload['icon']).not.toBeUndefined()
|
||||
expect(payload.icon).toBe('_------_-._Z-NC-Z02-LM_');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user