I’m not completely finished with these room cards yet – haven’t set up navigation or popups. There is a ton of logic that I’ve “stolen”, mostly from the card-mod pages – but I’m pretty dense when it comes to css navigation. Theme is Material You (thank you for that!), Background is from Frosted Glass
- Dimmed rooms are unoccupied
- Purple bar does follow the theme colorings
- TBD: alternative color main icon and maybe feature row when the room is set to sleep mode (from adaptive lighting)
- Lightbulb does work, color/background changes with the rgbvalues of the bulb as is default with a tile button. Long press turns it off and on, single tap brings up more-info – for now.
- SubButtons are reverse-row, and go in an order that makes sense to me.
- SubButtons hide when they are off/inactive.
- I’m a huge fan of bias lighting, so when the light syncs are active those buttons turn mediaplayer blue to indicate they are in sync mode.
- The motion and presence detectors (really it’s the default color I guess) is var(–warning-color); all other button colors are some sort of state color depending on the entity.
home.yaml – only including 1 room to cut down on length
- type: grid
column_span: 1
cards:
- type: custom:bubble-card
card_type: separator
name: Rooms Overview
modules:
# - "!default"
- "!home-assistant-default"
- type: custom:streamline-card
template: roomsum_tile
grid_options:
columns: 6
rows: 2
variables:
area: office
entity1: fan.z_wave_outlet_attic
entity1_icon: mdi:fan
entity2: light.hue_play_monitor_backlight_office
entity2_icon: hue:lightstrip-tv
entity3: binary_sensor.helper_pc_presence_office
entity3_icon: hue:room-computer
entity4: binary_sensor.helper_group_office_motion_sensors
entity4_icon: mdi:motion-sensor
roomsum_tile.yaml (using streamline-card, successorish to decluttering card)
roomsum_tile:
default:
- entity1: input_boolean.dashboard_placeholder
- entity1_icon: mdi:flask-empty-outline
- entity2: input_boolean.dashboard_placeholder
- entity2_icon: mdi:flask-empty-outline
- entity3: input_boolean.dashboard_placeholder
- entity3_icon: mdi:flask-empty-outline
- entity4: input_boolean.dashboard_placeholder
- entity4_icon: mdi:flask-empty-outline
card:
type: custom:mod-card
card_mod:
style:
hui-horizontal-stack-card:
$: |
div#root {
display: grid;
}
div#root > * {
grid-column-start: 1;
grid-row-start: 1;
display: block !important;
}
div#root > *:nth-child(2) > :first-child {
--ha-card-border-width: 0px;
--ha-card-background: rgba(0,0,0,0.0);
width: calc(36px + 2 * 10px);
display: block;
margin-left: auto;
}
.: |
ha-card {
border: none;
height: calc((var(--row-size, 1) * (var(--row-height) + var(--row-gap))) - var(--row-gap));
}
card:
type: horizontal-stack
cards:
- type: area
area: '[[area]]'
display_type: compact
alert_classes: []
sensor_classes:
- temperature
- humidity
features_position: bottom
features:
- type: custom:service-call
entries:
- type: button
entity_id: '[[entity1]]'
icon: '[[entity1_icon]]'
autofill_entity_id: true
hold_action:
action: toggle
target:
entity_id: "{{ config.entity }}"
data: {}
haptics: true
styles: !include roomsum_feature_style.yaml
- type: button
entity_id: '[[entity2]]'
icon: '[[entity2_icon]]'
autofill_entity_id: true
hold_action:
action: toggle
target:
entity_id: "{{ config.entity }}"
data: {}
haptics: true
styles: !include roomsum_feature_style.yaml
- type: button
entity_id: '[[entity3]]'
icon: '[[entity3_icon]]'
autofill_entity_id: true
hold_action:
action: toggle
target:
entity_id: "{{ config.entity }}"
data: {}
haptics: true
styles: !include roomsum_feature_style.yaml
- type: button
entity_id: '[[entity4]]'
icon: '[[entity4_icon]]'
autofill_entity_id: true
hold_action:
action: toggle
target:
entity_id: "{{ config.entity }}"
data: {}
haptics: true
styles: !include roomsum_feature_style.yaml
styles: |-
:host {
--feature-height: 32px;
--mdc-icon-size: 18px;
--feature-button-spacing: 8px;
}
.row {
justify-content: end;
flex-flow: row-reverse;
}
card_mod:
style:
ha-tile-info $: |
.primary {
font-size: var(--ha-font-size-l) !important;
white-space: unset;
{% if is_state('binary_sensor.helper_occupancy_[[area]]','off') %}
color: var(--disabled-text-color) !important;
{% endif %}
}
@media (max-width: 800px) {
.primary {
font-size: var(--ha-font-size-m) !important;
max-width: 65px !important;
}
}
ha-tile-icon $: |
.container {
--mdc-icon-size: 30px !important;
height: 48px !important;
width: 48px !important;
border-radius: 24px !important;
margin: -9px;
{% if is_state('binary_sensor.helper_occupancy_[[area]]','on') %}
--tile-icon-color: var(--state-active-color);
{% else %}
--tile-icon-color: var(--state-inactive-color);
{% endif %}
}
.: |
.container > hui-card-features {
min-height: 44px;
padding: 6px;
border-radius: var(--ha-card-border-radius, 12px);
box-shadow: var(--ha-card-box-shadow);
{% if is_state('binary_sensor.helper_occupancy_[[area]]','on') %}
background: rgba(from var(--secondary-background-color) r g b / .5);
{% else %}
background: var(--primary-background-color);
{% endif %}
}
- type: tile
entity: light.helper_group_[[area]]
visibility:
- condition: state
entity: light.helper_group_[[area]]
state_not: unknown
name: " "
icon: mdi:lightbulb
icon_tap_action:
action: more-info
icon_hold_action:
action: toggle
card_mod:
style:
ha-tile-info $: |
.info .secondary {
display: none !important;
}
ha-tile-icon $: |
.container {
--mdc-icon-size: 30px !important;
height: 48px !important;
width: 48px !important;
border-radius: 24px !important;
}
.: |
mwc-ripple {
display: none;
}
ha-card .container .content {
justify-content: center;
}
ha-card {
height: calc((var(--row-size, 1) * (var(--row-height) + var(--row-gap))) - var(--row-gap) - 50px) !important;
margin: -3px;
box-shadow: none;
--ha-ripple-color: none !important;
}
The random include the style key made getting the backgrounds and settings for all 4 badges so much easier – as much trial and error I was doing, I’m happy I found a way to only do it once.
roomsum_feature_style.yaml
|
:host {
flex-basis: 22.5%;
{% if is_state(config.entity,'off') %}
display: none;
{% endif %}
}
.background {
opacity: .5;
}
{% if config.entity is match('light.hue_play_') and is_state('binary_sensor.helper_hue_sync_[[area]]', 'on') %}
.background {
background: var(--state-media_player-active-color);
}
{% elif config.entity is match('light') %}
.background {
background: rgb({{ state_attr(config.entity,'rgb_color') -}});
}
{% elif config.entity is match('remote') %}
.background {
background: var(--state-media_player-active-color);
}
{% elif config.entity is match('fan') %}
.background {
background: var(--state-fan-active-color);
}
.icon {
animation: spin 1s linear infinite;
}
{% else %}
.background {
background: var(--warning-color);
}
{% endif %}
@keyframes spin {
100% {
transform: rotate(360deg)
}
}
Initially I had something different for the light.hue_play/sync detection.
{% if config.entity is match('light.hue_play_') and is_state((area_entities(area_id(config.entity)) | select('match','switch.hue_sync') | first), 'on') %}
Which did work, but the frontend was not aware that those entities were set to 'living_room" when the device was set to ‘infrastructure’ – so it refused to find the sensor. 1 room worked because that room has it’s own bridge, but not the other. Even creating a helper for that room with the correct area label didn’t work. The current code simplifies by just calling the helper sensors directly; I’m sure skipping the area_entities(area_id(config.entity)) is less compute anyways.