Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/actions/genericEntityAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ export class GenericEntityAction extends SingletonAction<Settings> {

private async onReconnect(ev: ReconnectEvent) {
await this.homeAssistant.connect(ev.serverUrl, ev.accessToken)
await this.entityConfigFactory.setDisplayConfigurationUrl(ev.customDisplayConfigurationUrl)
await this.sendConnectionState()
}

Expand Down
1 change: 1 addition & 0 deletions src/models/events/sendToPluginEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type ReconnectEvent = SendToPluginBaseEvent & {
event: 'reconnect'
serverUrl: string
accessToken: string
customDisplayConfigurationUrl: Nullable<string>
}

export type GetEntityEvent = SendToPluginBaseEvent & {
Expand Down
23 changes: 19 additions & 4 deletions src/render/entityConfigFactoryNg.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import fs from 'fs'

import streamDeck, { type FeedbackPayload } from '@elgato/streamdeck'
import axios from 'axios'
import type { HassEntity } from 'home-assistant-js-websocket'
Expand Down Expand Up @@ -27,12 +29,20 @@ export class EntityConfigFactory {
}

async setDisplayConfigurationUrl(url: Nullable<string>) {
if (!url) return
if (!url) {
this.displayConfiguration = defaultDisplayConfiguration as DisplayConfig
return
}

streamDeck.logger.info(`Loading display configuration from ${url}`)
try {
const response = await axios.get<string>(url)
this.displayConfiguration = yaml.load(response.data) as DisplayConfig
let response: string
if (url.startsWith('file://')) {
response = fs.readFileSync(url.replace('file://', ''), 'utf8')
} else {
response = (await axios.get<string>(url)).data
}
this.displayConfiguration = yaml.load(response) as DisplayConfig
} catch (error) {
streamDeck.logger.error(`Failed to download display configuration from ${url}`, error)
}
Expand Down Expand Up @@ -96,7 +106,12 @@ export class EntityConfigFactory {

const feedbackLayout = this.render(feedbackLayoutString, stateObject)
const renderedFeedback = this.render(feedbackValueString, stateObject)
const feedback = renderedFeedback ? (JSON.parse(renderedFeedback) as FeedbackPayload) : {}
let feedback: FeedbackPayload = {}
try {
feedback = renderedFeedback ? (JSON.parse(renderedFeedback) as FeedbackPayload) : {}
} catch (error) {
streamDeck.logger.error('Failed to parse feedback template', error)
}

const icon = this.render(iconString, stateObject)
const color = this.render(colorString, stateObject)
Expand Down
3 changes: 2 additions & 1 deletion src/view/components/PiComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,8 @@ async function saveGlobalSettings() {
await streamDeckClient.send('sendToPlugin', {
event: 'reconnect',
serverUrl: serverUrl.value,
accessToken: accessToken.value
accessToken: accessToken.value,
customDisplayConfigurationUrl: displayConfigurationUrlOverride.value
})
}

Expand Down
18 changes: 18 additions & 0 deletions test/render/entityConfigFactoryNg.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,21 @@ it('test setting bad custom display configuration', async () => {
const renderConfig = entityConfigFactory.buildRenderConfig(entity, settings)
expect(renderConfig.icon).toBe('mdi:lightbulb')
})

it('test setting custom display configuration with file', async () => {
const entityConfigFactory = new EntityConfigFactory()
const entity = buildTestEntity()
const settings = buildTestSettings()

// Set the display configuration URL to a local file
await entityConfigFactory.setDisplayConfigurationUrl(
'file://resources/custom-display-configuration.yml'
)
const renderConfig1 = entityConfigFactory.buildRenderConfig(entity, settings)
expect(renderConfig1.icon).toBe('mdi:ceiling-light')

// Set the display configuration URL back to the default
await entityConfigFactory.setDisplayConfigurationUrl('')
const renderConfig2 = entityConfigFactory.buildRenderConfig(entity, settings)
expect(renderConfig2.icon).toBe('mdi:lightbulb')
})
2 changes: 2 additions & 0 deletions test/resources/custom-display-configuration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
light:
icon: mdi:ceiling-light