Custom Header

Hey all,

Maybe someone stumbled already in this situation… I have a RPI3 with touchscreen installed. From that panel i login with chromium browser to go to the HA main webpage. What i configured is that when i login with user X then it should only display panel Y with no fancy features etc. Now this works on my normal laptop but the moment that i login via my rpi it always shows the default HA ui. Any ideas?

Thnx

have a small dashboard which enables testing the various settings extremely easily. So cool. Only possible because of your relentless effort to create something beautiful for the community. So thanks again!

(added split mode and a few others…once you get the taste for it the endless options won’t let you go)

ch_split_mode:
  name: Split mode
  icon: mdi:arrow-split-horizontal #or mdi:page-layout-header-footer ;-)

only thing is one needs to set exclusions settings either hard coded, or with dedicated booleans… the work never ends :wink:

1 Like

Hey Ryan,
do need some help…

right now I use this for button_text on options:

button_text:
  options: >-
    {{ time }} - <ha-icon icon='{{states('sensor.weather_icon')}}' style='vertical-align: middle';></ha-icon> - {{states('sensor.temp_current') }}°

How can I create a boolean input_boolean.ch_options_text that shows the above when on, and the default value when off? I think I can do this:

button_text:
  options: >-
    {% if is_state('input_boolean.ch_use_options_text_template','on')%}{{ time }} - <ha-icon icon='{{states('sensor.weather_icon')}}' style='vertical-align: middle';></ha-icon> - {{states('sensor.temp_current') }}°
    {% endif %}

but am not sure if I can leave out the {%else%} clause? For now this seems to work on the options text not sure if it is ‘safe’ though.

This technique doesn’t work on the header text, which is the vertical marquee as created in theo the thread. If I disable the input_boolean, the marquee disappears alright, but the default header text doesn’t appear, leaving an empty header…

is that a bug or simply unsupported…

Any way you can share your code for that dashboard (including the CH code)? please? :wink:

sure here you go:

ch header:

#https://maykar.github.io/custom-header/#configuration/main
#test_template: >-
#  System alerts: {{states('sensor.marquee_alerts')}}

header_text: >-
  {% if is_state('input_boolean.ch_use_header_text_template','on')%}
  <style>
  #flipper{color:#999;}
  #flip {height:24px;overflow:hidden;}
  #flip > div > div {color:var(--primary-text-color);height:24px;margin-bottom:24px;display:inline-block;text-overflow: clip;white-space: nowrap;}
  #flip div:first-child {animation: show 10s linear infinite;}
  @keyframes show {
  0% {margin-top:-144px;}
  17% {margin-top:-96px;}
  33% {margin-top:-96px;}
  50% {margin-top:-48px;}
  67% {margin-top:-48px;}
  83% {margin-top:0px;}
  100% {margin-top:0px;}}
  #flipper p {position:fixed;color:#999; }
  </style>
  <div style='float: left'>Ha Rpi4:&nbsp;</div>
  <div id=flip><div><div>
  Summary - {{states('sensor.dark_sky_summary')}}</div></div><div><div>
  Daily -  {{states('sensor.dark_sky_daily_summary')}}</div></div><div><div>
  Hourly - {{states('sensor.dark_sky_hourly_summary')}}</div></div><div><div>
  Summary - {{states('sensor.dark_sky_summary')}}</div></div><div><div>
  {% endif %}
#  {{states('sensor.dark_sky_summary')}}</div></div><div><div>
#  {{states('sensor.br_symbol')}}</div></div><div><div>

## all default
disabled_mode: >-
  {{is_state('input_boolean.ch_disabled_mode','on')}}
kiosk_mode: >-
  {{ is_state('input_select.mode','Kiosk') }}
compact_mode: >-
  {{is_state('input_boolean.ch_compact_mode','on')}}
shadow: >-
  {{is_state('input_boolean.ch_shadow','on')}}
footer_mode: >-
  {{is_state('input_boolean.ch_footermode_mode','on')}}
split_mode: >-
  {{is_state('input_boolean.ch_split_mode','on')}}
disable_sidebar: >-
  {{is_state('input_boolean.ch_disable_sidebar','on')}}
hide_header: >-
  {{is_state('input_boolean.ch_hide_header','on')}}
hide_help: >-
  {{is_state('input_boolean.ch_hide_help','on')}}
