diff --git a/Override_buttons.md b/Override_buttons.md index 147662d..a34541a 100644 --- a/Override_buttons.md +++ b/Override_buttons.md @@ -1,17 +1,20 @@ ## Overriding key actions +You can override the default behavior of any button to call a different Home Assistant service. You can also customize the icon and style for media control buttons (PLAY, PAUSE, STOP, REWIND, RECORD, FAST_FOWARD). + Example config: + ```yaml type: custom:lg-remote-control av_receiver_family: anthemav entity: media_player.lg_webos_smart_tv -is_smart_tv: 'true' +is_smart_tv: "true" colors: buttons: red text: blue background: blue -projectorentity: '' -mac: '00:11:22:33:44:66' +projectorentity: "" +mac: "00:11:22:33:44:66" keys: LEFT: service: light.toggle @@ -23,7 +26,58 @@ keys: entity_id: light.tv ``` -available keys: +### Customizing media control buttons (icons and style) + +For media control buttons (PLAY, PAUSE, STOP, REWIND, RECORD, FAST_FOWARD), you can also customize the icon and button style. This is useful for repurposing these buttons for other functions like receiver volume control: + +```yaml +type: custom:lg-remote-control +entity: media_player.lg_webos_smart_tv +keys: + PLAY: + icon: mdi:volume-high + service: media_player.volume_up + data: + entity_id: media_player.receiver + PAUSE: + icon: mdi:volume-medium + service: media_player.volume_mute + data: + entity_id: media_player.receiver + STOP: + icon: mdi:volume-low + service: media_player.volume_down + data: + entity_id: media_player.receiver + REWIND: + icon: mdi:skip-previous + service: media_player.media_previous_track + data: + entity_id: media_player.receiver + RECORD: + icon: mdi:power + style: color: green; + service: media_player.toggle + data: + entity_id: media_player.receiver + FAST_FOWARD: + icon: mdi:skip-next + service: media_player.media_next_track + data: + entity_id: media_player.receiver +``` + +### Key configuration options + +| Property | Description | +| --------- | ------------------------------------------------------------------ | +| `service` | Home Assistant service to call (e.g., `media_player.volume_up`) | +| `data` | Service data to pass (e.g., `entity_id: media_player.receiver`) | +| `icon` | Custom icon for media control buttons (e.g., `mdi:volume-high`) | +| `style` | Custom CSS style for media control buttons (e.g., `color: green;`) | + +### Available keys: + - `"1"` - `"2"` - `"3"` diff --git a/src/editor.ts b/src/editor.ts index ab8a910..f21b062 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -42,11 +42,51 @@ const avreceivers = { const AvReceiverdevicemap = new Map(Object.entries(avreceivers)); +const OVERRIDEABLE_BUTTONS = [ + { key: "1", name: "1" }, + { key: "2", name: "2" }, + { key: "3", name: "3" }, + { key: "4", name: "4" }, + { key: "5", name: "5" }, + { key: "6", name: "6" }, + { key: "7", name: "7" }, + { key: "8", name: "8" }, + { key: "9", name: "9" }, + { key: "0", name: "0" }, + { key: "UP", name: "Up" }, + { key: "LEFT", name: "Left" }, + { key: "ENTER", name: "Enter/OK" }, + { key: "RIGHT", name: "Right" }, + { key: "BACK", name: "Back" }, + { key: "DOWN", name: "Down" }, + { key: "EXIT", name: "Exit" }, + { key: "RED", name: "Red" }, + { key: "GREEN", name: "Green" }, + { key: "YELLOW", name: "Yellow" }, + { key: "BLUE", name: "Blue" }, + { key: "HOME", name: "Home" }, + { key: "CHANNELUP", name: "Channel Up" }, + { key: "MUTE", name: "Mute" }, + { key: "INFO", name: "Info" }, + { key: "CHANNELDOWN", name: "Channel Down" }, + { key: "PLAY", name: "Play" }, + { key: "PAUSE", name: "Pause" }, + { key: "STOP", name: "Stop" }, + { key: "REWIND", name: "Rewind" }, + { key: "RECORD", name: "Record" }, + { key: "FAST_FOWARD", name: "Fast Forward" }, + { key: "POWER", name: "Power" }, + { key: "VOLUME_UP", name: "Volume Up" }, + { key: "VOLUME_DOWN", name: "Volume Down" }, +]; + @customElement(EDITOR_CARD_TAG_NAME) class LgRemoteControlEditor extends LitElement { private _config: any; private hass: HomeAssistantFixed; + private _overridesExpanded: boolean = false; + private _expandedOverride: string | null = null; static get properties() { return { @@ -196,7 +236,7 @@ class LgRemoteControlEditor extends LitElement {

