My setup :
I have a TCL TV, connected to a Google TV, with a Lytmi Neo 3 for backlight.
The objective is to connect all that stuff in only one app instead of having 2 remotes (TV and GoogleTV) and an app (Lytmi Neo 3).
Lytmi Neo 3 :
Is a TV Backlight kit that use a HDMI sync box to adjust the light based on the image of the screen (recommanded stuff by the way!). Since it’s chinese and connected to Tuya, I was able to connect it to Openhab with Tuya-MQTT (https://github.com/TheAgentK/tuya-mqtt).
This remote is based on the current interface of the GoogleTV app and give me the possibility to turn on the TV and control ALL the Lytmi setup, even with the generic scenes in another TAB.
The Widget :
uid: UniversalRemote2
tags: []
props:
parameters:
- context: item
description: The item to send the command to
label: Item
name: item
required: false
type: TEXT
groupName: items
- context: item
description: TV Power
label: TV Power
name: tvpower
required: false
type: TEXT
groupName: items
- context: item
description: Backlight Input
label: Backlight Input
name: backlightInput
required: false
type: TEXT
groupName: items
- context: item
description: Backlight brightness item
label: Backlight Brithtness
name: backlightBrightness
required: false
type: TEXT
groupName: items
- context: item
description: Backlight diffusion item
label: Backlight Diffusion
name: backlightDiffusion
required: false
type: TEXT
groupName: items
- context: item
description: Backlight mode item
label: Backlight Mode
name: backlightMode
required: false
type: TEXT
groupName: items
- context: item
description: Backlight switch item
label: Light Switch
name: lightswitch
required: false
type: TEXT
groupName: items
- description: Command to power on
label: Power ON
name: poweron
required: false
type: TEXT
groupName: commands
- description: Command to power off
label: Power OFF
name: poweroff
required: false
type: TEXT
groupName: commands
- description: Command to power on light
label: Power On light
name: lighton
required: false
type: TEXT
groupName: commands
- description: Command to power off light
label: Power Off light
name: lightoff
required: false
type: TEXT
groupName: commands
- description: Command to increase volume
label: Volume Up
name: volumeup
required: false
type: TEXT
groupName: commands
- description: Command to decrease volume
label: Volume Down
name: volumedown
required: false
type: TEXT
groupName: commands
- description: Command to mute volume
label: Volume Mute
name: volumemute
required: false
type: TEXT
groupName: commands
- description: Command to send Return
label: Return
name: return
required: false
type: TEXT
groupName: commands
- description: Command to send Home/Menu
label: Home/Menu
name: home
required: false
type: TEXT
groupName: commands
- description: Command to send TV
label: TV
name: tv
required: false
type: TEXT
groupName: commands
- description: Command to send Computer
label: Computer
name: computer
required: false
type: TEXT
groupName: commands
- description: Command to send OK/Enter
label: OK/Enter
name: ok
required: false
type: TEXT
groupName: commands
- description: Command to send Up
label: Arrow Up
name: up
required: false
type: TEXT
groupName: commands
- description: Command to send Left
label: Arrow Left
name: left
required: false
type: TEXT
groupName: commands
- description: Command to send Right
label: Arrow Right
name: right
required: false
type: TEXT
groupName: commands
- description: Command to send Down
label: Arrow Down
name: down
required: false
type: TEXT
groupName: commands
- description: Command to Video mode
label: Video Mode
name: modeVideo
required: false
type: TEXT
groupName: commands
- description: Command to Recreation mode
label: Recreation Mode
name: modeRecreation
required: false
type: TEXT
groupName: commands
- description: Command to Game mode
label: Game Mode
name: modeGame
required: false
type: TEXT
groupName: commands
parameterGroups:
- name: items
label: Items to use
- name: commands
label: Commands to send
timestamp: Dec 29, 2023, 9:40:31 AM
component: f7-swiper
config:
pagination: true
params:
slides-per-view: 1
style:
--box-shadow: 2px 3px rgb(150,150,150)
--f7-card-margin-horizontal: 0px
background-color: transparent
height: 780px
width: 410px
slots:
default:
- component: f7-swiper-slide
slots:
default:
- component: oh-button
config:
action: toggle
actionCommand: =props.lighton
actionCommandAlt: =props.lightoff
actionItem: =props.lightswitch
color: white
iconF7: "=((items[props.lightswitch].state == props.lighton) ? 'lightbulb_fill' : 'lightbulb')"
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px
display: flex
height: 60px
left: 20px
position: absolute
top: 10px
width: 60px
- component: oh-button
config:
action: toggle
actionCommand: =props.poweron
actionCommandAlt: =props.poweroff
actionItem: =props.tvpower
color: white
iconF7: "=((items[props.tvpower].state == props.poweron) ? 'tv_circle_fill' : 'tv_circle')"
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px
display: flex
height: 60px
left: 330px
position: absolute
top: 10px
width: 60px
- component: f7-badge
config:
style:
background-color: rgb(31,31,31)
border-radius: 50%
height: 330px
left: 40px
position: absolute
top: 40px
width: 330px
z-index: 0
- component: oh-button
config:
action: command
actionCommand: =props.ok
actionItem: =props.item
color: white
style:
background-color: rgb(70,70,70)
border: gray solid 1px
border-radius: 50%
display: flex
font-size: 25px
height: 140px
left: 135px
position: absolute
top: 135px
width: 140px
z-index: 1
- component: oh-button
config:
action: command
actionCommand: =props.up
actionItem: =props.item
color: white
iconF7: chevron_up
iconSize: 30
style:
border-radius: 50% 50% 0px 0px
display: flex
height: 95px
left: 105px
position: absolute
top: 40px
width: 200px
z-index: 1
- component: oh-button
config:
action: command
actionCommand: =props.left
actionItem: =props.item
color: white
iconF7: chevron_left
iconSize: 30
style:
border-radius: 50% 0px 0px 50%
display: flex
height: 200px
left: 40px
position: absolute
top: 105px
width: 95px
z-index: 1
- component: oh-button
config:
action: command
actionCommand: =props.right
actionItem: =props.item
color: white
iconF7: chevron_right
iconSize: 30
style:
border-radius: 0px 50% 50% 0px
display: flex
height: 200px
left: 275px
position: absolute
top: 105px
width: 95px
z-index: 1
- component: oh-button
config:
action: command
actionCommand: =props.down
actionItem: =props.item
color: white
iconF7: chevron_down
iconSize: 30
style:
border-radius: 0px 0px 50% 50%
display: flex
height: 95px
left: 105px
position: absolute
top: 275px
width: 200px
z-index: 1
- component: oh-button
config:
action: command
actionCommand: =props.return
actionItem: =props.item
color: white
iconF7: arrow_uturn_left
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px
color: white
display: flex
height: 80px
left: 20px
position: absolute
top: 395px
width: 80px
- component: oh-button
config:
action: command
actionCommand: =props.home
actionItem: =props.item
color: white
iconF7: house
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px
color: white
display: flex
height: 80px
left: 116.67px
position: absolute
top: 395px
width: 80px
- component: oh-button
config:
action: command
actionCommand: =props.computer
actionItem: =props.backlightInput
color: white
iconF7: device_laptop
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px
color: white
display: flex
height: 80px
left: 213.34px
position: absolute
top: 395px
width: 80px
- component: oh-button
config:
action: command
actionCommand: =props.tv
actionItem: =props.backlightInput
color: white
iconF7: tv
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px
color: white
display: flex
height: 80px
left: 310px
position: absolute
top: 395px
width: 80px
- component: oh-button
config:
action: command
actionCommand: =props.volumemute
actionItem: =props.item
color: white
iconF7: speaker_slash
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px
display: flex
height: 80px
left: 20px
position: absolute
top: 495px
width: 80px
- component: oh-button
config:
action: command
actionCommand: =props.volumedown
actionItem: =props.item
color: white
iconF7: speaker_1
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px 0px 0px 50px
display: flex
height: 80px
left: 116.67px
position: absolute
top: 495px
width: 133.665px
z-index: 1
- component: oh-button
config:
action: command
actionCommand: =props.volumeup
actionItem: =props.item
color: white
iconF7: speaker_3
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 0px 50px 50px 0px
display: flex
height: 80px
left: 256.335px
position: absolute
top: 495px
width: 133.665px
z-index: 1
- component: f7-badge
config:
style:
background-color: rgb(31,31,31)
border-radius: 50px 0px 0px 50px
display: flex
height: 80px
left: 20px
position: absolute
top: 595px
width: 182px
z-index: 1
slots:
default:
- component: Label
config:
style:
font-size: 15px
font-weight: lighter
position: absolute
top: 12px
text: Brightness
- component: oh-slider
config:
color: white
item: =props.backlightBrightness
max: 1000
min: 10
releaseOnly: true
scale: false
step: 1
style:
top: 15px
width: 130px
title: Brightness
- component: f7-badge
config:
style:
background-color: rgb(31,31,31)
border-radius: 0px 50px 50px 0px
display: flex
height: 80px
left: 208px
position: absolute
top: 595px
width: 182px
z-index: 1
slots:
default:
- component: Label
config:
style:
font-size: 15px
font-weight: lighter
position: absolute
top: 12px
text: Diffusion
- component: oh-slider
config:
color: white
item: =props.backlightDiffusion
max: 1000
min: 10
releaseOnly: true
scale: false
step: 1
style:
top: 15px
width: 130px
title: Brightness
- component: oh-button
config:
action: command
actionCommand: =props.modeVideo
actionItem: =props.backlightMode
color: white
iconF7: "=((items[props.backlightMode].state == props.modeVideo) ? 'videocam_fill' : 'videocam')"
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px
color: white
display: flex
height: 80px
left: 20px
position: absolute
top: 690px
width: 80px
- component: oh-button
config:
action: command
actionCommand: =props.modeRecreation
actionItem: =props.backlightMode
color: white
iconF7: "=((items[props.backlightMode].state == props.modeRecreation) ? 'play_rectangle_fill' : 'play_rectangle')"
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px
color: white
display: flex
height: 80px
left: 165px
position: absolute
top: 690px
width: 80px
- component: oh-button
config:
action: command
actionCommand: =props.modeGame
actionItem: =props.backlightMode
color: white
iconF7: "=((items[props.backlightMode].state == props.modeGame) ? 'gamecontroller_fill' : 'gamecontroller')"
iconSize: 20
style:
background-color: rgb(31,31,31)
border-radius: 50px
color: white
display: flex
height: 80px
left: 310px
position: absolute
top: 690px
width: 80px
- component: f7-swiper-slide
config:
stylesheet: >
.item-content{
margin: 5px !important;
}
slots:
default:
- component: f7-list-item
config:
style:
background-color: rgb(31,31,31)
color: white
font-size: 18px
font-weight: bold
height: 40px
left: 20px
position: absolute
text-align: center
top: 40px
width: 370px
title: Music
- component: oh-button
config:
action: command
actionCommand: "98000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '98000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 20px
position: absolute
top: 100px
width: 80px
text: Classic
- component: oh-button
config:
action: command
actionCommand: "99000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '99000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 165px
position: absolute
top: 100px
width: 80px
text: Pop
- component: oh-button
config:
action: command
actionCommand: 9A000000000000000000000000000000
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '9A000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 310px
position: absolute
top: 100px
width: 80px
text: Rock
- component: oh-button
config:
action: command
actionCommand: 9B000000000000000000000000000000
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '9B000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 20px
position: absolute
top: 200px
width: 80px
text: Absolut
- component: oh-button
config:
action: command
actionCommand: 9C000000000000000000000000000000
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '9C000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 165px
position: absolute
top: 200px
width: 80px
text: Electro
- component: oh-button
config:
action: command
actionCommand: 9D000000000000000000000000000000
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '9D000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 310px
position: absolute
top: 200px
width: 80px
text: Ambient
- component: f7-list-item
config:
style:
background-color: rgb(31,31,31)
color: white
font-size: 18px
font-weight: bold
height: 40px
left: 20px
position: absolute
text-align: center
top: 320px
width: 370px
title: Scenes
- component: oh-button
config:
action: command
actionCommand: "86000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '86000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 20px
position: absolute
top: 380px
width: 80px
text: Rainbow
- component: oh-button
config:
action: command
actionCommand: "87000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '87000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 116.667px
position: absolute
top: 380px
width: 80px
text: Fire
- component: oh-button
config:
action: command
actionCommand: "88000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '88000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 216.667px
position: absolute
top: 380px
width: 80px
text: Read
- component: oh-button
config:
action: command
actionCommand: "89000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '89000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 316.667px
position: absolute
top: 380px
width: 80px
text: Firework
- component: oh-button
config:
action: command
actionCommand: "90000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '90000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 20px
position: absolute
top: 480px
width: 80px
text: Star
- component: oh-button
config:
action: command
actionCommand: "91000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '91000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 116.667px
position: absolute
top: 480px
width: 80px
text: Drip
- component: oh-button
config:
action: command
actionCommand: "92000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '92000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 216.667px
position: absolute
top: 480px
width: 80px
text: Particle
- component: oh-button
config:
action: command
actionCommand: "93000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '93000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 316.667px
position: absolute
top: 480px
width: 80px
text: Flow
- component: oh-button
config:
action: command
actionCommand: "94000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '94000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 20px
position: absolute
top: 580px
width: 80px
text: Ball
- component: oh-button
config:
action: command
actionCommand: "95000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '95000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 116.667px
position: absolute
top: 580px
width: 80px
text: Swing
- component: oh-button
config:
action: command
actionCommand: "96000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '96000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 216.667px
position: absolute
top: 580px
width: 80px
text: Breath
- component: oh-button
config:
action: command
actionCommand: "97000000000000000000000000000000"
actionItem: =props.backlightMode
color: white
style:
background-color: "=((items[props.backlightMode].state == '97000000000000000000000000000000') ? 'rgb(119, 119, 119)' : 'rgb(31,31,31)')"
border-radius: 50px
color: white
display: flex
height: 80px
left: 316.667px
position: absolute
top: 580px
width: 80px
text: Pure
The Page created for this :
config:
activeIdx: 0
fixedType: canvas
grid: 10
gridEnable: true
label: LivingRoomTV Remote
layoutType: fixed
order: "1"
scale: false
screenHeight: 780
screenWidth: 410
sidebar: true
style:
background-color: rgb(47,47,47)
stylesheet: |
.oh-canvas-background{
background-color: rgb(47,47,47)
}
.oh-canvas-item{
transform: none !important;
}
blocks: []
masonry: null
grid: []
canvas:
- component: oh-canvas-layer
config: {}
slots:
default:
- component: oh-canvas-item
config:
h: 780
w: 410
x: 0
y: 0
slots:
default:
- component: widget:UniversalRemote2
config:
backlightBrightness: Living_Room_TV_Backlight_Brightness
backlightDiffusion: Living_Room_TV_Backlight_Diffusion
backlightInput: Living_Room_TV_Backlight_Input
backlightMode: Living_Room_TV_Backlight_Mode
computer: "0"
down: "20"
home: "3"
item: GoogleTV_Keycode
left: "21"
light: Living_Room_TV_Backlight_Switch
lightoff: OFF
lighton: ON
lightswitch: Living_Room_TV_Backlight_Switch
modeGame: "82000000000000000000000000000000"
modeRecreation: "81000000000000000000000000000000"
modeVideo: "80000000000000000000000000000000"
ok: "23"
power: "26"
poweroff: OFF
poweron: ON
return: "4"
right: "22"
tv: "2"
tvpower: Living_Room_TV_Power
up: "19"
volumedown: "25"
volumemute: "91"
volumeup: "24"
For the one interested, here is my Living_Room_TV_Backlight that control the Lytmi box :
UID: mqtt:topic:d27f73269a:living_room_tv_backlight
label: Living Room TV Backlight
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:d27f73269a
location: Living Room
channels:
- id: switch
channelTypeUID: mqtt:switch
label: Switch
description: ""
configuration:
commandTopic: tuya/living_room_tv_backlight/dps/20/command
stateTopic: tuya/living_room_tv_backlight/dps/20/state
off: "false"
on: "true"
- id: input
channelTypeUID: mqtt:number
label: Input
description: ""
configuration:
commandTopic: tuya/living_room_tv_backlight/dps/105/command
min: 0
stateTopic: tuya/living_room_tv_backlight/dps/105/state
max: 3
- id: mode
channelTypeUID: mqtt:string
label: Mode
description: ""
configuration:
formatBeforePublish: "%s"
commandTopic: tuya/living_room_tv_backlight/dps/25/command
stateTopic: tuya/living_room_tv_backlight/dps/25/state
- id: diffusion
channelTypeUID: mqtt:number
label: Diffusion
description: ""
configuration:
commandTopic: tuya/living_room_tv_backlight/dps/108/command
min: 10
stateTopic: tuya/living_room_tv_backlight/dps/108/state
max: 1000
- id: brightness
channelTypeUID: mqtt:number
label: Brightness
description: ""
configuration:
commandTopic: tuya/living_room_tv_backlight/dps/22/command
min: 10
stateTopic: tuya/living_room_tv_backlight/dps/22/state
max: 1000