hide_unused: >-
  {{is_state('input_boolean.ch_hide_unused','on')}}
hide_refresh: >-
  {{is_state('input_boolean.ch_hide_refresh','on')}}
hide_config: >-
  {{is_state('input_boolean.ch_hide_config','on')}}
#hide_raw: false
default_tab_on_refresh: false

# https://maykar.github.io/custom-header/#configuration/buttons
menu_hide: >
  {{is_state('input_boolean.ch_menu_hide','on')}}
voice_hide: >-
  {{is_state('input_boolean.ch_voice_hide','on')}}
options_hide: >-
  {{is_state('input_boolean.ch_options_hide','on')}}
menu_dropdown: >-
  {{is_state('input_boolean.ch_menu_dropdown','on')}}
voice_dropdown: >-
  {{is_state('input_boolean.ch_voice_dropdown','on')}}
reverse_button_direction: >-
  {{is_state('input_boolean.ch_reverse_button_direction','on')}}
#button_icons:

button_text:
  options: >-
    {% if is_state('input_boolean.ch_use_options_text_template','on')%}{{ time }} - <ha-icon icon='{{states('sensor.weather_icon')}}' style='vertical-align: middle';></ha-icon> - {{states('sensor.temp_current') }}°
    {% endif %}
#options_css: 'color:var(--primary-text-color);'

show_tabs: >
  {% if not is_state('input_select.mode','Developer') %}0 to 21, 26 to 28
  {% else %} 0 to 28
  {% endif %}

# https://maykar.github.io/custom-header/#configuration/exceptions
exceptions:
  - conditions:
      user: Gezin, redacted names
    config:
      show_tabs: 0 to 3,6,15 to 18
      voice_hide: true
      options_hide: true
  - conditions:
      user_agent: iPhone
    config:
      footer_mode: true
      indicator_top: false
      header_text: >-
        {% set inside=states('sensor.temperatuur_living')%}
        {% set outside=states('sensor.temp_current')%} 
        {% set temp_color='var(--primary-text-color)'%} 
        {% set symbol='°C' %}
        <div style='display: flex;display: -webkit-flex;'>
        <div>Ha&nbspRpi4:&nbsp;</div>
        <marquee>
        <span style='color: {{ temp_color }}'>
        Inside temperature: {{ inside }}{{ symbol }},
        Outside temperature: {{ outside }}{{ symbol }},
        </span>
        <span style='color: orange;'> 
        System alerts: {{states('sensor.marquee_alerts')}},
        </span>
        <span style='color: {{ temp_color }}'>
        Summary - {{states('sensor.dark_sky_summary')}},
        Daily -  {{states('sensor.dark_sky_daily_summary').split('.')[0]}},
        Hourly - {{states('sensor.dark_sky_hourly_summary').split('.')[0]}}.
        </span>
        </marquee>

#        {% set alerts = namespace(active=[], color='var(--google-red-500)') %}
#        {% if states('sensor.weatheralerts') | float != 0 %}
#          {% for alert in state_attr('sensor.weatheralerts', 'alerts') %}
#          {% set alerts.active = alerts.active + [alert['title']] %}
#          {% endfor %}
#        {% else %} {% set alerts.active = alerts.active + ['No active alerts'] %}
#        {% endif %}
#        {% set inside=states('sensor.temperatuur_living')%}
#        {% set outside=states('sensor.temp_current')%} 
#        {% set temp_color='var(--primary-text-color)'%} 
#        {% set symbol='°C' %}
#        <div style='display: flex;display: -webkit-flex;'>
#        <div>Ha&nbspRpi4:&nbsp;</div>
#        <marquee>
#        <span style='color: {{ temp_color }}'>
#        Inside temperature: {{ inside }}{{ symbol }},
#        Outside temperature: {{ outside }}{{ symbol }},
#        </span>
#        <span style='color: {{ alerts.color }};'>
#        Alerts: {{ alerts.active | join(' - ')}},
#        </span>
#        <span style='color: orange;'> 
#        System alerts: {{states('sensor.marquee_alerts')}},
#        </span>
#        <span style='color: {{ temp_color }}'>
#        Summary - {{states('sensor.dark_sky_summary')}},
#        Daily -  {{states('sensor.dark_sky_daily_summary').split('.')[0]}},
#        Hourly - {{states('sensor.dark_sky_hourly_summary').split('.')[0]}}.
#        </span>
#        </marquee>

      menu_hide: true
