neilimixamo / Home-Assistant-Quick-Look-Mobile

127 stars 6 forks source link

Call a card in footer section #33

Closed Michelone86 closed 5 months ago

Michelone86 commented 6 months ago

Hi Neil, I created a card dedicated to my TV remote control. How can I call her when I click on one of these buttons? Thank you! Screenshot_20240527_104120_edit_1164052791380269

IMG-20240527-WA0007

Michelone86 commented 6 months ago

Hi @neilimixamo, any ideas for me? Thanks ✌🏻

neilimixamo commented 6 months ago

Hi @Michelone86, yes, your request is totally doable. I'll make sure to give you a detailed response tonight. Is your remote view part of the QLM dashboard, or is it in another Home Assistant dashboard ?

Michelone86 commented 6 months ago

Hi @neilimixamo, that remote control belongs to a tab of another Dashboard, but only because I'm not able to make it in your qlm Dashboard... It would be nice if it were native in your Dashboard, it could also open with a popup effect πŸš€

neilimixamo commented 6 months ago

Hi @neilimixamo, that remote control belongs to a tab of another Dashboard, but only because I'm not able to make it in your qlm Dashboard... It would be nice if it were native in your Dashboard, it could also open with a popup effect πŸš€

Here is how i integrated the TV remote in my dashboard by double clicking on the green TV card

https://github.com/neilimixamo/Home-Assistant-Quick-Look-Mobile/assets/43101688/8d1b0542-8970-4f0e-8c82-5eaf51e8dce9

Michelone86 commented 6 months ago

@neilimixamo it's beautiful, I really like it 😍

neilimixamo commented 6 months ago

Ok, so, if you want to access the view of another dashboard via the routine cards as you asked, copy its URL, let's say "/lovelace/remote", update the "routines_footer.yaml" template with the code below, then add the "navigation_path" variable in your Home view like this :