`; } - + selectMac(macValue) { macValue = macValue ?? '00:11:22:33:44:55'; let heading = 'MAC Address:'; @@ -223,18 +263,18 @@ class LgRemoteControlEditor extends LitElement { - - + + - + - + @@ -291,7 +331,7 @@ class LgRemoteControlEditor extends LitElement { return html`
AV-Receiver config option:
- this._onButtonSelect(e)}> + + ${OVERRIDEABLE_BUTTONS.map((btn) => html` + + `)} + +
+ ${configuredKeys.length > 0 ? html` +
+ ${configuredKeys.map((key) => this._renderOverrideItem(key))} +
+ ` : ''} + + ` : ''} + `; + } + + _renderOverrideItem(key: string) { + const isExpanded = this._expandedOverride === key; + const keyConfig = this._config?.keys?.[key] || {}; + const icon = keyConfig.icon || ''; + const style = keyConfig.style || ''; + const service = keyConfig.service || ''; + const entityId = keyConfig.data?.entity_id || ''; + return html` +
+
this._toggleOverrideConfig(key)}> + ${this._getButtonName(key)} +
+ { e.stopPropagation(); this._deleteOverride(key); }}> + +
+
+ ${isExpanded ? html` +
+ + this._updateOverrideField(key, 'icon', e.target.value)} /> + + this._updateOverrideField(key, 'style', e.target.value)} /> + + this._updateOverrideField(key, 'service', e.target.value)} /> + + ${this._getServiceOptions().map((s) => html``)} + + + this._updateOverrideField(key, 'entity_id', e.target.value)} /> + + ${this._getEntityOptions().map((e) => html``)} + +
+ ` : ''} +
+ `; + } render() { @@ -362,6 +587,7 @@ class LgRemoteControlEditor extends LitElement { ${this.getDeviceAVReceiverDropdown(this._config.av_receiver_family)} ${this.getMediaPlayerEntityDropdown(this._config.av_receiver_family)} ${this.setDimensions(this._config.dimensions??{})} + ${this._renderOverridesSection()}

Other functionalities must be configured manually in code editor

references to https://github.com/madmicio/LG-WebOS-Remote-Control

@@ -379,29 +605,105 @@ class LgRemoteControlEditor extends LitElement { static get styles() { return css` - + .color-selector { display: grid; grid-template-columns: auto 8ch 3ch; width: 40ch; } - + .color-item { padding: .6em; font-size: 1em; } - + .heading { font-weight: bold; } - + .select-item { background-color: var(--label-badge-text-color); width: 40ch; - padding: .6em; + padding: .6em; font-size: 1em; } - + + .overrides-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5em; + background-color: var(--primary-color); + color: white; + border-radius: 4px; + cursor: pointer; + margin-top: 1em; + } + .overrides-header .heading { + color: white; + } + .overrides-content { + padding: 0.5em; + background-color: var(--card-background-color); + border: 1px solid var(--divider-color); + border-top: none; + border-radius: 0 0 4px 4px; + } + .add-override-row { + margin-bottom: 0.5em; + } + .add-override-row select { + width: 100%; + box-sizing: border-box; + } + .configured-overrides { + margin-top: 0.5em; + } + .override-item { + margin-bottom: 0.5em; + border: 1px solid var(--divider-color); + border-radius: 4px; + overflow: hidden; + } + .override-item-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5em; + background-color: var(--secondary-background-color); + cursor: pointer; + } + .override-item-actions { + display: flex; + align-items: center; + gap: 0.5em; + } + .override-item-actions ha-icon { + cursor: pointer; + } + .override-item-actions ha-icon[icon="mdi:delete"] { + color: var(--error-color); + } + .override-item-config { + padding: 0.5em; + background-color: var(--card-background-color); + } + .override-item-config label { + display: block; + margin-top: 0.4em; + margin-bottom: 0.2em; + font-size: 0.9em; + } + .override-item-config input { + width: calc(100% - 0.8em); + padding: 0.4em; + font-size: 0.9em; + border: 1px solid var(--divider-color); + border-radius: 4px; + background-color: var(--input-background-color, var(--card-background-color)); + color: var(--primary-text-color); + } + `; } diff --git a/src/lg-remote-control.ts b/src/lg-remote-control.ts index 1397072..07fc72c 100644 --- a/src/lg-remote-control.ts +++ b/src/lg-remote-control.ts @@ -138,9 +138,9 @@ class LgRemoteControl extends LitElement {
${['off', 'unavailable'].includes(stateObj.state) ? html` - + ` : html` - + `}
@@ -198,17 +198,17 @@ class LgRemoteControl extends LitElement { ${this._show_keypad ? html`
- - - - - - - - - + + + + + + + + + - +
@@ -219,14 +219,14 @@ class LgRemoteControl extends LitElement { - + - -
this._button("ENTER")}>${this._show_vol_text === true ? this.volume_value : 'OK'}
- - - - + +
this._button("ENTER")}>${this._getIcon("ENTER", "") ? html`` : (this._show_vol_text === true ? this.volume_value : 'OK')}
+ + + + `} @@ -255,10 +255,10 @@ class LgRemoteControl extends LitElement { ${colorButtons ? html`
- - - - + + + +
` : html` `} @@ -266,8 +266,8 @@ class LgRemoteControl extends LitElement {
- @@ -277,23 +277,23 @@ class LgRemoteControl extends LitElement { - - - - + + + + - - + +
- - - - - - + + + + + +
@@ -536,6 +536,21 @@ class LgRemoteControl extends LitElement { } + + _getIcon(key: string, defaultIcon: string): string { + if (this.config.keys && key in this.config.keys && this.config.keys[key]["icon"]) { + return this.config.keys[key]["icon"]; + } + return defaultIcon; + } + + _getButtonStyle(key: string, defaultStyle: string): string { + if (this.config.keys && key in this.config.keys && this.config.keys[key]["style"]) { + return this.config.keys[key]["style"]; + } + return defaultStyle; + } + static getIcon(iconName) { return Object.keys(LgRemoteControl.iconMapping).includes(iconName) ? LgRemoteControl.iconMapping[iconName]