#      voice_hide: false
      options_hide: true
  - conditions:
      user_agent: iPad
    config:
      menu_hide: true
#      voice_hide: false
      options_hide: true

# https://maykar.github.io/custom-header/#configuration/tabs
chevrons: >-
  {{is_state('input_boolean.ch_chevrons','on')}}
indicator_top: >-
  {{is_state('input_boolean.ch_indicator_top','on')}}

#default_tab:
reverse_tab_direction: >-
  {{is_state('input_boolean.ch_reverse_tab_direction','on')}}

#hide_tabs: An array or comma separated string of tabs to hide, more info below
#show_tabs: An array or comma separated string of tabs to hide, more info below
hidden_tab_redirect: >-
  {{is_state('input_boolean.ch_hidden_tab_redirect','on')}}

tab_icons:
  alarm: >-
    {{states('sensor.alarm_panel_icon')}}
  phones_tablets: >-
    {{states('sensor.presence_icon')}}
  weer_klimaat: >-
    {{states('sensor.weather_icon')}}
  alarmclock: >-
    {{'mdi:alarm-off' if is_state('sensor.next_alarm','Not set') else 'mdi:alarm'}}

#active_tab_color: black
active_tab_css: 'background-color: rgba(0, 0, 0, 0.3);'
tab_indicator_color: black
tabs_color:
  alarm: >-
    {{states('sensor.alarm_panel_icon_color')}}
  phones_tablets: >-
    {{state_attr('sensor.family_home','icon_color')}}
  alarmclock: >-
    {{'green' if is_state('sensor.next_alarm','Not set') else 'red'}}

package:

homeassistant:
  customize_glob:
    input_boolean.ch_*:
      templates:
        icon_color: >
          if (state === 'on') return 'green';
          return 'grey';

  customize:
    input_boolean.ch_disabled_mode:
      templates:
        icon: >
          if (state === 'on') return 'mdi:death-star-variant';
          return 'mdi:death-star';
        icon_color: >
          if (state === 'on') return 'red';
          return 'green';

##########################################################################################
# Inputs
##########################################################################################

input_boolean:
  ch_disabled_mode:
    name: Disabled mode

  ch_use_options_text_template:
    name: Use options text template
    icon: mdi:code-braces

  ch_use_header_text_template:
    name: Use header text template
    icon: mdi:code-braces

#  ch_kiosk_mode:
#    name: Ch Kiosk mode
#    icon: mdi:overscan

  ch_compact_mode:
    name: Compact mode
    icon: mdi:resize

  ch_disable_sidebar:
    name: Disable sidebar
    icon: mdi:dock-left

  ch_menu_dropdown:
    name: Menu dropdown
    icon: mdi:menu

  ch_voice_dropdown:
    name: Voice dropdown
    icon: mdi:microphone

  ch_reverse_tab_direction:
    name: Reverse tab direction
    icon: mdi:arrow-left-right-bold

  ch_hidden_tab_redirect:
    name: Hidden tab redirect
    icon: mdi:directions

  ch_reverse_button_direction:
    name: Reverse button direction
    icon: mdi:arrow-left-right-bold

  ch_footer_mode:
    name: Footer mode
    icon: mdi:arrow-down-bold-box

  ch_split_mode:
    name: Split mode
    icon: mdi:page-layout-header-footer

  ch_chevrons:
    name: Chevrons
    icon: mdi:chevron-right-box-outline

  ch_shadow:
    name: Shadow
    icon: mdi:text-shadow

  ch_indicator_top:
    name: Indicator top
    icon: mdi:format-vertical-align-top

  ch_hide_header:
    name: Hide header
    icon: mdi:format-header-1

  ch_hide_help:
    name: Hide help
    icon: mdi:help

  ch_hide_unused:
    name: Hide unused
    icon: mdi:block-helper

  ch_hide_refresh:
    name: Hide refresh
    icon: mdi:refresh

  ch_hide_config:
    name: Hide config
    icon: mdi:settings-helper

  ch_hide_raw:
    name: Hide raw
    icon: mdi:code-braces-box

  ch_menu_hide:
    name: Menu hide
    icon: mdi:menu

  ch_voice_hide:
    name: Voice hide
    icon: mdi:microphone

  ch_options_hide:
    name: Options hide
    icon: mdi:apple-keyboard-option

