Fixes to scene handling and device unique id

This commit is contained in:
Victor Hagelbäck 2021-04-01 13:19:02 +02:00
parent 754fe00c9a
commit 464c17d920
5 changed files with 57 additions and 31 deletions

View file

@ -7,10 +7,12 @@ class DeviceRegistry {
/** @private @type {Object.<string, import('types/ApiSite').Device>} */
devices = {};
/** @private */
/** @private @type {Object.<string, string[]>} */
outputDeviceUniqueIdsByRoomId = {};
/** @private */
/** @private @type {Object.<number, string>} */
outputUniqueIdByBleOutputAddress = {};
/** @private @type {Object.<number, string>} */
sceneUniqueIdByBleOutputAddress = {};
/** @private @type {import('./types/ApiSite').ApiSite} */
apiSite;
@ -28,6 +30,13 @@ class DeviceRegistry {
/** @param outputDevice {import('types/DeviceRegistry').OutputDevice} */
addOutputDevice(outputDevice) {
if (outputDevice.hiddenFromIntegrations || outputDevice.hiddenFromRoomList) {
logger.verbose(`Device ${outputDevice.name} is hidden and will not be included.
Hidden from room list: ${outputDevice.hiddenFromRoomList}
Hidden from integrations: ${outputDevice.hiddenFromIntegrations}`);
return;
}
this.outputDevices = {
...this.outputDevices,
[outputDevice.uniqueId]: outputDevice,
@ -55,12 +64,6 @@ class DeviceRegistry {
)}`,
);
}
if (outputDevice.hiddenFromIntegrations || outputDevice.hiddenFromRoomList) {
logger.verbose(`Device is hidden and should possibly not be included.
Hidden from room list: ${outputDevice.hiddenFromRoomList}
Hidden from integrations: ${outputDevice.hiddenFromIntegrations}`);
}
}
/** @param scene {import('types/DeviceRegistry').OutputDevice} */
@ -85,6 +88,7 @@ class DeviceRegistry {
clearSceneDevices() {
this.sceneDevices = {};
this.sceneUniqueIdByBleOutputAddress = {};
}
/**
@ -135,12 +139,29 @@ class DeviceRegistry {
return this.devices[deviceId];
}
getScene(sceneId) {
return this.sceneDevices[sceneId];
/**
* @param {string} sceneUniqueId
*/
getScene(sceneUniqueId) {
return this.sceneDevices[sceneUniqueId];
}
getSceneName(sceneId) {
return (this.sceneDevices[sceneId] || {}).name;
/**
* @param {number} sceneBleAddress
*/
getSceneByBleAddress(sceneBleAddress) {
const sceneUniqueId = this.sceneUniqueIdByBleOutputAddress[sceneBleAddress];
if (!sceneUniqueId) {
return null;
}
return this.sceneDevices[sceneUniqueId];
}
/**
* @param {string} sceneUniqueId
*/
getSceneName(sceneUniqueId) {
return (this.sceneDevices[sceneUniqueId] || {}).name;
}
// eslint-disable-next-line class-methods-use-this

View file

@ -69,7 +69,6 @@ const getScenehDiscoveryPayload = (
) => ({
name: sceneDevice.name,
'~': getBaseTopic(sceneDevice),
state_topic: `~/${TOPICS.STATE}`,
command_topic: `~/${TOPICS.COMMAND}`,
optimistic: false,
qos: 1,

View file

@ -325,19 +325,17 @@ class PlejdApi {
`No outputSettings found for ${device.title} (${device.deviceId}), assuming output 0`,
);
}
const bleOutputAddress = this.siteDetails.outputAddress[device.deviceId][
outputSettings ? outputSettings.output : 0
];
const deviceOutput = outputSettings ? outputSettings.output : 0;
const bleOutputAddress = this.siteDetails.outputAddress[device.deviceId][deviceOutput];
if (device.traits === TRAITS.NO_LOAD) {
logger.warn(
`Device ${device.title} (${device.deviceId}) has no load configured and will be excluded`,
);
} else if (outputSettings) {
} else {
const uniqueOutputId = this.deviceRegistry.getUniqueOutputId(
device.deviceId,
outputSettings.output,
deviceOutput,
);
const plejdDevice = this.siteDetails.plejdDevices.find(
@ -357,7 +355,7 @@ class PlejdApi {
hiddenFromRoomList: device.hiddenFromRoomList,
hiddenFromIntegrations: device.hiddenFromIntegrations,
name: device.title,
output: outputSettings.output,
output: deviceOutput,
roomId: device.roomId,
state: undefined,
type,
@ -448,7 +446,7 @@ class PlejdApi {
output: undefined,
roomId: undefined,
state: false,
type: 'switch',
type: 'scene',
typeName: 'Scene',
version: undefined,
uniqueId: scene.sceneId,

View file

@ -846,13 +846,18 @@ class PlejBLEHandler extends EventEmitter {
command = state ? COMMANDS.TURN_ON : COMMANDS.TURN_OFF;
this.emit(PlejBLEHandler.EVENTS.commandReceived, outputUniqueId, command, data);
} else if (cmd === BLE_CMD_SCENE_TRIG) {
const sceneId = state;
const sceneName = this.deviceRegistry.getSceneName(sceneId);
const sceneBleAddress = state;
const scene = this.deviceRegistry.getSceneByBleAddress(sceneBleAddress);
logger.debug(`${sceneName} (${sceneId}) scene triggered (device id ${outputUniqueId}).`);
if (!scene) {
logger.warn(`Scene with BLE address ${sceneBleAddress} could not be found, can't process message`);
return;
}
logger.debug(`${scene.name} (${sceneBleAddress}) scene triggered (device id ${outputUniqueId}).`);
command = COMMANDS.TRIGGER_SCENE;
data = { sceneId };
data = { sceneId: scene.uniqueId };
this.emit(PlejBLEHandler.EVENTS.commandReceived, outputUniqueId, command, data);
} else if (cmd === BLE_CMD_TIME_UPDATE) {
const now = new Date();

View file

@ -7,7 +7,7 @@ class SceneManager {
deviceRegistry;
/** @private @type {import('./PlejdDeviceCommunication')} */
plejdDeviceCommunication;
/** @private @type {Object.<number,Scene>} */
/** @private @type {Object.<string,Scene>} */
scenes;
constructor(deviceRegistry, plejdDeviceCommunication) {
@ -23,15 +23,18 @@ class SceneManager {
this.scenes = {};
scenes.forEach((scene) => {
const idx = this.deviceRegistry.getApiSite().sceneIndex[scene.sceneId];
this.scenes[idx] = new Scene(this.deviceRegistry, idx, scene);
const sceneBleAddress = this.deviceRegistry.getApiSite().sceneIndex[scene.sceneId];
this.scenes[scene.sceneId] = new Scene(this.deviceRegistry, sceneBleAddress, scene);
});
}
executeScene(sceneId) {
const scene = this.scenes[sceneId];
/**
* @param {string} sceneUniqueId
*/
executeScene(sceneUniqueId) {
const scene = this.scenes[sceneUniqueId];
if (!scene) {
logger.info(`Scene with id ${sceneId} not found`);
logger.info(`Scene with id ${sceneUniqueId} not found`);
logger.verbose(`Scenes: ${JSON.stringify(this.scenes, null, 2)}`);
return;
}