สั่ง Home Assistant ให้ทีวี LG webOS ไปที่ HDMI 2 ด้วยวิธีตรง ๆ แล้วบางเย็นทีวีกลับเปิดแอปสตรีมมิงแทน หน้านี้อธิบายว่าทำไม ให้วิธีที่ได้ผล — เปิดอินพุตในฐานะแอปที่มันเป็นอยู่ลับ ๆ ซ้ำไปเรื่อย ๆ จนสถานะยืนยัน — และปิดท้ายด้วยสคริปต์ฉบับเต็มที่พาเครื่องเกมจากปิดไปจนเล่นบนจอ รวมถึงรีซีฟเวอร์ และรายงานเฉพาะสิ่งที่ตรวจสอบแล้วเท่านั้น
บน webOS ทุกอินพุต HDMI คือแอปพลิเคชัน — com.webos.app.hdmi1, hdmi2 และอื่น ๆ — และรายการแหล่งสัญญาณของทีวีปนแอปอินพุตเหล่านั้นเข้ากับแอปจริง media_player.select_source จับคู่กับรายการที่ปนกันนั้น และขึ้นกับว่าทีวีรายงานอะไรในขณะนั้น “เลือก HDMI 2” อาจกลายเป็นการเปิดแอปไหนก็ได้ที่ทีวีเพิ่งนึกชอบ กับดักที่สองคือจังหวะเวลา: ทีวี webOS ที่เพิ่งตื่นจะรับคำสั่งก่อนที่จะลงมือทำตาม คำสั่งสลับที่ส่งครั้งเดียวจึงหายไปในความว่างเปล่า และกับดักที่สามโหดที่สุด: การเชื่อมต่อ webOS ของ Home Assistant ตอบว่าสำเร็จสำหรับคำสั่งที่ส่งไปยังทีวีซึ่ง websocket หลุดไปเงียบ ๆ — คำสั่ง “สำเร็จ” แต่ไม่มีอะไรเกิดขึ้น
media_player.select_source กับอินพุต HDMI บนทีวี LG และอย่าเชื่อคำสั่งแบบยิงแล้วลืมเพียงครั้งเดียว เปิดอินพุตในฐานะแอป ในลูป แล้วให้สถานะของเอนทิตีเองเป็นตัวตัดสินว่าเสร็จเมื่อไรเคล็ดลับทั้งหมดในสคริปต์เล็ก ๆ ตัวเดียว: เปิดทีวี (ไม่เสียหายอะไรถ้าเปิดอยู่แล้ว) แล้วเปิดแอป HDMI ทุกสองวินาทีจนทีวีรายงานว่าเปิดอยู่ แทนที่ entity id ด้วยของทีวีคุณ และแทน hdmi2 ด้วยอินพุตที่คุณต้องการ
select_hdmi2:
alias: Select HDMI 2
mode: single
sequence:
- action: media_player.turn_on
target:
entity_id: media_player.lg_webos_tv
continue_on_error: true
- repeat:
until:
- condition: or
conditions:
- condition: state
entity_id: media_player.lg_webos_tv
state: "on"
- "{{ repeat.index >= 15 }}"
sequence:
- action: media_player.turn_on
target:
entity_id: media_player.lg_webos_tv
continue_on_error: true
- delay:
seconds: 2
- action: webostv.command
data:
command: system.launcher/launch
payload:
id: com.webos.app.hdmi2
target:
entity_id: media_player.lg_webos_tv
continue_on_error: trueรายละเอียดสองอย่างแบกน้ำหนักทั้งหมด media_player.turn_on บนเอนทิตี webOS จะส่ง Wake-on-LAN เมื่อทีวีปิดอยู่ — ลูปจึงเป็นเส้นทางปลุกเครื่องไปในตัว และการส่งซ้ำระหว่างทีวีกำลังบูตคือสิ่งที่แพ็กเก็ตแรกที่อาจหลุดต้องการพอดี และ continue_on_error ทุกจุด ทำให้ทีวีที่กำลังบูตไม่ทำให้สคริปต์หยุดกลางคัน ลูปแค่ลองใหม่
คำขอจริงคือ “เปิด PlayStation” ซึ่งหมายถึงอุปกรณ์สามชิ้นทำงานประสานกัน: ปลุกเครื่องเกม ปลุกทีวี ตั้งรีซีฟเวอร์ไปที่อินพุตของเครื่องเกม ตั้งทีวีไปที่ HDMI ของรีซีฟเวอร์ — และกดทั้งหมดซ้ำไปเรื่อย ๆ จนรีซีฟเวอร์รายงานอินพุตที่ถูกต้อง และทีวีรายงานว่าเปิด หรือจนหมดงบเวลา 50 วินาที สคริปต์ด้านล่างคือเวอร์ชันที่ใช้งานจริงจากห้องนั่งเล่นของเรา เปิดให้ผู้ช่วยเสียงใช้ มันคืนประโยคให้พูดที่ไม่เคยอ้างเกินกว่าที่สถานะแสดง ในภาษาใดก็ได้จากสามภาษาที่คำขอส่งมา เปลี่ยน entity id ทั้งสี่และชื่ออินพุตเป็นของคุณ
select_ps5:
alias: Select PS5
icon: mdi:sony-playstation
mode: single
description: >-
Turns the PlayStation 5 ON for the living room, end to end: wakes the console
(switch.living_room_ps5_pro), turns on the LG TV and the receiver, then switches
the receiver to its PlayStation 5 input and the TV to HDMI 2, retrying every 2 s
(re-sending wake-on-LAN to the TV while it is off) until the receiver reports the
PlayStation 5 input AND the TV is on (at most ~50 s). Use this for "turn on the
PS5", "switch to the PlayStation", "I want to play" and their translations.
Never use the bare console switch for these requests: it wakes the console but
leaves the TV and receiver untouched. Returns a sentence to speak verbatim; do
not say the PlayStation is on unless it is the returned message.
fields:
language:
name: Language
description: "Language of the sentence to return: en, th or zh."
selector:
select:
options:
- en
- th
- zh
default: en
sequence:
- action: switch.turn_on
target:
entity_id: switch.living_room_ps5_pro
continue_on_error: true
- action: media_player.turn_on
target:
entity_id: media_player.lg_webos_tv_oled77c1ptb
continue_on_error: true
- action: media_player.turn_on
target:
entity_id: media_player.living_room
continue_on_error: true
- repeat:
until:
- condition: or
conditions:
- condition: and
conditions:
- condition: state
entity_id: media_player.living_room
attribute: source
state: PlayStation 5
- condition: state
entity_id: media_player.lg_webos_tv_oled77c1ptb
state: "on"
- "{{ repeat.index >= 25 }}"
sequence:
- if:
- condition: not
conditions:
- condition: state
entity_id: media_player.lg_webos_tv_oled77c1ptb
state: "on"
then:
- action: media_player.turn_on
target:
entity_id: media_player.lg_webos_tv_oled77c1ptb
continue_on_error: true
- action: media_player.select_source
data:
source: PlayStation 5
target:
entity_id: media_player.living_room
continue_on_error: true
- if:
- condition: state
entity_id: media_player.lg_webos_tv_oled77c1ptb
state: "on"
then:
- action: webostv.command
data:
command: system.launcher/launch
payload:
id: com.webos.app.hdmi2
target:
entity_id: media_player.lg_webos_tv_oled77c1ptb
continue_on_error: true
- delay:
seconds: 2
- if:
- condition: state
entity_id: media_player.lg_webos_tv_oled77c1ptb
state: "on"
then:
- action: webostv.command
data:
command: system.launcher/launch
payload:
id: com.webos.app.hdmi2
target:
entity_id: media_player.lg_webos_tv_oled77c1ptb
continue_on_error: true
- variables:
avr_ok: "{{ is_state_attr('media_player.living_room', 'source', 'PlayStation 5') }}"
ps5_on: "{{ is_state('switch.living_room_ps5_pro', 'on') }}"
tv_on: "{{ is_state('media_player.lg_webos_tv_oled77c1ptb', 'on') }}"
result:
message: >-
{% set lang = language | default('en') %}
{% if avr_ok and ps5_on and tv_on %}{{ {'en': 'The PlayStation is on and the TV is set to it.',
'th': 'เปิดเพลย์สเตชั่นแล้ว และตั้งทีวีไปที่เพลย์สเตชั่นเรียบร้อยครับ',
'zh': 'PlayStation 已开机,电视已切换到它。'}[lang] }}
{% elif ps5_on and avr_ok %}{{ {'en': 'The PlayStation and receiver are on, but the TV did not wake up. Press the TV power button.',
'th': 'เพลย์สเตชั่นและรีซีฟเวอร์เปิดแล้ว แต่ทีวียังไม่ติด กรุณากดปุ่มเปิดทีวีครับ',
'zh': 'PlayStation 和功放已开机,但电视没有唤醒。请按电视电源键。'}[lang] }}
{% elif ps5_on %}{{ {'en': 'The PlayStation is awake, but the receiver did not switch to the PlayStation input. Try again or use the remote.',
'th': 'เพลย์สเตชั่นเปิดแล้ว แต่รีซีฟเวอร์ยังไม่สลับไปที่ช่องเพลย์สเตชั่น ลองสั่งอีกครั้งหรือใช้รีโมทครับ',
'zh': 'PlayStation 已唤醒,但功放没有切换到 PlayStation 输入。请再试一次或使用遥控器。'}[lang] }}
{% else %}{{ {'en': 'The PlayStation did not wake up. Check it is plugged in and on the network.',
'th': 'เพลย์สเตชั่นไม่ตื่นขึ้นมา กรุณาตรวจสอบว่าเสียบปลั๊กและเชื่อมต่อเครือข่ายอยู่ครับ',
'zh': 'PlayStation 没有唤醒。请检查是否已插电并连接网络。'}[lang] }}
{% endif %}
- stop: Done
response_variable: resultฝั่งรีซีฟเวอร์ใช้ media_player.select_source — บนรีซีฟเวอร์ภาพและเสียงแบบเครือข่าย นี่คือคำสั่งที่ถูกต้อง เพราะรีซีฟเวอร์รายงานและสลับอินพุตตามชื่ออย่างซื่อตรง มีเพียงการเลือก HDMI ของทีวี LG ที่ต้องใช้เส้นทางเปิดแอป สังเกตโครงสร้างของตอนจบ: สคริปต์อ่านสถานะทั้งสามหลังลูป แล้วสร้างคำตอบจากสถานะเหล่านั้น โดยมีแขนงสำหรับทุกผลลัพธ์ที่ซื่อตรง ผู้ช่วยเสียงที่ได้สคริปต์นี้ไปจะพูดความจริงได้ — รวมถึง “กรุณากดปุ่มเปิดทีวี” ในเย็นที่หายากซึ่งจอเพิกเฉยต่อแพ็กเก็ตปลุกทุกอัน
เปิดให้ผู้ช่วยเห็นสคริปต์ ไม่ใช่ตัวอุปกรณ์ description ยาว ๆ ในตัวอย่างกำลังทำงานจริง: มันบอกผู้ช่วยแบบโมเดลภาษาว่าควรเรียกสคริปต์เมื่อไร ครอบคลุมรูปประโยคแบบไหน และ — สำคัญไม่แพ้กัน — อะไรที่ห้ามทำ (“never use the bare console switch”) ฟิลด์ language คู่กับ response_variable ให้ประโยคสำเร็จรูปแก่ผู้ช่วยไว้พูด มันจึงด้นความสำเร็จที่ฮาร์ดแวร์ไม่เคยทำได้ขึ้นมาเองไม่ได้ หนึ่งสคริปต์ต่อหนึ่งปลายทาง (select_ps5, select_shield, select_appletv…) ทำให้คำอธิบายแต่ละอันสั้น และคำตัดสินแต่ละอันซื่อตรง
unavailable และโหลดการเชื่อมต่อใหม่ถ้าใช่com.webos.app.hdmi2 หมายถึงช่องที่เขียนว่า HDMI 2 บนทีวีเครื่องนั้น — ตรวจก่อนว่าแหล่งสัญญาณของคุณเสียบอยู่ช่องไหน ก่อนจะโทษสคริปต์repeat.index ไม่ใช่ของประดับ: ถ้าไม่มีมัน ทีวีที่ถอดปลั๊กจะทำให้สคริปต์หมุนอยู่ตลอดไปใน mode: single และคำขอทุกครั้งหลังจากนั้นจะถูกทิ้งไปเงียบ ๆ