#  ch_icon_changes:
#    name: Ch icon change demo
#    icon: mdi:emoticon-poop
#
#  ch_text_changes:
#    name: Ch button text demo
#    initial: off
#    icon: mdi:alphabetical

lovelace card:

  - type: entities
    show_header_toggle: false
    title: Custom header settings
    entities:
      - input_boolean.ch_disabled_mode
      - input_boolean.ch_compact_mode
      - input_boolean.ch_footer_mode
      - input_boolean.ch_split_mode
      - input_boolean.ch_chevrons
      - input_boolean.ch_shadow
      - input_boolean.ch_indicator_top
      - input_boolean.ch_use_options_text_template
      - input_boolean.ch_use_header_text_template
      - input_boolean.ch_hidden_tab_redirect
      - type: divider
      - input_boolean.ch_reverse_tab_direction
      - input_boolean.ch_reverse_button_direction
      - input_boolean.ch_disable_sidebar
      - input_boolean.ch_menu_dropdown
      - input_boolean.ch_voice_dropdown
      - type: divider
      - input_boolean.ch_hide_header
      - input_boolean.ch_hide_help
      - input_boolean.ch_hide_unused
      - input_boolean.ch_hide_refresh
      - input_boolean.ch_hide_config
      - input_boolean.ch_hide_raw
      - type: divider
      - input_boolean.ch_menu_hide
      - input_boolean.ch_voice_hide
      - input_boolean.ch_options_hide

will customize some icons based on state, but this does it for now ;-

2 Likes

Hey Ryan,

didn’t really notice the test_template functionality before, but this is a marvelous tool! So much, I would like to ask if you couldn’t create a small dedicated card for that, so we can test our templates outside of the inspector.

I ask, because I’ve been struggling with these newlines mostly in my messaging and notification templates, which can be a real pain to format, when using templates and passing variables. The template editor isn’t really of much use in that case, because it doesn’t show the newlines like your test_template does.

Having a dedicated card for the frontend would be a real treat indeed, so hope you would consider…

edit

now that I asked for a special card above, I’d love to add the same request for the marquee. There has been only 1 marquee card, and that is now deprecated. Seeing how the Custom header allows for both a vertical and horizontal marquee, my hopes are up this could be achieved in a dedicated card also… Would you consider creating that, based on what now is done in CH #fingerscrossed

thanks!

update this snapped in today: Finally made my first marquee (on a custom: button-card) which suffices for now in the marquee.

Please, read the first post in this thread. It links to the issues section of the docs that explains what info I would need to help you.

I’m mostly interested in errors either in HA logs or the browsers dev console, but anything more than the fact that it isn’t working is helpful.

have a related issue:

show_tabs: >
  {% if not is_state('input_select.mode','Developer') %}0 to 21, 26, 28
  {% else %} 0 to 28
  {% endif %}

won’t show me tab 28. 0 to 21 and 26 show fine. Doesn’t mater if I use

show_tabs: >
  {% if not is_state('input_select.mode','Developer') %}0 to 21,26,28
  {% else %} 0 to 28
  {% endif %}

also, the else clause kicks in as the template prescribes, showing all tabs

leaving that out:

  {% if not is_state('input_select.mode','Developer') %}0 to 21,26,28{% endif %}

makes no difference in behavior (though I still don’t like if’s without else’s…)
maybe you could introduce ‘all’ and ‘none’ so we can use that in the templates?

edit

after some further experimenting even reverting to my original 0 to 21, 26 didn’t work any longer… tested it in the test_template (great tool!) and found it returned Custom Header test returned: "0 to 21, 26 "

darned whitespace…

show_tabs: >-
  {% if not is_state('input_select.mode','Developer') %}0 to 21, 26, 28
  {% else %} 0 to 28
  {% endif %}

does the trick again!

Have you tried that in the test_template:?

sorry, crossposted… yes! see above.

1 Like

Yup you beat me to it. Also, your else statement has a space before it resulting in " 0 to 28". This wouldn’t be a problem with something like hide tabs as I strip spaces in that case, but in other options it might.