dashboards/quick_look_mobile/templates/footers/routines_footer.yaml ```yaml routines_footer: variables: routine1_entity: #scene, script or automation routine1_name: routine1_background_color: routine1_icon_color: routine1_navigation_path: routine2_entity: #scene, script or automation routine2_name: routine2_background_color: routine2_icon_color: routine2_navigation_path: routine3_entity: #scene, script or automation routine3_name: routine3_background_color: routine3_icon_color: routine3_navigation_path: routine4_entity: #scene, script or automation routine4_name: routine4_background_color: routine4_icon_color: routine4_navigation_path: routine5_entity: #scene, script or automation routine5_name: routine5_background_color: routine5_icon_color: routine5_navigation_path: triggers_update: all styles: card: - height: 9vh - width: 92vw - margin: -0.3vh 0vh 0vh 1vw - background-color: 'transparent' - padding: 0px - border-radius: 0px - box-shadow: none - cursor: none grid: - grid-template-rows: auto - grid-template-columns: auto - grid-template-areas: | "menu" custom_fields: menu: card: type: grid columns: 5 square: false cards: - type: custom:button-card # Routine 1 entity: '[[[return variables.routine1_entity ]]]' size: '50%' show_name: | [[[ if (variables.routine1_name) return true; return false; ]]] name: | [[[ if (variables.routine1_name) return variables.routine1_name; return ''; ]]] show_icon: | [[[ if (variables.routine1_name) return false; return true; ]]] show_state: false show_label: false styles: card: - height: 7.9vh - width: 7.5vh - margin: 0vh 0.2vh 0vh 0.5vh - border-radius: 50% - box-shadow: none - background: | [[[ if (variables.routine1_background_color) { return variables.routine1_background_color; } else { return "var(--routine-background-color)"; } ]]] - cursor: none - --mdc-ripple-press-opacity: 0 name: - font-size: 12px icon: - color: | [[[ if (variables.routine1_icon_color) { return variables.routine1_icon_color; } else { return "var(--routine-icon-color)"; } ]]] tap_action: action: > [[[ if (variables.routine1_navigation_path) return 'navigate'; return 'call-service'; ]]] service: > [[[ const routine = variables['routine1_entity']; if (!routine || variables.routine1_navigation_path) return 'none'; return routine.startsWith('script.') ? 'script.turn_on' : routine.startsWith('scene.') ? 'scene.turn_on' : routine.startsWith('automation.') ? 'automation.trigger' : 'none'; ]]] navigation_path: > [[[ if (variables.routine1_navigation_path) return variables.routine1_navigation_path; return ''; ]]] service_data: entity_id: '[[[return variables.routine1_entity ]]]' - type: custom:button-card # Routine 2 entity: '[[[return variables.routine2_entity ]]]' size: '50%' show_name: | [[[ if (variables.routine2_name) return true; return false; ]]] name: | [[[ if (variables.routine2_name) return variables.routine2_name; return ''; ]]] show_icon: | [[[ if (variables.routine2_name) return false; return true; ]]] show_state: false show_label: false styles: card: - height: 7.9vh - width: 7.5vh - margin: 0vh 0.2vh - border-radius: 50% - box-shadow: none - background: | [[[ if (variables.routine2_background_color) { return variables.routine2_background_color; } else { return "var(--routine-background-color)"; } ]]] - cursor: none - --mdc-ripple-press-opacity: 0 name: - font-size: 12px icon: - color: | [[[ if (variables.routine2_icon_color) { return variables.routine2_icon_color; } else { return "var(--routine-icon-color)"; } ]]] tap_action: action: > [[[ if (variables.routine2_navigation_path) return 'navigate'; return 'call-service'; ]]] service: > [[[ const routine = variables['routine2_entity']; if (!routine || variables.routine2_navigation_path) return 'none'; return routine.startsWith('script.') ? 'script.turn_on' : routine.startsWith('scene.') ? 'scene.turn_on' : routine.startsWith('automation.') ? 'automation.trigger' : 'none'; ]]] navigation_path: > [[[ if (variables.routine2_navigation_path) return variables.routine2_navigation_path; return ''; ]]] service_data: entity_id: '[[[return variables.routine2_entity ]]]' - type: custom:button-card # Routine 3 entity: '[[[return variables.routine3_entity ]]]' size: '50%' show_name: | [[[ if (variables.routine3_name) return true; return false; ]]] name: | [[[ if (variables.routine3_name) return variables.routine3_name; return ''; ]]] show_icon: | [[[ if (variables.routine3_name) return false; return true; ]]] show_state: false show_label: false styles: card: - height: 7.9vh - width: 7.5vh - margin: 0vh 0.2vh - border-radius: 50% - box-shadow: none - background: | [[[ if (variables.routine3_background_color) { return variables.routine3_background_color; } else { return "var(--routine-background-color)"; } ]]] - cursor: none - --mdc-ripple-press-opacity: 0 name: - font-size: 12px icon: - color: | [[[ if (variables.routine3_icon_color) { return variables.routine3_icon_color; } else { return "var(--routine-icon-color)"; } ]]] tap_action: action: > [[[ if (variables.routine3_navigation_path) return 'navigate'; return 'call-service'; ]]] service: > [[[ const routine = variables['routine3_entity']; if (!routine || variables.routine3_navigation_path) return 'none'; return routine.startsWith('script.') ? 'script.turn_on' : routine.startsWith('scene.') ? 'scene.turn_on' : routine.startsWith('automation.') ? 'automation.trigger' : 'none'; ]]] navigation_path: > [[[ if (variables.routine3_navigation_path) return variables.routine3_navigation_path; return ''; ]]] service_data: entity_id: '[[[return variables.routine3_entity ]]]' - type: custom:button-card # Routine 4 entity: '[[[return variables.routine4_entity ]]]' size: '50%' show_name: | [[[ if (variables.routine4_name) return true; return false; ]]] name: | [[[ if (variables.routine4_name) return variables.routine4_name; return ''; ]]] show_icon: | [[[ if (variables.routine4_name) return false; return true; ]]] show_state: false show_label: false styles: card: - height: 7.9vh - width: 7.5vh - margin: 0vh 0.2vh - border-radius: 50% - box-shadow: none - background: | [[[ if (variables.routine4_background_color) { return variables.routine4_background_color; } else { return "var(--routine-background-color)"; } ]]] - cursor: none - --mdc-ripple-press-opacity: 0 name: - font-size: 12px icon: - color: | [[[ if (variables.routine4_icon_color) { return variables.routine4_icon_color; } else { return "var(--routine-icon-color)"; } ]]] tap_action: action: > [[[ if (variables.routine4_navigation_path) return 'navigate'; return 'call-service'; ]]] service: > [[[ const routine = variables['routine4_entity']; if (!routine || variables.routine4_navigation_path) return 'none'; return routine.startsWith('script.') ? 'script.turn_on' : routine.startsWith('scene.') ? 'scene.turn_on' : routine.startsWith('automation.') ? 'automation.trigger' : 'none'; ]]] navigation_path: > [[[ if (variables.routine4_navigation_path) return variables.routine4_navigation_path; return ''; ]]] service_data: entity_id: '[[[return variables.routine4_entity ]]]' - type: custom:button-card # Routine 5 entity: '[[[return variables.routine5_entity ]]]' size: '50%' show_name: | [[[ if (variables.routine5_name) return true; return false; ]]] name: | [[[ if (variables.routine5_name) return variables.routine5_name; return ''; ]]] show_icon: | [[[ if (variables.routine5_name) return false; return true; ]]] show_state: false show_label: false styles: card: - height: 7.9vh - width: 7.5vh - margin: 0vh 0.2vh 0vh 0.2vh - border-radius: 50% - box-shadow: none - background: | [[[ if (variables.routine5_background_color) { return variables.routine5_background_color; } else { return "var(--routine-background-color)"; } ]]] - cursor: none - --mdc-ripple-press-opacity: 0 name: - font-size: 12px icon: - color: | [[[ if (variables.routine5_icon_color) { return variables.routine5_icon_color; } else { return "var(--routine-icon-color)"; } ]]] tap_action: action: > [[[ if (variables.routine5_navigation_path) return 'navigate'; return 'call-service'; ]]] service: > [[[ const routine = variables['routine5_entity']; if (!routine || variables.routine5_navigation_path) return 'none'; return routine.startsWith('script.') ? 'script.turn_on' : routine.startsWith('scene.') ? 'scene.turn_on' : routine.startsWith('automation.') ? 'automation.trigger' : 'none'; ]]] navigation_path: > [[[ if (variables.routine5_navigation_path) return variables.routine5_navigation_path; return ''; ]]] service_data: entity_id: '[[[return variables.routine5_entity ]]]' ```
- type: custom:button-card # FOOTER
  view_layout:
    grid-area: footer
  template: routines_footer
  variables:
    routine1_entity: #optional  
    routine1_name: #optional
    routine1_background_color: #optional
    routine1_icon_color: #optional
    routine1_navigation_path: /lovelace/remote

