Skip to content

Commit e75c04d

Browse files
authored
Merge pull request #344 from tlusk/bugfix/fix-custom-display-configuration
Fix the use of custom display configuration files
2 parents c91adb3 + 35c314e commit e75c04d

6 files changed

Lines changed: 43 additions & 5 deletions

File tree

src/actions/genericEntityAction.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ export class GenericEntityAction extends SingletonAction<Settings> {
329329

330330
private async onReconnect(ev: ReconnectEvent) {
331331
await this.homeAssistant.connect(ev.serverUrl, ev.accessToken)
332+
await this.entityConfigFactory.setDisplayConfigurationUrl(ev.customDisplayConfigurationUrl)
332333
await this.sendConnectionState()
333334
}
334335

src/models/events/sendToPluginEvents.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type ReconnectEvent = SendToPluginBaseEvent & {
1414
event: 'reconnect'
1515
serverUrl: string
1616
accessToken: string
17+
customDisplayConfigurationUrl: Nullable<string>
1718
}
1819

1920
export type GetEntityEvent = SendToPluginBaseEvent & {

src/render/entityConfigFactoryNg.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import fs from 'fs'
2+
13
import streamDeck, { type FeedbackPayload } from '@elgato/streamdeck'
24
import axios from 'axios'
35
import type { HassEntity } from 'home-assistant-js-websocket'
@@ -27,12 +29,20 @@ export class EntityConfigFactory {
2729
}
2830

2931
async setDisplayConfigurationUrl(url: Nullable<string>) {
30-
if (!url) return
32+
if (!url) {
33+
this.displayConfiguration = defaultDisplayConfiguration as DisplayConfig
34+
return
35+
}
3136

3237
streamDeck.logger.info(`Loading display configuration from ${url}`)
3338
try {
34-
const response = await axios.get<string>(url)
35-
this.displayConfiguration = yaml.load(response.data) as DisplayConfig
39+
let response: string
40+
if (url.startsWith('file://')) {
41+
response = fs.readFileSync(url.replace('file://', ''), 'utf8')
42+
} else {
43+
response = (await axios.get<string>(url)).data
44+
}
45+
this.displayConfiguration = yaml.load(response) as DisplayConfig
3646
} catch (error) {
3747
streamDeck.logger.error(`Failed to download display configuration from ${url}`, error)
3848
}
@@ -96,7 +106,12 @@ export class EntityConfigFactory {
96106

97107
const feedbackLayout = this.render(feedbackLayoutString, stateObject)
98108
const renderedFeedback = this.render(feedbackValueString, stateObject)
99-
const feedback = renderedFeedback ? (JSON.parse(renderedFeedback) as FeedbackPayload) : {}
109+
let feedback: FeedbackPayload = {}
110+
try {
111+
feedback = renderedFeedback ? (JSON.parse(renderedFeedback) as FeedbackPayload) : {}
112+
} catch (error) {
113+
streamDeck.logger.error('Failed to parse feedback template', error)
114+
}
100115

101116
const icon = this.render(iconString, stateObject)
102117
const color = this.render(colorString, stateObject)

src/view/components/PiComponent.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,8 @@ async function saveGlobalSettings() {
427427
await streamDeckClient.send('sendToPlugin', {
428428
event: 'reconnect',
429429
serverUrl: serverUrl.value,
430-
accessToken: accessToken.value
430+
accessToken: accessToken.value,
431+
customDisplayConfigurationUrl: displayConfigurationUrlOverride.value
431432
})
432433
}
433434

test/render/entityConfigFactoryNg.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,21 @@ it('test setting bad custom display configuration', async () => {
152152
const renderConfig = entityConfigFactory.buildRenderConfig(entity, settings)
153153
expect(renderConfig.icon).toBe('mdi:lightbulb')
154154
})
155+
156+
it('test setting custom display configuration with file', async () => {
157+
const entityConfigFactory = new EntityConfigFactory()
158+
const entity = buildTestEntity()
159+
const settings = buildTestSettings()
160+
161+
// Set the display configuration URL to a local file
162+
await entityConfigFactory.setDisplayConfigurationUrl(
163+
'file://resources/custom-display-configuration.yml'
164+
)
165+
const renderConfig1 = entityConfigFactory.buildRenderConfig(entity, settings)
166+
expect(renderConfig1.icon).toBe('mdi:ceiling-light')
167+
168+
// Set the display configuration URL back to the default
169+
await entityConfigFactory.setDisplayConfigurationUrl('')
170+
const renderConfig2 = entityConfigFactory.buildRenderConfig(entity, settings)
171+
expect(renderConfig2.icon).toBe('mdi:lightbulb')
172+
})
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
light:
2+
icon: mdi:ceiling-light

0 commit comments

Comments
 (0)