diff --git a/src/components/PluginComponent.vue b/src/components/PluginComponent.vue index de502f6..5a4621d 100644 --- a/src/components/PluginComponent.vue +++ b/src/components/PluginComponent.vue @@ -19,6 +19,7 @@ const touchScreenImageFactory = new EntityButtonImageFactory({width: 200, height const $SD = ref(null) const $HA = ref(null) const $reconnectTimeout = ref({}) +const globalSettings = ref({}) const actionSettings = ref([]) const buttonLongpressTimeouts = ref(new Map()) //context, timeout @@ -30,36 +31,13 @@ onMounted(() => { window.connectElgatoStreamDeckSocket = (inPort, inPluginUUID, inRegisterEvent, inInfo) => { $SD.value = new StreamDeck(inPort, inPluginUUID, inRegisterEvent, inInfo, "{}"); - $SD.value.on("globalsettings", (globalSettings) => { + $SD.value.on("globalsettings", (inGlobalSettings) => { console.log("Got global settings.") - globalSettings.value = globalSettings; - connectHomeAssistant(globalSettings); + globalSettings.value = inGlobalSettings; + connectHomeAssistant(); } ) - const onHAConnected = () => { - $HA.value.getStates(entitiyStatesChanged) - $HA.value.subscribeEvents(entityStateChanged) - } - - const onHAError = (msg) => { - console.log(`Home Assistant connection error: ${msg}`) - showAlert() - window.clearTimeout($reconnectTimeout) - $reconnectTimeout.value = window.setTimeout(connectHomeAssistant, 5000) - } - - const onHAClosed = (msg) => { - console.log(`Home Assistant connection closed, trying to reopen connection: ${msg}`) - showAlert() - window.clearTimeout($reconnectTimeout) - $reconnectTimeout.value = window.setTimeout(connectHomeAssistant, 5000) - } - - const showAlert = () => { - Object.keys(actionSettings.value).forEach(key => $SD.value.showAlert(key)) - } - $SD.value.on("connected", () => { $SD.value.requestGlobalSettings(); }) @@ -78,7 +56,7 @@ onMounted(() => { rotationPercent[context] = 0; actionSettings.value[context] = Settings.parse(message.payload.settings) if ($HA.value) { - $HA.value.getStates(entitiyStatesChanged) + $HA.value.getStates(entityStatesChanged) } }) @@ -141,163 +119,186 @@ onMounted(() => { rotationAmount[context] = 0; actionSettings.value[context] = Settings.parse(message.payload.settings) if ($HA.value) { - $HA.value.getStates(entitiyStatesChanged) + $HA.value.getStates(entityStatesChanged) } }) + } +}) - const buttonDown = (context) => { - const timeout = setTimeout(buttonLongPress, 300, context); - buttonLongpressTimeouts.value.set(context, timeout) - } - - const buttonUp = (context) => { - // If "long press timeout" is still present, we perform a normal press - const lpTimeout = buttonLongpressTimeouts.value.get(context); - if (lpTimeout) { - clearTimeout(lpTimeout); - buttonLongpressTimeouts.value.delete(context) - buttonShortPress(context); - } +function connectHomeAssistant() { + console.log("Connecting to Home Assistant") + if (globalSettings.value.serverUrl && globalSettings.value.accessToken) { + if ($HA.value) { + $HA.value.close(); } + console.log("Connecting to Home Assistant " + globalSettings.value.serverUrl) + $HA.value = new Homeassistant(globalSettings.value.serverUrl, globalSettings.value.accessToken, onHAConnected, onHAError, onHAClosed) + } +} + +const onHAConnected = () => { + $HA.value.getStates(entityStatesChanged) + $HA.value.subscribeEvents(entityStateChanged) +} + +function onHAError(msg) { + showAlert() + console.log(`Home Assistant connection error: ${msg}`) + window.clearTimeout($reconnectTimeout) + $reconnectTimeout.value = window.setTimeout(connectHomeAssistant, 5000) +} + +function onHAClosed(msg) { + showAlert() + console.log(`Home Assistant connection closed, trying to reopen connection: ${msg}`) + window.clearTimeout($reconnectTimeout) + $reconnectTimeout.value = window.setTimeout(connectHomeAssistant, 5000) +} + +function showAlert() { + Object.keys(actionSettings.value).forEach(key => $SD.value.showAlert(key)) +} + +function entityStatesChanged(event) { + event.forEach(updateState) +} + +function entityStateChanged(event) { + if (event) { + let newState = event.data.new_state; + updateState(newState) + } +} - const buttonShortPress = (context) => { - let settings = actionSettings.value[context]; - callService(context, settings.button.serviceShortPress); - } +function updateState(stateMessage) { + if (!stateMessage.entity_id) { + console.log(`Missing entity_id in updated state: ${stateMessage}`) + return; + } - const buttonLongPress = (context) => { - buttonLongpressTimeouts.value.delete(context); - let settings = actionSettings.value[context]; - if (settings.button.serviceLongPress.serviceId) { - callService(context, settings.button.serviceLongPress); - } else { - callService(context, settings.button.serviceShortPress); - } - } + let domain = stateMessage.entity_id.split('.')[0] + let changedContexts = Object.keys(actionSettings.value).filter(key => actionSettings.value[key].display.entityId === stateMessage.entity_id) - const callService = (context, serviceToCall, serviceDataAttributes = {}) => { - if ($HA.value) { - if (serviceToCall["serviceId"]) { - try { - const serviceIdParts = serviceToCall.serviceId.split('.'); - - let serviceData = null; - if (serviceToCall.serviceData) { - let renderedServiceData = nunjucks.renderString(serviceToCall.serviceData, serviceDataAttributes) - serviceData = JSON.parse(renderedServiceData); - } - - $HA.value.callService(serviceIdParts[1], serviceIdParts[0], serviceToCall.entityId, serviceData) - } catch (e) { - console.error(e) - $SD.value.showAlert(context); - } - } - } - } + changedContexts.forEach(context => { + try { + if (stateMessage.last_updated != null) stateMessage.attributes["last_updated"] = new Date(stateMessage.last_updated).toLocaleTimeString(); + if (stateMessage.last_changed != null) stateMessage.attributes["last_changed"] = new Date(stateMessage.last_changed).toLocaleTimeString(); - const connectHomeAssistant = (globalSettings) => { - console.log("Connecting to Home Assistant") - if (globalSettings.serverUrl && globalSettings.accessToken) { - if ($HA.value) { - $HA.value.close(); - } - console.log("Connecting to Home Assistant " + globalSettings.serverUrl) - $HA.value = new Homeassistant(globalSettings.serverUrl, globalSettings.accessToken, onHAConnected, onHAError, onHAClosed) - } + updateContextState(context, domain, stateMessage); + } catch (e) { + console.error(e) + $SD.value.setImage(context, null); + $SD.value.showAlert(context); } + }) +} - const entitiyStatesChanged = (event) => { - event.forEach(updateState) - } +function updateContextState(currentContext, domain, stateObject) { + let contextSettings = actionSettings.value[currentContext] + let labelTemplates = null; - const entityStateChanged = (event) => { - if (event) { - let newState = event.data.new_state; - updateState(newState) - } + if (contextSettings.display.useCustomButtonLabels && contextSettings.display.buttonLabels) { + labelTemplates = contextSettings.display.buttonLabels.split("\n"); + } + let entityConfig = entityConfigFactory.determineConfig(domain, stateObject, labelTemplates) + + entityConfig.isAction = contextSettings.button.serviceShortPress.serviceId && (contextSettings.display.enableServiceIndicator === undefined || contextSettings.display.enableServiceIndicator) // undefined = on by default + entityConfig.isMultiAction = contextSettings.button.serviceLongPress.serviceId && (contextSettings.display.enableServiceIndicator === undefined || contextSettings.display.enableServiceIndicator) // undefined = on by default + entityConfig.hideIcon = contextSettings.display.hideIcon + + if (contextSettings.display.useStateImagesForOnOffStates) { + switch (stateObject.state) { + case "on": + case "playing": + case "open": + case "opening": + case "home": + case "locked": + case "active": + console.log("Setting state of " + currentContext + " to 1") + $SD.value.setState(currentContext, 1); + break; + default: + console.log("Setting state of " + currentContext + " to 0") + $SD.value.setState(currentContext, 0); } - - const updateState = (stateMessage) => { - if (!stateMessage.entity_id) { - console.log(`Missing entity_id in updated state: ${stateMessage}`) - return; - } - - let domain = stateMessage.entity_id.split('.')[0] - let changedContexts = Object.keys(actionSettings.value).filter(key => actionSettings.value[key].display.entityId === stateMessage.entity_id) - - changedContexts.forEach(context => { - try { - if (stateMessage.last_updated != null) stateMessage.attributes["last_updated"] = new Date(stateMessage.last_updated).toLocaleTimeString(); - if (stateMessage.last_changed != null) stateMessage.attributes["last_changed"] = new Date(stateMessage.last_changed).toLocaleTimeString(); - - updateContextState(context, domain, stateMessage); - } catch (e) { - console.error(e) - $SD.value.setImage(context, null); - $SD.value.showAlert(context); - } - }) + } else { + if (contextSettings.controllerType === 'Encoder') { + const buttonImage = touchScreenImageFactory.createButton(entityConfig); + setButtonSVG(buttonImage, currentContext) + } else { + const buttonImage = buttonImageFactory.createButton(entityConfig); + setButtonSVG(buttonImage, currentContext) } + } - const updateContextState = (currentContext, domain, stateObject) => { - let contextSettings = actionSettings.value[currentContext] - let labelTemplates = null; + if (contextSettings.display.useCustomTitle) { + let state = stateObject.state; + let stateAttributes = stateObject.attributes; - if (contextSettings.display.useCustomButtonLabels && contextSettings.display.buttonLabels) { - labelTemplates = contextSettings.display.buttonLabels.split("\n"); - } - let entityConfig = entityConfigFactory.determineConfig(domain, stateObject, labelTemplates) - - entityConfig.isAction = contextSettings.button.serviceShortPress.serviceId && (contextSettings.display.enableServiceIndicator === undefined || contextSettings.display.enableServiceIndicator) // undefined = on by default - entityConfig.isMultiAction = contextSettings.button.serviceLongPress.serviceId && (contextSettings.display.enableServiceIndicator === undefined || contextSettings.display.enableServiceIndicator) // undefined = on by default - entityConfig.hideIcon = contextSettings.display.hideIcon - - if (contextSettings.display.useStateImagesForOnOffStates) { - switch (stateObject.state) { - case "on": - case "playing": - case "open": - case "opening": - case "home": - case "locked": - case "active": - console.log("Setting state of " + currentContext + " to 1") - $SD.value.setState(currentContext, 1); - break; - default: - console.log("Setting state of " + currentContext + " to 0") - $SD.value.setState(currentContext, 0); - } - } else { - if (contextSettings.controllerType === 'Encoder') { - const buttonImage = touchScreenImageFactory.createButton(entityConfig); - setButtonSVG(buttonImage, currentContext) - } else { - const buttonImage = buttonImageFactory.createButton(entityConfig); - setButtonSVG(buttonImage, currentContext) + const customTitle = nunjucks.renderString(contextSettings.display.buttonTitle, {...{state}, ...stateAttributes}) + $SD.value.setTitle(currentContext, customTitle); + } +} + +function setButtonSVG(svg, changedContext) { + const image = "data:image/svg+xml;charset=utf8," + svg; + if (actionSettings.value[changedContext].controllerType === 'Encoder') { + $SD.value.setFeedback(changedContext, {"full-canvas": image, "canvas": null, "title": ""}) + } else { + $SD.value.setImage(changedContext, image) + } +} + +function buttonDown(context) { + const timeout = setTimeout(buttonLongPress, 300, context); + buttonLongpressTimeouts.value.set(context, timeout) +} + +function buttonUp(context) { + // If "long press timeout" is still present, we perform a normal press + const lpTimeout = buttonLongpressTimeouts.value.get(context); + if (lpTimeout) { + clearTimeout(lpTimeout); + buttonLongpressTimeouts.value.delete(context) + buttonShortPress(context); + } +} + +function buttonShortPress(context) { + let settings = actionSettings.value[context]; + callService(context, settings.button.serviceShortPress); +} + +function buttonLongPress(context) { + buttonLongpressTimeouts.value.delete(context); + let settings = actionSettings.value[context]; + if (settings.button.serviceLongPress.serviceId) { + callService(context, settings.button.serviceLongPress); + } else { + callService(context, settings.button.serviceShortPress); + } +} + +function callService(context, serviceToCall, serviceDataAttributes = {}) { + if ($HA.value) { + if (serviceToCall["serviceId"]) { + try { + const serviceIdParts = serviceToCall.serviceId.split('.'); + + let serviceData = null; + if (serviceToCall.serviceData) { + let renderedServiceData = nunjucks.renderString(serviceToCall.serviceData, serviceDataAttributes) + serviceData = JSON.parse(renderedServiceData); } - } - if (contextSettings.display.useCustomTitle) { - let state = stateObject.state; - let stateAttributes = stateObject.attributes; - - const customTitle = nunjucks.renderString(contextSettings.display.buttonTitle, {...{state}, ...stateAttributes}) - $SD.value.setTitle(currentContext, customTitle); + $HA.value.callService(serviceIdParts[1], serviceIdParts[0], serviceToCall.entityId, serviceData) + } catch (e) { + console.error(e) + $SD.value.showAlert(context); } } } - - const setButtonSVG = (svg, changedContext) => { - const image = "data:image/svg+xml;charset=utf8," + svg; - if (actionSettings.value[changedContext].controllerType === 'Encoder') { - $SD.value.setFeedback(changedContext, {"full-canvas": image, "canvas": null, "title": ""}) - } else { - $SD.value.setImage(changedContext, image) - } - } -}) +} diff --git a/src/components/ServiceCallConfiguration.vue b/src/components/ServiceCallConfiguration.vue index 9fde751..9200910 100644 --- a/src/components/ServiceCallConfiguration.vue +++ b/src/components/ServiceCallConfiguration.vue @@ -34,7 +34,7 @@
- +