Now, personally, I am a big fan of @PRProd Doug's 'fireremote' card, which allows importing the look and feel of a wide variety of existing remote controls. For me, I chose the 'chromecast-4k' remote and created this dedicated view for the remote :

dashboards/quick_look_mobile/views/popups/media_tv_remote.yaml ```yaml title: media_tv_remote path: media_tv_remote icon: mdi:remote-tv theme: Quick Look Mobile background: var(--theme) #linear-gradient(180deg, rgba(255,255,255,1) 0%, rgba(240,243,253,1) 15%) type: custom:grid-layout layout: margin: -0.5vh 1vh 0vh grid-template-columns: auto grid-template-rows: min-content grid-template-areas: | "main" cards: - type: custom:layout-card # MAIN view_layout: grid-area: main layout_type: custom:vertical-layout layout: margin: 0vh 0vh 0vh padding: 0vh 0.4vh cards: - type: custom:button-card styles: card: - background: transparent - height: 97vh - width: 91vw - padding: 0px - box-shadow: none - cursor: none - --mdc-ripple-press-opacity: 0 grid: - display: flex - justify-content: center - align-items: flex-end tap_action: action: navigate navigation_path: media_tv custom_fields: remote: card: type: custom:firemote-card entity: media_player.lounge_tv_debug device_family: chromecast device_type: chromecast-4k compatibility_mode: default android_tv_remote_entity: remote.lounge_tv defaultRemoteStyle_override: #'XM2' app_launch_1: youtube app_launch_2: hide_button_highlights: true button_overrides: netflix-button: hidden: true scale: '100' card_mod: style: | ha-card { width: min-content; padding: 0px; } ```

I opted to call this view remote from a media card dedicated to my TV where you can see that the navigation_path only includes the name of the view because it is integrated into the QLM dashboard like this :

- type: custom:button-card 
  template: media 
  variables:
    entity: media_player.lounge_tv_debug
    remote: remote.lounge_tv
    name: TV
    label: '[[[ return states["media_player.lounge_tv_debug"].attributes.app_name; ]]]'
    name_double_tap_action:
      action: navigate
      navigation_path: media_tv_remote

There's also a dashboard template dedicated to remote controls available on the official Home Assistant website.

Michelone86 commented 5 months ago

Ok everything works, thank you very much @neilimixamo, you are always very kind πŸ™πŸ˜Š

Michelone86 commented 5 months ago

CIAO@neilimixamo, quel telecomando appartiene ad una scheda di un'altra Dashboard, ma solo perchΓ© non riesco a farlo nella tua Dashboard qlm... Sarebbe carino se fosse nativo nella tua Dashboard, si potrebbe aprire anche con un effetto popup πŸš€

Ecco come ho integrato il telecomando della TV nella mia dashboard facendo doppio clic sulla scheda TV verde

Registratore dello schermo-2024-05-29-14-08-18-517.mp4

Hi @neilimixamo, I'm going crazy to do something.. when I activate the QLM theme, unfortunately I lose the menu at the top right that allows me to update the Dashboard after making some changes. I saw in this video that you have a "reload" type icon. Could you please tell me what is the command to refresh the page? Thank you πŸ™

neilimixamo commented 5 months ago

Hi, the following code used to allow me to refresh the page :

tap_action:
  action: call-service
  service: browser_mod.javascript
  service_data:
    code: lovelace_reload()
  target:
    device_id:

However, it isn't working anymore for me now and I haven't found a fix yet. Therefore, I need to activate the default theme when I perform regular refreshes and then I switch back to the QLM theme once my testing phase is over.

If I find a solution, I will keep you informed.

Michelone86 commented 5 months ago

Ok thanks, I hope you can find an ingenious solution πŸ˜‰πŸ’ͺ🏻