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>} */ /** @private @type {Object.<string, import('types/ApiSite').Device>} */
devices = {}; devices = {};
/** @private */ /** @private @type {Object.<string, string[]>} */
outputDeviceUniqueIdsByRoomId = {}; outputDeviceUniqueIdsByRoomId = {};
/** @private */ /** @private @type {Object.<number, string>} */
outputUniqueIdByBleOutputAddress = {}; outputUniqueIdByBleOutputAddress = {};
/** @private @type {Object.<number, string>} */
sceneUniqueIdByBleOutputAddress = {};
/** @private @type {import('./types/ApiSite').ApiSite} */ /** @private @type {import('./types/ApiSite').ApiSite} */
apiSite; apiSite;
@ -28,6 +30,13 @@ class DeviceRegistry {
/** @param outputDevice {import('types/DeviceRegistry').OutputDevice} */ /** @param outputDevice {import('types/DeviceRegistry').OutputDevice} */
addOutputDevice(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 = {
...this.outputDevices, ...this.outputDevices,
[outputDevice.uniqueId]: outputDevice, [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} */ /** @param scene {import('types/DeviceRegistry').OutputDevice} */
@ -85,6 +88,7 @@ class DeviceRegistry {
clearSceneDevices() { clearSceneDevices() {
this.sceneDevices = {}; this.sceneDevices = {};
this.sceneUniqueIdByBleOutputAddress = {};
} }
/** /**
@ -135,12 +139,29 @@ class DeviceRegistry {
return this.devices[deviceId]; 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 // eslint-disable-next-line class-methods-use-this

View file

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

View file

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

View file

@ -846,13 +846,18 @@ class PlejBLEHandler extends EventEmitter {
command = state ? COMMANDS.TURN_ON : COMMANDS.TURN_OFF; command = state ? COMMANDS.TURN_ON : COMMANDS.TURN_OFF;
this.emit(PlejBLEHandler.EVENTS.commandReceived, outputUniqueId, command, data); this.emit(PlejBLEHandler.EVENTS.commandReceived, outputUniqueId, command, data);
} else if (cmd === BLE_CMD_SCENE_TRIG) { } else if (cmd === BLE_CMD_SCENE_TRIG) {
const sceneId = state; const sceneBleAddress = state;
const sceneName = this.deviceRegistry.getSceneName(sceneId); 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; command = COMMANDS.TRIGGER_SCENE;
data = { sceneId }; data = { sceneId: scene.uniqueId };
this.emit(PlejBLEHandler.EVENTS.commandReceived, outputUniqueId, command, data); this.emit(PlejBLEHandler.EVENTS.commandReceived, outputUniqueId, command, data);
} else if (cmd === BLE_CMD_TIME_UPDATE) { } else if (cmd === BLE_CMD_TIME_UPDATE) {
const now = new Date(); const now = new Date();

View file

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