I don’t think I’d introduce something like this as it’s already handled by not using an else statement, but I did see your mention of this behavior not working with header text and am looking into it.

Edit: Actually thinking of it a bit more, something like ‘all’ and ‘none’ might be helpful even outside of templates. That way the behavior would stay the same even when you add or remove views. I’ll add it to the growing list :slight_smile:

it is still a mystery sometimes why things work or don’t work.

test_template: >-
  {% if not is_state('input_select.mode','Developer') %}0 to 21, 26, 28
  {% else %} 0 to 28
  {% endif %}

has this as output:

and works just fine…in both cases of the template

show_tabs: >-
  {% if not is_state('input_select.mode','Developer') %}0 to 21, 26, 28
  {% else %} 0 to 28
  {% endif %}

or is the >- taking care of the white spaces even the test_template shows?

The white space in this case with " 0 to 28 " as mentioned above is actually handled by Custom Header. With hide tabs and show tabs it is necessary for me to strip the white space, so CH just sees “0to28” the problem was when you didn’t use >- and just used >. In that case it was rendering as "0 to 21, 26, 28 n" the “n” being the new line that wasn’t stripped.

Other options won’t handle that white space as well.

1 Like

Pre-Release 1.1.9

This one is marked as a pre-release since I’ve now got babel converting everything (need to “show beta” in HACS to install). I have tested to the best of my ability, but this has the potential to cause some issues. If you’re having issues then report the issue and downgrade if necessary.

  • Use Babel to hopefully support some of the less common browsers
  • Fix button text justification
  • Fix for view names containing the letters “to” being detected as a range
  • Fix for boolean reporting in test_template:
  • Fix for notification dot color
  • Fix for cards overlapping in split mode and footer mode

I’ve got a (hopefully easy) question about using multiple templates in the “show_tabs” & “hide_tabs” options.

right now I’ve got a hide_tabs set up that hides only one tab dependent on the state of a switch:

hide_tabs: '{% if states.switch.debug_view.state == "off" %}Debug{% endif %}'

I just added some tabs that I only want to show to a specific user (I think I can get that part working) but I want to also hide it from my own frontend views unless I turn on another switch.

how would I format the hide_tabs: above to add the second template to only show the views if the switch is on.

can I do this:

hide_tabs: 
  - '{% if states.switch.debug_view.state == "off" %}Debug{% endif %}'
  - '{% if states.switch.other_switch.state == "off" %}other tabs{% endif %}'

it definitely doesn’t look right.

Or do I have to template the whole thing out in one big template using if/else, and/or?

Might something like this work?

hide_tabs: >-
  {{ 'Debug' if states.switch.debug_view.state == "off" else '' }}
  {{ 'other tabs' if states.switch.other_switch.state == "off" else '' }}

Edit: realised you’d probably also need another test in between those two to add a comma if both switches are off

1 Like

Yeah, I was just testing it before your last edit and realized the same thing. But it ended up being even easier than that.

It looks like having the commas+spaces at the end of the list is still OK.

Here’s what I came up with that worked:

hide_tabs: >-
    {{ 'Debug, ' if states.switch.debug_view.state == "off" else '' }}{{ 'view_1, view_2, view_3' if states.input_boolean.show_kids_views.state == "off" else '' }}

If in future you want more granular control (e.g more switches for individual views) something like this would also work and would probably be easier to maintain (it basically builds up a list of the tabs to hide and then joins the list using commas):

hide_tabs: >-
  {%- set tabs = [] -%}
  {%- if states.switch.debug_view.state == "off" -%}{%- set tabs = tabs + ['Debug'] -%}{%- endif -%}
  {%- if states.switch.other_switch.state == "off" -%}{%- set tabs = tabs + ['other tabs'] -%}{%- endif -%}
  {{ tabs | join(',') }}
2 Likes

Thanks, I’ll keep that handy for later.

Quick question. Regarding the User Agent entry. Is there a way that you could just declare any/all windows devices? Instead of having to declare something like “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0” just for Firefox alone? Because since I just updated Firefox, it went from 71.0 to 72.0, and I had to update all exceptions I had made. If possible, I’d rather future proof it and have just “if windows”. Because I have a different Home Screen for my family members and I, based on whether you’re on the computer, or on a phone.

Thank you in advanced, for whoever helps answer this question.