diff --git a/main.yaml b/main.yaml index 57bfa67..b0f5081 100644 --- a/main.yaml +++ b/main.yaml @@ -5157,6 +5157,1214 @@ views: /* 当前子卡片与其他子卡片的间距 */ margin: 6px 2px !important; } + - type: custom:mushroom-chips-card + chips: + - type: template + entity: fan.xiaomi_cn_2196552583_p90_s_2_fan + icon: mdi:minus + tap_action: + action: perform-action + perform_action: fan.decrease_speed + target: + entity_id: fan.xiaomi_cn_2196552583_p90_s_2_fan + data: + percentage_step: 5 + alignment: end + card_mod: + style: > + ha-card { + /* ================================ */ + /* USER CONFIG HERE */ + /* ================================ */ + + /* 1. ACTIVE STATES */ + {% set active_states = ['on'] %} + + /* 2. POSITIONING */ + {% set pos_y = 'bottom' %} + {% set pos_y_val = '15px' %} + {% set pos_x = 'right' %} + {% set pos_x_val = '85px' %} + + /* 3. SIZING */ + {% set icon_size = '32px' %} + {% set text_size = '13px' %} + {% set badge_height = '10px' %} + {% set border_radius = '5px' %} + {% set border_thickness = '0px' %} + + /* 4. COLORS (HEX, RGB, Color Name) */ + /* --- Active --- */ + {% set active_bg = 'rgba(66, 165, 245, 0.3)' %} + {% set active_icon = 'rgb(144, 202, 249)' %} + {% set active_text = 'white' %} + {% set active_border = 'white' %} + {% set active_opacity = 0.3 %} + + /* --- Inactive --- */ + {% set inactive_bg = 'grey' %} + {% set inactive_icon = 'grey' %} + {% set inactive_text = 'darkgrey' %} + {% set inactive_border = 'transparent' %} + {% set inactive_opacity = 0.3 %} + + + /* 5. ANIMATIONS */ + /* Options: pulse, shake, wobble */ + /* flash, heartbeat, swing, vibrate */ + + {% set anim_type = 'none' %} + + /* true = 24/7, false = only when active */ + {% set always_animate = false %} + + {% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */ + {% set anim_duration_sec = 1 %} + {% set anim_delay_sec = 1 %} + + /* ================================== */ + /* USER CONFIG END (DONT TOUCH BELOW) */ + /* ================================== */ + + {% set current_state = states(config.chips[0].entity) %} + {% set is_active = current_state in active_states %} + + {% if is_active %} + {% set current_bg = active_bg %} + {% set current_icon = active_icon %} + {% set current_text = active_text %} + {% set current_border = active_border %} + {% set current_op = active_opacity %} + {% set current_anim = anim_type %} + {% else %} + {% set current_bg = inactive_bg %} + {% set current_icon = inactive_icon %} + {% set current_text = inactive_text %} + {% set current_border = inactive_border %} + {% set current_op = inactive_opacity %} + {% set current_anim = anim_type if always_animate else 'none' %} + {% endif %} + + {% set master_cycle = anim_duration_sec + anim_delay_sec %} + {% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %} + {% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %} + + --chip-padding: {{ badge_height }}; + --chip-border-radius: {{ border_radius }}; + + --chip-border-width: 0px !important; + --ha-card-border-width: 0px !important; + + --chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important; + + --text-color: {{ current_icon }} !important; + --color: {{ current_icon }} !important; + --chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important; + --chip-font-size: {{ text_size }} !important; + --chip-icon-size: {{ icon_size }} !important; + --mdc-icon-size: {{ icon_size }} !important; + --chip-height: auto !important; + --primary-text-color: {{ current_text }} !important; + --secondary-text-color: {{ current_text }} !important; + + position: absolute !important; + {{ pos_y }}: {{ pos_y_val }}; + {{ pos_x }}: {{ pos_x_val }}; + z-index: 1; + border: none !important; + border-radius: {{ border_radius }} !important; + box-shadow: 0 4px 6px rgba(0,0,0,0.2); + overflow: visible !important; + will-change: transform; + + {% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %} + animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear; + {% endif %} + } + + + ha-state-icon, ha-icon { + display: flex; + align-items: center; + justify-content: center; + width: {{ icon_size }} !important; + height: {{ icon_size }} !important; + } + + + {% if config.chips[0].content is not defined or + config.chips[0].content | length == 0 %} + ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; } + .content { display: none; } + {% else %} + ha-card { padding: 0 10px !important; } + .content { padding-left: 5px; font-weight: bold; } + {% endif %} + + + {% if current_anim != 'none' and iterations > 0 and + master_cycle > 0 %} + + @keyframes anim-{{ config.chips[0].entity | replace('.', + '-') }}-{{ anim_type }} { + {% for i in range(iterations) %} + {% set t = i * step_percent %} + + {% if anim_type == 'pulse' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'shake' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); } + {{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'flash' %} + {{ t + 0 }}% { opacity: 1; } + {{ t + (step_percent * 0.5) }}% { opacity: 0; } + {{ t + step_percent }}% { opacity: 1; } + + {% elif anim_type == 'wobble' %} + {{ t + 0 }}% { transform: translate3d(0%, 0, 0); } + {{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); } + {{ t + step_percent }}% { transform: translate3d(0%, 0, 0); } + + {% elif anim_type == 'heartbeat' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'swing' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); } + {{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'vibrate' %} + {{ t + 0 }}% { transform: translate3d(0, 0, 0); } + {{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); } + {{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); } + {{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); } + {{ t + step_percent }}% { transform: translate3d(0, 0, 0); } + + {% endif %} + {% endfor %} + } + + {% endif %} + - type: custom:mushroom-chips-card + chips: + - type: template + entity: fan.xiaomi_cn_2196552583_p90_s_2_fan + icon: mdi:plus + tap_action: + action: perform-action + perform_action: fan.increase_speed + target: + entity_id: fan.xiaomi_cn_2196552583_p90_s_2_fan + data: + percentage_step: 5 + alignment: end + card_mod: + style: > + ha-card { + /* ================================ */ + /* USER CONFIG HERE */ + /* ================================ */ + + /* 1. ACTIVE STATES */ + {% set active_states = ['on'] %} + + /* 2. POSITIONING */ + {% set pos_y = 'bottom' %} + {% set pos_y_val = '15px' %} + {% set pos_x = 'right' %} + {% set pos_x_val = '15px' %} + + /* 3. SIZING */ + {% set icon_size = '32px' %} + {% set text_size = '13px' %} + {% set badge_height = '10px' %} + {% set border_radius = '5px' %} + {% set border_thickness = '0px' %} + + /* 4. COLORS (HEX, RGB, Color Name) */ + /* --- Active --- */ + {% set active_bg = 'rgba(255, 167, 38, 0.3)' %} + {% set active_icon = 'rgb(255, 204, 128)' %} + {% set active_text = 'white' %} + {% set active_border = 'white' %} + {% set active_opacity = 0.3 %} + + /* --- Inactive --- */ + {% set inactive_bg = 'grey' %} + {% set inactive_icon = 'grey' %} + {% set inactive_text = 'darkgrey' %} + {% set inactive_border = 'transparent' %} + {% set inactive_opacity = 0.3 %} + + + /* 5. ANIMATIONS */ + /* Options: pulse, shake, wobble */ + /* flash, heartbeat, swing, vibrate */ + + {% set anim_type = 'none' %} + + /* true = 24/7, false = only when active */ + {% set always_animate = false %} + + {% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */ + {% set anim_duration_sec = 1 %} + {% set anim_delay_sec = 1 %} + + /* ================================== */ + /* USER CONFIG END (DONT TOUCH BELOW) */ + /* ================================== */ + + {% set current_state = states(config.chips[0].entity) %} + {% set is_active = current_state in active_states %} + + {% if is_active %} + {% set current_bg = active_bg %} + {% set current_icon = active_icon %} + {% set current_text = active_text %} + {% set current_border = active_border %} + {% set current_op = active_opacity %} + {% set current_anim = anim_type %} + {% else %} + {% set current_bg = inactive_bg %} + {% set current_icon = inactive_icon %} + {% set current_text = inactive_text %} + {% set current_border = inactive_border %} + {% set current_op = inactive_opacity %} + {% set current_anim = anim_type if always_animate else 'none' %} + {% endif %} + + {% set master_cycle = anim_duration_sec + anim_delay_sec %} + {% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %} + {% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %} + + --chip-padding: {{ badge_height }}; + --chip-border-radius: {{ border_radius }}; + + --chip-border-width: 0px !important; + --ha-card-border-width: 0px !important; + + --chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important; + + --text-color: {{ current_icon }} !important; + --color: {{ current_icon }} !important; + --chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important; + --chip-font-size: {{ text_size }} !important; + --chip-icon-size: {{ icon_size }} !important; + --mdc-icon-size: {{ icon_size }} !important; + --chip-height: auto !important; + --primary-text-color: {{ current_text }} !important; + --secondary-text-color: {{ current_text }} !important; + + position: absolute !important; + {{ pos_y }}: {{ pos_y_val }}; + {{ pos_x }}: {{ pos_x_val }}; + z-index: 1; + border: none !important; + border-radius: {{ border_radius }} !important; + box-shadow: 0 4px 6px rgba(0,0,0,0.2); + overflow: visible !important; + will-change: transform; + + {% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %} + animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear; + {% endif %} + } + + + ha-state-icon, ha-icon { + display: flex; + align-items: center; + justify-content: center; + width: {{ icon_size }} !important; + height: {{ icon_size }} !important; + } + + + {% if config.chips[0].content is not defined or + config.chips[0].content | length == 0 %} + ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; } + .content { display: none; } + {% else %} + ha-card { padding: 0 10px !important; } + .content { padding-left: 5px; font-weight: bold; } + {% endif %} + + + {% if current_anim != 'none' and iterations > 0 and + master_cycle > 0 %} + + @keyframes anim-{{ config.chips[0].entity | replace('.', + '-') }}-{{ anim_type }} { + {% for i in range(iterations) %} + {% set t = i * step_percent %} + + {% if anim_type == 'pulse' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'shake' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); } + {{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'flash' %} + {{ t + 0 }}% { opacity: 1; } + {{ t + (step_percent * 0.5) }}% { opacity: 0; } + {{ t + step_percent }}% { opacity: 1; } + + {% elif anim_type == 'wobble' %} + {{ t + 0 }}% { transform: translate3d(0%, 0, 0); } + {{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); } + {{ t + step_percent }}% { transform: translate3d(0%, 0, 0); } + + {% elif anim_type == 'heartbeat' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'swing' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); } + {{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'vibrate' %} + {{ t + 0 }}% { transform: translate3d(0, 0, 0); } + {{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); } + {{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); } + {{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); } + {{ t + step_percent }}% { transform: translate3d(0, 0, 0); } + + {% endif %} + {% endfor %} + } + + {% endif %} + - type: custom:mushroom-chips-card + chips: + - type: template + entity: fan.xiaomi_cn_2196552583_p90_s_2_fan + content: >- + {% set speed = state_attr(entity, 'percentage') %} {{ + speed | int(0) }}% + alignment: end + card_mod: + style: > + ha-card { + /* ================================== */ + /* USER CONFIG HERE */ + /* ================================== */ + + /* 1. ACTIVE STATE (NUMERIC) */ + {% set threshold_below = 20 %} + {% set threshold_above = false %} + + /* 2. POSITIONING */ + {% set pos_y = 'bottom' %} + {% set pos_y_val = '22px' %} + {% set pos_x = 'left' %} + {% set pos_x_val = '140px' %} + + /* 3. SIZING */ + {% set icon_size = '18px' %} + {% set text_size = '35px' %} + {% set badge_height = '5px' %} + {% set border_radius = '8px' %} + {% set border_thickness = '1px' %} + + /* 4. COLORS (HEX, RGB, Color Name) */ + /* --- Active --- */ + {% set active_bg = '#a63a3a' %} + {% set active_icon = 'white' %} + {% set active_text = 'white' %} + {% set active_border = '#ab1c1c' %} + {% set active_opacity = 0.3 %} + + /* --- Inactive --- */ + {% set inactive_bg = 'rgba(255, 167, 38, 0)' %} + {% set inactive_icon = 'grey' %} + {% set inactive_text = 'darkgrey' %} + {% set inactive_border = 'transparent' %} + {% set inactive_opacity = 0.3 %} + + /* 5. ANIMATIONS */ + /* Options: pulse, shake, wobble */ + /* flash, heartbeat, swing, vibrate */ + + {% set anim_type = 'none' %} + + /* true = 24/7, false = only when active */ + {% set always_animate = false %} + + {% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */ + {% set anim_duration_sec = 2 %} + {% set anim_delay_sec = 5 %} + + /* ================================== */ + /* USER CONFIG END (DONT TOUCH BELOW) */ + /* ================================== */ + + {% set current_state = states(config.chips[0].entity) %} + {% set state_num = current_state | float(-99999) %} + + {% set check_below = threshold_below | string | lower != 'false' %} + {% set check_above = threshold_above | string | lower != 'false' %} + + {% set is_active_below = check_below and state_num != -99999 and state_num <= (threshold_below | float(-99999)) %} + {% set is_active_above = check_above and state_num != -99999 and state_num >= (threshold_above | float(-99999)) %} + + {% set is_active = is_active_below or is_active_above %} + + {% if is_active %} + {% set current_bg = active_bg %} + {% set current_icon = active_icon %} + {% set current_text = active_text %} + {% set current_border = active_border %} + {% set current_op = active_opacity %} + {% set current_anim = anim_type %} + {% else %} + {% set current_bg = inactive_bg %} + {% set current_icon = inactive_icon %} + {% set current_text = inactive_text %} + {% set current_border = inactive_border %} + {% set current_op = inactive_opacity %} + {% set current_anim = anim_type if always_animate else 'none' %} + {% endif %} + + {% set master_cycle = anim_duration_sec + anim_delay_sec %} + {% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %} + {% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %} + + --chip-padding: {{ badge_height }}; + --chip-border-radius: {{ border_radius }}; + + --chip-border-width: 0px !important; + --ha-card-border-width: 0px !important; + + --chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important; + + --text-color: {{ current_icon }} !important; + --color: {{ current_icon }} !important; + --chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important; + --chip-font-size: {{ text_size }} !important; + --chip-icon-size: {{ icon_size }} !important; + --mdc-icon-size: {{ icon_size }} !important; + --chip-height: auto !important; + --primary-text-color: {{ current_text }} !important; + --secondary-text-color: {{ current_text }} !important; + + position: absolute !important; + {{ pos_y }}: {{ pos_y_val }}; + {{ pos_x }}: {{ pos_x_val }}; + z-index: 1; + border: none !important; + border-radius: {{ border_radius }} !important; + box-shadow: 0 4px 6px rgba(0,0,0,0.2); + overflow: visible !important; + will-change: transform; + + {% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %} + animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear; + {% endif %} + } + + + ha-state-icon, ha-icon { + display: flex; + align-items: center; + justify-content: center; + width: {{ icon_size }} !important; + height: {{ icon_size }} !important; + } + + + {% if config.chips[0].content is not defined or + config.chips[0].content | length == 0 %} + ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; } + .content { display: none; } + {% else %} + ha-card { padding: 0 10px !important; } + .content { padding-left: 5px; font-weight: bold; } + {% endif %} + + + {% if current_anim != 'none' and iterations > 0 and + master_cycle > 0 %} + + @keyframes anim-{{ config.chips[0].entity | replace('.', + '-') }}-{{ anim_type }} { + {% for i in range(iterations) %} + {% set t = i * step_percent %} + + {% if anim_type == 'pulse' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'shake' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); } + {{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'flash' %} + {{ t + 0 }}% { opacity: 1; } + {{ t + (step_percent * 0.5) }}% { opacity: 0; } + {{ t + step_percent }}% { opacity: 1; } + + {% elif anim_type == 'wobble' %} + {{ t + 0 }}% { transform: translate3d(0%, 0, 0); } + {{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); } + {{ t + step_percent }}% { transform: translate3d(0%, 0, 0); } + + {% elif anim_type == 'heartbeat' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'swing' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); } + {{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'vibrate' %} + {{ t + 0 }}% { transform: translate3d(0, 0, 0); } + {{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); } + {{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); } + {{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); } + {{ t + step_percent }}% { transform: translate3d(0, 0, 0); } + + {% endif %} + {% endfor %} + } + + {% endif %} + - type: custom:mushroom-chips-card + chips: + - type: template + entity: fan.shhf_cn_1129134246_sflt11_s_11_fan + icon: mdi:minus + tap_action: + action: perform-action + perform_action: fan.decrease_speed + target: + entity_id: fan.shhf_cn_1129134246_sflt11_s_11_fan + alignment: end + card_mod: + style: > + ha-card { + /* ================================ */ + /* USER CONFIG HERE */ + /* ================================ */ + + /* 1. ACTIVE STATES */ + {% set active_states = ['on'] %} + + /* 2. POSITIONING */ + {% set pos_y = 'top' %} + {% set pos_y_val = '15px' %} + {% set pos_x = 'right' %} + {% set pos_x_val = '85px' %} + + /* 3. SIZING */ + {% set icon_size = '32px' %} + {% set text_size = '13px' %} + {% set badge_height = '10px' %} + {% set border_radius = '5px' %} + {% set border_thickness = '0px' %} + + /* 4. COLORS (HEX, RGB, Color Name) */ + /* --- Active --- */ + {% set active_bg = 'rgba(66, 165, 245, 0.3)' %} + {% set active_icon = 'rgb(144, 202, 249)' %} + {% set active_text = 'white' %} + {% set active_border = 'white' %} + {% set active_opacity = 0.3 %} + + /* --- Inactive --- */ + {% set inactive_bg = 'grey' %} + {% set inactive_icon = 'grey' %} + {% set inactive_text = 'darkgrey' %} + {% set inactive_border = 'transparent' %} + {% set inactive_opacity = 0.3 %} + + + /* 5. ANIMATIONS */ + /* Options: pulse, shake, wobble */ + /* flash, heartbeat, swing, vibrate */ + + {% set anim_type = 'none' %} + + /* true = 24/7, false = only when active */ + {% set always_animate = false %} + + {% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */ + {% set anim_duration_sec = 1 %} + {% set anim_delay_sec = 1 %} + + /* ================================== */ + /* USER CONFIG END (DONT TOUCH BELOW) */ + /* ================================== */ + + {% set current_state = states(config.chips[0].entity) %} + {% set is_active = current_state in active_states %} + + {% if is_active %} + {% set current_bg = active_bg %} + {% set current_icon = active_icon %} + {% set current_text = active_text %} + {% set current_border = active_border %} + {% set current_op = active_opacity %} + {% set current_anim = anim_type %} + {% else %} + {% set current_bg = inactive_bg %} + {% set current_icon = inactive_icon %} + {% set current_text = inactive_text %} + {% set current_border = inactive_border %} + {% set current_op = inactive_opacity %} + {% set current_anim = anim_type if always_animate else 'none' %} + {% endif %} + + {% set master_cycle = anim_duration_sec + anim_delay_sec %} + {% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %} + {% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %} + + --chip-padding: {{ badge_height }}; + --chip-border-radius: {{ border_radius }}; + + --chip-border-width: 0px !important; + --ha-card-border-width: 0px !important; + + --chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important; + + --text-color: {{ current_icon }} !important; + --color: {{ current_icon }} !important; + --chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important; + --chip-font-size: {{ text_size }} !important; + --chip-icon-size: {{ icon_size }} !important; + --mdc-icon-size: {{ icon_size }} !important; + --chip-height: auto !important; + --primary-text-color: {{ current_text }} !important; + --secondary-text-color: {{ current_text }} !important; + + position: absolute !important; + {{ pos_y }}: {{ pos_y_val }}; + {{ pos_x }}: {{ pos_x_val }}; + z-index: 1; + border: none !important; + border-radius: {{ border_radius }} !important; + box-shadow: 0 4px 6px rgba(0,0,0,0.2); + overflow: visible !important; + will-change: transform; + + {% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %} + animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear; + {% endif %} + } + + + ha-state-icon, ha-icon { + display: flex; + align-items: center; + justify-content: center; + width: {{ icon_size }} !important; + height: {{ icon_size }} !important; + } + + + {% if config.chips[0].content is not defined or + config.chips[0].content | length == 0 %} + ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; } + .content { display: none; } + {% else %} + ha-card { padding: 0 10px !important; } + .content { padding-left: 5px; font-weight: bold; } + {% endif %} + + + {% if current_anim != 'none' and iterations > 0 and + master_cycle > 0 %} + + @keyframes anim-{{ config.chips[0].entity | replace('.', + '-') }}-{{ anim_type }} { + {% for i in range(iterations) %} + {% set t = i * step_percent %} + + {% if anim_type == 'pulse' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'shake' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); } + {{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'flash' %} + {{ t + 0 }}% { opacity: 1; } + {{ t + (step_percent * 0.5) }}% { opacity: 0; } + {{ t + step_percent }}% { opacity: 1; } + + {% elif anim_type == 'wobble' %} + {{ t + 0 }}% { transform: translate3d(0%, 0, 0); } + {{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); } + {{ t + step_percent }}% { transform: translate3d(0%, 0, 0); } + + {% elif anim_type == 'heartbeat' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'swing' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); } + {{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'vibrate' %} + {{ t + 0 }}% { transform: translate3d(0, 0, 0); } + {{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); } + {{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); } + {{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); } + {{ t + step_percent }}% { transform: translate3d(0, 0, 0); } + + {% endif %} + {% endfor %} + } + + {% endif %} + - type: custom:mushroom-chips-card + chips: + - type: template + entity: fan.shhf_cn_1129134246_sflt11_s_11_fan + icon: mdi:plus + tap_action: + action: perform-action + perform_action: fan.increase_speed + target: + entity_id: fan.shhf_cn_1129134246_sflt11_s_11_fan + alignment: end + card_mod: + style: > + ha-card { + /* ================================ */ + /* USER CONFIG HERE */ + /* ================================ */ + + /* 1. ACTIVE STATES */ + {% set active_states = ['on'] %} + + /* 2. POSITIONING */ + {% set pos_y = 'top' %} + {% set pos_y_val = '15px' %} + {% set pos_x = 'right' %} + {% set pos_x_val = '15px' %} + + /* 3. SIZING */ + {% set icon_size = '32px' %} + {% set text_size = '13px' %} + {% set badge_height = '10px' %} + {% set border_radius = '5px' %} + {% set border_thickness = '0px' %} + + /* 4. COLORS (HEX, RGB, Color Name) */ + /* --- Active --- */ + {% set active_bg = 'rgba(255, 167, 38, 0.3)' %} + {% set active_icon = 'rgb(255, 204, 128)' %} + {% set active_text = 'white' %} + {% set active_border = 'white' %} + {% set active_opacity = 0.3 %} + + /* --- Inactive --- */ + {% set inactive_bg = 'grey' %} + {% set inactive_icon = 'grey' %} + {% set inactive_text = 'darkgrey' %} + {% set inactive_border = 'transparent' %} + {% set inactive_opacity = 0.3 %} + + + /* 5. ANIMATIONS */ + /* Options: pulse, shake, wobble */ + /* flash, heartbeat, swing, vibrate */ + + {% set anim_type = 'none' %} + + /* true = 24/7, false = only when active */ + {% set always_animate = false %} + + {% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */ + {% set anim_duration_sec = 1 %} + {% set anim_delay_sec = 1 %} + + /* ================================== */ + /* USER CONFIG END (DONT TOUCH BELOW) */ + /* ================================== */ + + {% set current_state = states(config.chips[0].entity) %} + {% set is_active = current_state in active_states %} + + {% if is_active %} + {% set current_bg = active_bg %} + {% set current_icon = active_icon %} + {% set current_text = active_text %} + {% set current_border = active_border %} + {% set current_op = active_opacity %} + {% set current_anim = anim_type %} + {% else %} + {% set current_bg = inactive_bg %} + {% set current_icon = inactive_icon %} + {% set current_text = inactive_text %} + {% set current_border = inactive_border %} + {% set current_op = inactive_opacity %} + {% set current_anim = anim_type if always_animate else 'none' %} + {% endif %} + + {% set master_cycle = anim_duration_sec + anim_delay_sec %} + {% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %} + {% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %} + + --chip-padding: {{ badge_height }}; + --chip-border-radius: {{ border_radius }}; + + --chip-border-width: 0px !important; + --ha-card-border-width: 0px !important; + + --chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important; + + --text-color: {{ current_icon }} !important; + --color: {{ current_icon }} !important; + --chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important; + --chip-font-size: {{ text_size }} !important; + --chip-icon-size: {{ icon_size }} !important; + --mdc-icon-size: {{ icon_size }} !important; + --chip-height: auto !important; + --primary-text-color: {{ current_text }} !important; + --secondary-text-color: {{ current_text }} !important; + + position: absolute !important; + {{ pos_y }}: {{ pos_y_val }}; + {{ pos_x }}: {{ pos_x_val }}; + z-index: 1; + border: none !important; + border-radius: {{ border_radius }} !important; + box-shadow: 0 4px 6px rgba(0,0,0,0.2); + overflow: visible !important; + will-change: transform; + + {% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %} + animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear; + {% endif %} + } + + + ha-state-icon, ha-icon { + display: flex; + align-items: center; + justify-content: center; + width: {{ icon_size }} !important; + height: {{ icon_size }} !important; + } + + + {% if config.chips[0].content is not defined or + config.chips[0].content | length == 0 %} + ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; } + .content { display: none; } + {% else %} + ha-card { padding: 0 10px !important; } + .content { padding-left: 5px; font-weight: bold; } + {% endif %} + + + {% if current_anim != 'none' and iterations > 0 and + master_cycle > 0 %} + + @keyframes anim-{{ config.chips[0].entity | replace('.', + '-') }}-{{ anim_type }} { + {% for i in range(iterations) %} + {% set t = i * step_percent %} + + {% if anim_type == 'pulse' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'shake' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); } + {{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'flash' %} + {{ t + 0 }}% { opacity: 1; } + {{ t + (step_percent * 0.5) }}% { opacity: 0; } + {{ t + step_percent }}% { opacity: 1; } + + {% elif anim_type == 'wobble' %} + {{ t + 0 }}% { transform: translate3d(0%, 0, 0); } + {{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); } + {{ t + step_percent }}% { transform: translate3d(0%, 0, 0); } + + {% elif anim_type == 'heartbeat' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'swing' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); } + {{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'vibrate' %} + {{ t + 0 }}% { transform: translate3d(0, 0, 0); } + {{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); } + {{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); } + {{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); } + {{ t + step_percent }}% { transform: translate3d(0, 0, 0); } + + {% endif %} + {% endfor %} + } + + {% endif %} + - type: custom:mushroom-chips-card + chips: + - type: template + entity: fan.shhf_cn_1129134246_sflt11_s_11_fan + content: >- + {% set speed = state_attr(entity, 'percentage') %} {{ + speed | int(0) }}% + alignment: end + card_mod: + style: > + ha-card { + /* ================================== */ + /* USER CONFIG HERE */ + /* ================================== */ + + /* 1. ACTIVE STATE (NUMERIC) */ + {% set threshold_below = 20 %} + {% set threshold_above = false %} + + /* 2. POSITIONING */ + {% set pos_y = 'top' %} + {% set pos_y_val = '22px' %} + {% set pos_x = 'left' %} + {% set pos_x_val = '140px' %} + + /* 3. SIZING */ + {% set icon_size = '18px' %} + {% set text_size = '35px' %} + {% set badge_height = '5px' %} + {% set border_radius = '8px' %} + {% set border_thickness = '1px' %} + + /* 4. COLORS (HEX, RGB, Color Name) */ + /* --- Active --- */ + {% set active_bg = '#a63a3a' %} + {% set active_icon = 'white' %} + {% set active_text = 'white' %} + {% set active_border = '#ab1c1c' %} + {% set active_opacity = 0.3 %} + + /* --- Inactive --- */ + {% set inactive_bg = 'rgba(255, 167, 38, 0)' %} + {% set inactive_icon = 'grey' %} + {% set inactive_text = 'darkgrey' %} + {% set inactive_border = 'transparent' %} + {% set inactive_opacity = 0.3 %} + + /* 5. ANIMATIONS */ + /* Options: pulse, shake, wobble */ + /* flash, heartbeat, swing, vibrate */ + + {% set anim_type = 'none' %} + + /* true = 24/7, false = only when active */ + {% set always_animate = false %} + + {% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */ + {% set anim_duration_sec = 2 %} + {% set anim_delay_sec = 5 %} + + /* ================================== */ + /* USER CONFIG END (DONT TOUCH BELOW) */ + /* ================================== */ + + {% set current_state = states(config.chips[0].entity) %} + {% set state_num = current_state | float(-99999) %} + + {% set check_below = threshold_below | string | lower != 'false' %} + {% set check_above = threshold_above | string | lower != 'false' %} + + {% set is_active_below = check_below and state_num != -99999 and state_num <= (threshold_below | float(-99999)) %} + {% set is_active_above = check_above and state_num != -99999 and state_num >= (threshold_above | float(-99999)) %} + + {% set is_active = is_active_below or is_active_above %} + + {% if is_active %} + {% set current_bg = active_bg %} + {% set current_icon = active_icon %} + {% set current_text = active_text %} + {% set current_border = active_border %} + {% set current_op = active_opacity %} + {% set current_anim = anim_type %} + {% else %} + {% set current_bg = inactive_bg %} + {% set current_icon = inactive_icon %} + {% set current_text = inactive_text %} + {% set current_border = inactive_border %} + {% set current_op = inactive_opacity %} + {% set current_anim = anim_type if always_animate else 'none' %} + {% endif %} + + {% set master_cycle = anim_duration_sec + anim_delay_sec %} + {% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %} + {% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %} + + --chip-padding: {{ badge_height }}; + --chip-border-radius: {{ border_radius }}; + + --chip-border-width: 0px !important; + --ha-card-border-width: 0px !important; + + --chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important; + + --text-color: {{ current_icon }} !important; + --color: {{ current_icon }} !important; + --chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important; + --chip-font-size: {{ text_size }} !important; + --chip-icon-size: {{ icon_size }} !important; + --mdc-icon-size: {{ icon_size }} !important; + --chip-height: auto !important; + --primary-text-color: {{ current_text }} !important; + --secondary-text-color: {{ current_text }} !important; + + position: absolute !important; + {{ pos_y }}: {{ pos_y_val }}; + {{ pos_x }}: {{ pos_x_val }}; + z-index: 1; + border: none !important; + border-radius: {{ border_radius }} !important; + box-shadow: 0 4px 6px rgba(0,0,0,0.2); + overflow: visible !important; + will-change: transform; + + {% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %} + animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear; + {% endif %} + } + + + ha-state-icon, ha-icon { + display: flex; + align-items: center; + justify-content: center; + width: {{ icon_size }} !important; + height: {{ icon_size }} !important; + } + + + {% if config.chips[0].content is not defined or + config.chips[0].content | length == 0 %} + ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; } + .content { display: none; } + {% else %} + ha-card { padding: 0 10px !important; } + .content { padding-left: 5px; font-weight: bold; } + {% endif %} + + + {% if current_anim != 'none' and iterations > 0 and + master_cycle > 0 %} + + @keyframes anim-{{ config.chips[0].entity | replace('.', + '-') }}-{{ anim_type }} { + {% for i in range(iterations) %} + {% set t = i * step_percent %} + + {% if anim_type == 'pulse' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'shake' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); } + {{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'flash' %} + {{ t + 0 }}% { opacity: 1; } + {{ t + (step_percent * 0.5) }}% { opacity: 0; } + {{ t + step_percent }}% { opacity: 1; } + + {% elif anim_type == 'wobble' %} + {{ t + 0 }}% { transform: translate3d(0%, 0, 0); } + {{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); } + {{ t + step_percent }}% { transform: translate3d(0%, 0, 0); } + + {% elif anim_type == 'heartbeat' %} + {{ t + 0 }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); } + {{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); } + {{ t + step_percent }}% { transform: scale3d(1, 1, 1); } + + {% elif anim_type == 'swing' %} + {{ t + 0 }}% { transform: rotateZ(0deg); } + {{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); } + {{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); } + {{ t + step_percent }}% { transform: rotateZ(0deg); } + + {% elif anim_type == 'vibrate' %} + {{ t + 0 }}% { transform: translate3d(0, 0, 0); } + {{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); } + {{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); } + {{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); } + {{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); } + {{ t + step_percent }}% { transform: translate3d(0, 0, 0); } + + {% endif %} + {% endfor %} + } + + {% endif %} card_mod: style: | ha-card {