views: - type: sections max_columns: 4 title: Main path: main-home icon: mdi:home sections: - type: grid cards: - type: custom:stack-in-card mode: vertical keep: outer_padding: false margin: true cards: - type: custom:mushroom-chips-card chips: - type: template entity: >- sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1 icon_color: '{{states(''sensor.livingroom_temp_color_no_rgb'')}}' icon: mdi:thermometer use_entity_picture: true double_tap_action: action: none hold_action: action: none tap_action: action: more-info content: >- {% if is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1','unavailable') %} - {% elif is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1','unknown') %} - {% else %} {{states('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1')}}° {% endif %} - type: template entity: >- sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2 icon_color: light-blue icon: mdi:water-percent name: '' use_entity_picture: true hold_action: action: none double_tap_action: action: none tap_action: action: more-info content: >- {% if is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2','unavailable') %} - {% else %} {{states('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2')}}% {% endif %} - type: template entity: sensor.xiaomi_cn_2005161482_va3_hcho_density_p_3_11 icon_color: light-green icon: mdi:air-filter name: '' use_entity_picture: true hold_action: action: none double_tap_action: action: none tap_action: action: more-info content: >- {% if is_state('sensor.xiaomi_cn_2005161482_va3_hcho_density_p_3_11','unavailable') %} - {% else %} {{states('sensor.xiaomi_cn_2005161482_va3_hcho_density_p_3_11')}}% {% endif %} alignment: center - type: custom:mushroom-chips-card chips: - type: template double_tap_action: action: none icon: mdi:lightbulb-group content: |- {% if is_state('sensor.lights_of_count','0') %} {% else %} {{states('sensor.lights_of_count')}} {% endif %} icon_color: |- {% set state = states('sensor.lights_of_count')|float %} {% if state <= 0 %} grey {% else %} amber {% endif %} hold_action: action: none tap_action: action: none entity: sensor.lights_of_count - type: template double_tap_action: action: none icon: mdi:air-conditioner content: |- {% if is_state('sensor.aircondition_of_count','0') %} {% else %} {{states('sensor.aircondition_of_count')}} {% endif %} icon_color: >- {% set state = states('sensor.aircondition_of_count')|float %} {% if state <= 0 %} grey {% else %} amber {% endif %} hold_action: action: none tap_action: action: none entity: sensor.aircondition_of_count - type: template double_tap_action: action: none icon: mdi:water content: |- {% if is_state('sensor.water_damage_count','0') %} {% else %} {{states('sensor.water_damage_count')}} {% endif %} icon_color: >- {% set state = states('sensor.water_damage_count')|float %} {% if state <= 0 %} grey {% else %} blue {% endif %} hold_action: action: none tap_action: action: none entity: sensor.water_damage_count alignment: center - type: custom:swipe-card mode: vertical keep: outer_padding: false margin: true box_shadow: false background: false cards: - type: horizontal-stack cards: - type: custom:mushroom-entity-card card_mod: style: | ha-card{ box-shadow: none; } entity: input_boolean.on_state double_tap_action: action: none icon: mdi:home icon_color: green layout: vertical hold_action: action: none tap_action: action: navigate navigation_path: main-home primary_info: none secondary_info: name name: 首页 - type: custom:mushroom-entity-card card_mod: style: | ha-card{ box-shadow: none; } entity: switch.cuco_cn_2006579195_v3_on_p_2_1 icon: mdi:server icon_color: light-blue layout: vertical primary_info: none secondary_info: name tap_action: action: navigate navigation_path: home-server hold_action: action: none double_tap_action: action: none name: 机房 - type: custom:mushroom-entity-card card_mod: style: | ha-card{ box-shadow: none; } entity: light.quan_wu_zhao_ming icon_color: yellow secondary_info: name layout: vertical name: Lights double_tap_action: action: none hold_action: action: none tap_action: action: more-info primary_info: none icon: mdi:lamps card_mod: style: | ha-card { background-color: rgba(255, 255, 255, 0) !important; box-shadow: none !important; padding: 2px 0px 2px 0px; } column_span: 4 - type: grid cards: - type: custom:mushroom-title-card title: Light - type: custom:button-card entity: light.quan_wu_zhao_ming show_icon: true show_name: true show_state: true show_label: true name: 灯光状态 icon: mdi:lightbulb-group state_display: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); const percentage = allLeafLights.length > 0 ? Math.round((onLights.length / allLeafLights.length) * 100) : 0; return `${percentage}%`; ]]] label: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); if (onLights.length === 0) { return '所有灯光已关闭'; } else { return `${onLights.length}/${allLeafLights.length} 盏灯亮着`; } ]]] styles: card: - height: 80px - background: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); const percentage = allLeafLights.length > 0 ? (onLights.length / allLeafLights.length) : 0; // 胶囊形状背景 if (percentage === 0) { // 全关状态 - 深色胶囊 return 'linear-gradient(145deg, rgba(35,45,65,0.95), rgba(25,35,55,0.9))'; } else { // 进度条效果 - 亮色表示开启比例 const progressPercent = percentage * 100; return ` linear-gradient(to right, rgba(255,210,60,0.8) 0%, rgba(255,190,40,0.9) ${progressPercent}%, rgba(50,70,110,0.3) ${progressPercent}%, rgba(35,55,95,0.4) 100% ) `; } ]]] - border-radius: 45px !important - box-shadow: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); const percentage = allLeafLights.length > 0 ? (onLights.length / allLeafLights.length) : 0; if (percentage === 0) { return 'inset 3px 3px 6px rgba(0,0,0,0.4), inset -3px -3px 6px rgba(80,100,140,0.2), 0 2px 8px rgba(0,0,0,0.3)'; } else { return 'inset 2px 2px 4px rgba(0,0,0,0.3), inset -2px -2px 4px rgba(255,255,255,0.1), 0 6px 20px rgba(255,190,40,0.4)'; } ]]] - border: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); if (onLights.length === 0) { return '1px solid rgba(70,90,130,0.4)'; } else { return '1px solid rgba(255,190,40,0.6)'; } ]]] - padding: 12px 20px - display: flex - align-items: center - position: relative - overflow: hidden grid: - grid-template-areas: '"icon name state" "icon label label"' - grid-template-columns: min-content 1fr min-content - grid-template-rows: 1fr 1fr - gap: 0px 12px icon: - width: 50px - height: 50px - grid-area: icon - color: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); if (onLights.length === 0) { return 'rgba(140,160,200,0.7)'; } else { return 'rgba(255,220,60,1)'; } ]]] - filter: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); if (onLights.length === 0) { return 'none'; } else { return 'drop-shadow(0 0 12px rgba(255,220,60,0.8))'; } ]]] name: - font-size: 15px - font-weight: 700 - color: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); if (onLights.length === 0) { return 'rgba(180,200,240,0.9)'; } else { return 'rgba(255,255,255,1)'; } ]]] - grid-area: name - align-self: end - justify-self: start - text-shadow: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); if (onLights.length === 0) { return 'none'; } else { return '0 1px 3px rgba(0,0,0,0.5)'; } ]]] state: - font-size: 22px - font-weight: bold - color: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); if (onLights.length === 0) { return 'rgba(160,180,220,0.9)'; } else { return 'rgba(255,240,150,1)'; } ]]] - grid-area: state - align-self: end - justify-self: end - text-shadow: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); if (onLights.length === 0) { return 'none'; } else { return '0 0 12px rgba(255,220,60,0.7)'; } ]]] label: - font-size: 13px - font-weight: 600 - color: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); if (onLights.length === 0) { return 'rgba(160,180,220,0.9)'; } else { return 'rgba(255,255,240,1)'; } ]]] - grid-area: label - align-self: start - justify-self: start - margin-top: 2px - text-shadow: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); if (onLights.length === 0) { return 'none'; } else { return '0 1px 2px rgba(0,0,0,0.4)'; } ]]] custom_fields: progress_indicator: | [[[ const getAllLightEntities = (entityId) => { const entityState = states[entityId]; if (!entityState) return []; if (entityState.attributes && entityState.attributes.entity_id) { const childEntities = entityState.attributes.entity_id; let allLights = []; childEntities.forEach(childId => { allLights = allLights.concat(getAllLightEntities(childId)); }); return allLights; } else { return [entityId]; } }; const allLeafLights = getAllLightEntities('light.quan_wu_zhao_ming'); const onLights = allLeafLights.filter(eid => states[eid] && states[eid].state === 'on'); const percentage = allLeafLights.length > 0 ? (onLights.length / allLeafLights.length) : 0; if (percentage === 0) { return '
'; } else { const progressWidth = percentage * 100; return `
`; } ]]] styles_css: | ha-card { position: relative; overflow: hidden; } .custom-fields { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; } - type: vertical-stack cards: - type: custom:bubble-card card_type: separator icon: mdi:ceiling-light-multiple card_layout: large rows: '0.8' - type: custom:mushroom-light-card entity: light.pmfbj_cn_1187112198_xsx340_s_2 name: 客厅主灯 use_light_color: false icon: mdi:ceiling-light-multiple icon_color: accent show_brightness_control: true show_color_temp_control: true show_color_control: false - type: custom:mushroom-light-card entity: light.shhf_cn_1129134246_sflt11_s_2_light name: 餐桌 icon_color: orange fill_container: true show_brightness_control: true use_light_color: false show_color_temp_control: true show_color_control: false icon: mdi:ceiling-fan-light primary_info: name grid_options: columns: 6 rows: 2 - type: custom:mushroom-light-card entity: light.pmfbj_cn_1186735998_xsx340_s_2 name: 主卧 use_light_color: true show_brightness_control: true show_color_temp_control: true show_color_control: false - type: custom:mushroom-light-card entity: light.pmfbj_cn_1186772227_xsx340_s_2 name: 次卧灯 use_light_color: false show_brightness_control: true show_color_temp_control: true show_color_control: false collapsible_controls: false - type: custom:mushroom-light-card entity: light.opple_cn_2005385416_moat_s_2_light name: 阳台灯 icon: mdi:light-recessed icon_color: accent fill_container: true show_brightness_control: true show_color_temp_control: true - type: custom:mushroom-light-card entity: light.pmfbj_cn_1186744390_xsx340_s_2 name: 书房灯 icon: mdi:ceiling-light icon_color: light-blue fill_container: true show_brightness_control: true show_color_temp_control: true - type: custom:mushroom-light-card entity: light.panpan_cn_876603548_y18_s_3_light icon: '' show_brightness_control: false show_color_temp_control: false use_light_color: false show_color_control: false grid_options: columns: 12 rows: 2 column_span: 1 - type: grid cards: - type: custom:mushroom-title-card title: 空调 - type: custom:vertical-stack-in-card cards: - type: thermostat entity: climate.qdhkl_cn_2113954983_b19c show_current_as_primary: false features: - type: climate-hvac-modes grid_options: columns: 12 rows: 6 theme: Mushroom Shadow - type: custom:mushroom-chips-card chips: - type: template entity: climate.qdhkl_cn_2113954983_b19c icon: mdi:power 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 = '8px' %} {% set pos_x = 'right' %} {% set pos_x_val = '28px' %} /* 3. SIZING */ {% set icon_size = '25px' %} {% set text_size = '13px' %} {% set badge_height = '6px' %} {% set border_radius = '6px' %} {% set border_thickness = '0.5px' %} /* 4. COLORS (HEX, RGB, Color Name) */ /* --- Active --- */ {% set active_bg = '#b86836' %} {% set active_icon = '#d4f228' %} {% set active_text = 'white' %} {% set active_border = 'transparent' %} {% 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 = 'pulse' %} /* 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 != 'off' %} {% 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:vertical-stack-in-card cards: - type: custom:mushroom-climate-card entity: climate.qdhkl_cn_2113955096_b19c show_temperature_control: true collapsible_controls: true hvac_modes: - heat - cool - type: custom:mushroom-chips-card chips: - type: template entity: climate.qdhkl_cn_2113955096_b19c icon: mdi:power 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 = '4px' %} {% set pos_x = 'right' %} {% set pos_x_val = '4px' %} /* 3. SIZING */ {% set icon_size = '22px' %} {% set text_size = '13px' %} {% set badge_height = '2px' %} {% set border_radius = '5px' %} {% set border_thickness = '0.5px' %} /* 4. COLORS (HEX, RGB, Color Name) */ /* --- Active --- */ {% set active_bg = '#b86836' %} {% set active_icon = '#d4f228' %} {% set active_text = 'white' %} {% set active_border = 'transparent' %} {% 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 = 'pulse' %} /* 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 != 'off' %} {% 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 %} grid_options: columns: 6 - type: custom:vertical-stack-in-card cards: - type: custom:mushroom-climate-card entity: climate.qdhkl_cn_2113966364_b19c show_temperature_control: true collapsible_controls: true hvac_modes: - heat - cool - type: custom:mushroom-chips-card chips: - type: template entity: climate.qdhkl_cn_2113966364_b19c icon: mdi:power 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 = '4px' %} {% set pos_x = 'right' %} {% set pos_x_val = '4px' %} /* 3. SIZING */ {% set icon_size = '22px' %} {% set text_size = '13px' %} {% set badge_height = '2px' %} {% set border_radius = '5px' %} {% set border_thickness = '0.5px' %} /* 4. COLORS (HEX, RGB, Color Name) */ /* --- Active --- */ {% set active_bg = '#b86836' %} {% set active_icon = '#d4f228' %} {% set active_text = 'white' %} {% set active_border = 'transparent' %} {% 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 = 'pulse' %} /* 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 != 'off' %} {% 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 %} grid_options: columns: 6 - type: custom:vertical-stack-in-card cards: - type: custom:mushroom-climate-card entity: climate.qdhkl_cn_2113955084_b19c show_temperature_control: true collapsible_controls: true fill_container: false grid_options: columns: 12 rows: 1 hvac_modes: - heat - cool - type: custom:mushroom-chips-card chips: - type: template entity: climate.qdhkl_cn_2113955084_b19c icon: mdi:power 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 = '4px' %} {% set pos_x = 'right' %} {% set pos_x_val = '4px' %} /* 3. SIZING */ {% set icon_size = '22px' %} {% set text_size = '13px' %} {% set badge_height = '2px' %} {% set border_radius = '5px' %} {% set border_thickness = '0.5px' %} /* 4. COLORS (HEX, RGB, Color Name) */ /* --- Active --- */ {% set active_bg = '#b86836' %} {% set active_icon = '#d4f228' %} {% set active_text = 'white' %} {% set active_border = 'transparent' %} {% 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 = 'pulse' %} /* 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 != 'off' %} {% 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: grid cards: - type: custom:mushroom-title-card title: Devices column_span: 4 - type: grid cards: - type: custom:mushroom-fan-card entity: fan.xiaomi_cn_2196552583_p90_s_2_fan icon_animation: true fill_container: false show_percentage_control: true show_oscillate_control: true show_direction_control: false collapsible_controls: false - type: custom:mushroom-fan-card entity: fan.shhf_cn_1129134246_sflt11_s_11_fan name: 风扇 icon: '' icon_animation: true show_percentage_control: true show_oscillate_control: false show_direction_control: true - type: custom:mushroom-fan-card entity: fan.xiaomi_cn_2005161482_va3_s_2_air_purifier name: 空气净化器 icon_animation: true fill_container: false show_percentage_control: true show_oscillate_control: false show_direction_control: false collapsible_controls: false grid_options: columns: 12 rows: 2 - type: custom:mushroom-cover-card entity: cover.panpan_cn_876603548_y18_s_2_airer name: 晾衣架 show_buttons_control: true show_position_control: false grid_options: columns: 12 rows: 2 header: layout: responsive badges_position: bottom badges_wrap: wrap background: opacity: 80 alignment: center size: cover repeat: repeat attachment: fixed cards: [] theme: ios-dark-mode-light-blue visible: - user: 7a6c93d08acc4692bfd561154bb386df - user: 7809f2c31fda449b8e7c5a0d2eaf5fd5 - type: sections max_columns: 4 title: home-server path: home-server icon: mdi:server theme: Mushroom Shadow sections: - type: grid cards: - type: custom:mushroom-entity-card entity: input_boolean.on_state icon: mdi:home tap_action: action: navigate navigation_path: /lovelace/main-home hold_action: action: none double_tap_action: action: none name: 首页 primary_info: none secondary_info: name fill_container: false layout: horizontal grid_options: columns: 6 rows: 1 icon_color: green card_mod: style: | ha-card{ box-shadow: none; } - type: custom:mushroom-entity-card entity: sensor.pan_ke_feng_de_iphone_battery_level tap_action: action: more-info icon: '' icon_color: white primary_info: name secondary_info: none name: Pan's Phone grid_options: rows: 1 card_mod: style: .: | ha-card { /* ====== USER SETTINGS ===== */ {% set charging_entity = 'binary_sensor.anasbox_is_charging' %} /* ========================= */ /* ======= FONT SETTINGS ======= */ --card-primary-font-size: 15px !important; --card-secondary-font-size: 12px !important; --card-primary-font-weight: bold !important; /* --- LOGIC --- */ {% set level = states(config.entity) | float(0) %} {% set is_charging = is_state(charging_entity, 'on') %} /* 1. Determine Color */ {% if is_charging %} {% set color = '0, 255, 255' %} /* Cyan (Charging) */ {% elif level <= 20 %} {% set color = '244, 67, 54' %} /* Red */ {% elif level <= 60 %} {% set color = '255, 152, 0' %} /* Orange */ {% else %} {% set color = '0, 255, 100' %} /* Green */ {% endif %} /* --- PASS VARIABLES TO CSS --- */ --custom-level: {{ level }}%; --custom-color: rgba({{ color }}, 0.8); --custom-bubble: {{ 'block' if is_charging else 'none' }}; /* Icon Glow */ --custom-icon-shadow: {{ '0 0 15px rgba(' ~ color ~ ', 0.6)' if is_charging else 'none' }}; /* Text Color */ --text-color: {{ 'rgba(' ~ color ~ ', 1)' if level < 100 else 'rgba(255,255,255,0.7)' }}; /* --- CARD STYLING --- */ background: #1c1c1c !important; border: none !important; border-radius: 12px; position: relative; overflow: hidden; transition: all 0.5s ease; /* Ambient Glow behind the liquid */ background-image: radial-gradient(circle at 24px 24px, rgba({{ color }}, 0.15) 0%, transparent 60%) !important; } /* Icon Styling */ mushroom-shape-icon { --icon-size: 45px; display: flex; padding-right: 10px; padding-bottom: 5px; } /* --- PERCENTAGE BADGE (Top Right) --- */ ha-card::before { content: '{{ level | round(0) }}%'; position: absolute; top: 12px; right: 12px; font-size: 1rem; font-weight: 700; color: var(--text-color); background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(255, 255, 255, 0.1); padding: 2px 6px; border-radius: 4px; } /* --- PROGRESS BAR TRACK --- */ ha-card::after { content: ''; position: absolute; bottom: 0; left: 0; height: 4px; width: {{ level }}%; background: linear-gradient(90deg, transparent, rgb({{ color }})); box-shadow: 0 0 10px rgb({{ color }}); transition: width 0.5s ease; } mushroom-shape-icon$: | .shape { /* --- LOGIC INJECTION --- */ --liquid-level: var(--custom-level); --liquid-color: var(--custom-color); --bubble-display: var(--custom-bubble); /* Container Setup */ background: rgba(255, 255, 255, 0.05) !important; overflow: hidden !important; /* Keeps the liquid inside the circle */ position: relative; border: 1px solid rgba(255,255,255,0.1); box-shadow: var(--custom-icon-shadow) !important; } /* THE LIQUID (Wavy Fill) */ .shape::before { content: ''; position: absolute; left: -50%; width: 200%; height: 200%; /* The top is calculated based on battery level (100% - level) */ top: calc(100% - var(--liquid-level)); background: var(--liquid-color); border-radius: 40%; /* Creates the "Wave" shape when rotated */ /* The Wave Animation */ animation: liquid-wave 6s linear infinite; opacity: 0.8; } /* CHARGING BUBBLES */ .shape::after { content: ''; display: var(--bubble-display); position: absolute; inset: 0; background-image: radial-gradient(2px 2px at 20% 80%, rgba(255,255,255,0.8), transparent), radial-gradient(2px 2px at 50% 70%, rgba(255,255,255,0.8), transparent), radial-gradient(3px 3px at 80% 90%, rgba(255,255,255,0.8), transparent); background-size: 100% 100%; animation: bubbles-rise 0.7s linear infinite; } /* Ensure the MDI Icon sits on top of the liquid */ ha-icon { position: relative; z-index: 2; /* Blend the icon slightly so it looks submerged */ mix-blend-mode: overlay; color: white !important; } /* --- ANIMATIONS --- */ @keyframes liquid-wave { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes bubbles-rise { 0% { transform: translateY(10px); opacity: 0; } 50% { opacity: 1; } 100% { transform: translateY(-20px); opacity: 0; } } column_span: 4 - type: grid cards: - type: custom:mushroom-title-card title: Hello Mother Fucker alignment: center - square: false type: grid cards: - type: custom:vertical-stack-in-card cards: - type: custom:mushroom-entity-card entity: >- sensor.xiaomi_cn_blt_3_1ni9qhv584c03_mini_temperature_p_2_1001 tap_action: action: more-info icon: mdi:thermometer name: 温度 primary_info: state secondary_info: name card_mod: style: mushroom-shape-icon$: | .shape { {# ========== CONFIG ========== #} {# == Updated: entity auto generated == #} {% set temp = states(config.entity) | float(0) %} {# ------------------------------------------- #} {# TEMPERATURE → COLOR + EFFECT PRESETS #} {# ------------------------------------------- #} {# DEFAULTS (will be overridden by ranges) #} {% set rgb = '0,140,255' %} {% set anim = 'temp-cold-breathe' %} {% set glow_anim = 'temp-cold-glow' %} {% set halo_anim = 'temp-cold-halo' %} {% set duration = 4.0 %} {% set intensity = 0.5 %} {# RANGES / COLORS #} {# You can change temp numbers below if needed #} {% if temp < 16 %} {# BLUE #} {% set rgb = '0,140,255' %} {% set anim = 'temp-cold-breathe' %} {% set glow_anim = 'temp-cold-glow' %} {% set halo_anim = 'temp-cold-halo' %} {% set duration = 4.4 %} {% set intensity = 0.4 %} {% elif temp < 18 %} {# YELLOW #} {% set rgb = '255,210,40' %} {% set anim = 'temp-cool-wave' %} {% set glow_anim = 'temp-cool-glow' %} {% set halo_anim = 'temp-cool-halo' %} {% set duration = 3.4 %} {% set intensity = 0.55 %} {% elif temp < 20 %} {# ORANGE #} {% set rgb = '255,150,40' %} {% set anim = 'temp-comfy-breathe' %} {% set glow_anim = 'temp-comfy-glow' %} {% set halo_anim = 'temp-comfy-halo' %} {% set duration = 3.0 %} {% set intensity = 0.6 %} {% elif temp < 22 %} {# DARK ORANGE #} {% set rgb = '255,115,20' %} {% set anim = 'temp-warm-pulse' %} {% set glow_anim = 'temp-warm-glow' %} {% set halo_anim = 'temp-warm-halo' %} {% set duration = 2.4 %} {% set intensity = 0.8 %} {% else %} {# RED #} {% set rgb = '255,40,40' %} {% set anim = 'temp-hot-shimmer' %} {% set glow_anim = 'temp-hot-glow' %} {% set halo_anim = 'temp-hot-halo' %} {% set duration = 2.0 %} {% set intensity = 1.0 %} {% endif %} {# Apply variables #} --temp-rgb: {{ rgb }}; --temp-intensity: {{ intensity }}; --shape-animation: {{ anim }} {{ duration }}s ease-in-out infinite; --temp-glow-animation: {{ glow_anim }} {{ (duration * 0.9) | round(2) }}s ease-in-out infinite; --temp-halo-animation: {{ halo_anim }} {{ (duration * 1.15) | round(2) }}s ease-in-out infinite; opacity: 1; /* Icon color follows the temperature */ --icon-color: rgba({{ rgb }}, 1); /* KILL THE THEME BLUE & MAKE SHAPE NEUTRAL */ background-color: rgba(77, 77, 77,0.1) !important; box-shadow: none !important; border: 1px solid rgba(255,255,255,0.06); position: relative; transform-origin: 50% 60%; animation: var(--shape-animation); } /* Glow layers */ .shape::before, .shape::after { content: ''; position: absolute; border-radius: inherit; pointer-events: none; } .shape::before { inset: -8px; animation: var(--temp-glow-animation); } .shape::after { inset: -22px; animation: var(--temp-halo-animation); mix-blend-mode: screen; } /* ========== COLD ========== */ @keyframes temp-cold-breathe { 0% { transform: scale(0.96); } 50% { transform: scale(1.03); } 100% { transform: scale(0.96); } } @keyframes temp-cold-glow { 0% { box-shadow: 0 0 20px 0 rgba(var(--temp-rgb), 0.6), 0 0 34px 6 rgba(var(--temp-rgb), 0.55); } 50% { box-shadow: 0 0 30px 4 rgba(var(--temp-rgb), 0.95), 0 0 50px 10px rgba(var(--temp-rgb), 0.85); } 100% { box-shadow: 0 0 20px 0 rgba(var(--temp-rgb), 0.6), 0 0 34px 6 rgba(var(--temp-rgb), 0.55); } } @keyframes temp-cold-halo { 0% { box-shadow: 0 0 80px 20px rgba(var(--temp-rgb), 0.35), 0 -20px 80px -14px rgba(220, 240, 255, 0.55); } 50% { box-shadow: 0 0 130px 36px rgba(var(--temp-rgb), 0.5), 0 -34px 100px -8px rgba(240, 250, 255, 0.8); } 100% { box-shadow: 0 0 80px 20px rgba(var(--temp-rgb), 0.35), 0 -20px 80px -14px rgba(220, 240, 255, 0.55); } } /* ========== COOL ========== */ @keyframes temp-cool-wave { 0% { transform: translateX(0); } 25% { transform: translateX(-1px); } 50% { transform: translateX(1px) translateY(-1px); } 75% { transform: translateX(-1px); } 100% { transform: translateX(0); } } @keyframes temp-cool-glow { 0% { box-shadow: 0 0 22px 0 rgba(var(--temp-rgb), 0.6), 0 0 34px 4 rgba(var(--temp-rgb), 0.7); } 50% { box-shadow: 0 0 28px 2 rgba(var(--temp-rgb), 0.95), 0 0 48px 12px rgba(var(--temp-rgb), 0.85); } 100% { box-shadow: 0 0 22px 0 rgba(var(--temp-rgb), 0.6), 0 0 34px 4 rgba(var(--temp-rgb), 0.7); } } @keyframes temp-cool-halo { 0% { box-shadow: 0 0 90px 26px rgba(var(--temp-rgb), 0.35), 0 18px 80px -12px rgba(0, 220, 255, 0.35); } 50% { box-shadow: 0 0 140px 42px rgba(var(--temp-rgb), 0.45), 0 30px 110px -10px rgba(0, 255, 255, 0.5); } 100% { box-shadow: 0 0 90px 26px rgba(var(--temp-rgb), 0.35), 0 18px 80px -12px rgba(0, 220, 255, 0.35); } } /* ========== COMFY ========== */ @keyframes temp-comfy-breathe { 0% { transform: scale(0.98); } 50% { transform: scale(1.05); } 100% { transform: scale(0.98); } } @keyframes temp-comfy-glow { 50% { box-shadow: 0 0 26px 4 rgba(var(--temp-rgb), 0.9), 0 0 42px 10px rgba(var(--temp-rgb), 0.85); } } @keyframes temp-comfy-halo { 50% { box-shadow: 0 0 120px 40px rgba(var(--temp-rgb), 0.45), 0 26px 80px -10px rgba(180,255,200,0.5); } } /* ========== WARM ========== */ @keyframes temp-warm-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.07); } 100% { transform: scale(1); } } @keyframes temp-warm-glow { 50% { box-shadow: 0 0 30px 4 rgba(var(--temp-rgb), 0.95), 0 0 54px 14px rgba(var(--temp-rgb), 0.9); } } @keyframes temp-warm-halo { 50% { box-shadow: 0 0 140px 48px rgba(var(--temp-rgb), 0.55), 0 26px 100px -10px rgba(255,210,150,0.5); } } /* ========== HOT ========== */ @keyframes temp-hot-shimmer { 0% { transform: scale(1); filter: blur(0); } 50% { transform: scale(1.08); filter: blur(0.6px); } 100% { transform: scale(1); filter: blur(0); } } @keyframes temp-hot-glow { 50% { box-shadow: 0 0 34px 6 rgba(var(--temp-rgb), 1), 0 0 62px 14px rgba(var(--temp-rgb), 0.95); } } @keyframes temp-hot-halo { 50% { box-shadow: 0 0 160px 60px rgba(var(--temp-rgb), 0.6), 0 34px 120px -12px rgba(255,150,100,0.6); } } .: | mushroom-shape-icon { --icon-size: 48px; --icon-color: rgba(var(--hum-rgb),1) !important; display: flex; margin: -16px 0 10px -20px !important; padding-right: 22px; padding-bottom: 18px; } ha-card { clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 14px)); /* FONT SIZE & SPACING SETTINGS */ --card-primary-font-size: 1.4rem !important; /* Increases vertical space between primary and secondary */ --card-primary-line-height: 1.3 !important; } - type: custom:vertical-stack-in-card cards: - type: custom:mini-graph-card entities: - >- sensor.xiaomi_cn_blt_3_1ni9qhv584c03_mini_temperature_p_2_1001 hours_to_show: 24 line_width: 5 show: name: false icon: false state: false labels: false legend: false color_thresholds: - value: 0 color: blue - value: 16 color: lightblue - value: 18 color: orange - value: 21 color: red card_mod: style: | ha-card { background: none; box-shadow: none; opacity: 50%; border: none; width: 250px; mask-image: radial-gradient( ellipse at center, rgba(0,0,0,1) 0%, rgba(0,0,0,0) 90% ); } card_mod: style: .: | ha-card { background: none; box-shadow: none; border: none; margin: 8px 12px; position: absolute; bottom: -10px; right: -10px; } - type: custom:vertical-stack-in-card cards: - type: custom:mushroom-entity-card entity: >- sensor.xiaomi_cn_blt_3_1ni9qhv584c03_mini_relative_humidity_p_2_1002 tap_action: action: more-info icon: mdi:water-percent name: 湿度 primary_info: state secondary_info: name card_mod: style: mushroom-shape-icon$: > .shape { {# ========== CONFIG ========== #} {# == Updated: entity auto generated == #} {% set hum = states(config.entity) | float(0) %} {# DEFAULTS #} {% set rgb = '120,210,255' %} {% set anim = 'hum-good-breathe' %} {% set glow_anim = 'hum-good-glow' %} {% set halo_anim = 'hum-good-halo' %} {% set duration = 3.2 %} {# RANGES < 40 -> BAD (dark blue) 40-60 -> GOOD (light blue) > 60 -> MIDDLE / humid (medium blue) #} {% if hum < 40 %} {# BAD - dry - dark blue #} {% set rgb = '0,80,200' %} {% set anim = 'hum-bad-pulse' %} {% set glow_anim = 'hum-bad-glow' %} {% set halo_anim = 'hum-bad-halo' %} {% set duration = 2.8 %} {% elif hum <= 60 %} {# GOOD - light blue #} {% set rgb = '120,210,255' %} {% set anim = 'hum-good-breathe' %} {% set glow_anim = 'hum-good-glow' %} {% set halo_anim = 'hum-good-halo' %} {% set duration = 3.4 %} {% else %} {# MIDDLE / humid - medium blue #} {% set rgb = '40,140,255' %} {% set anim = 'hum-mid-wave' %} {% set glow_anim = 'hum-mid-glow' %} {% set halo_anim = 'hum-mid-halo' %} {% set duration = 3.0 %} {% endif %} --hum-rgb: {{ rgb }}; --shape-animation: {{ anim }} {{ duration }}s ease-in-out infinite; --hum-glow-animation: {{ glow_anim }} {{ (duration * 0.9) | round(2) }}s ease-in-out infinite; --hum-halo-animation: {{ halo_anim }} {{ (duration * 1.1) | round(2) }}s ease-in-out infinite; /* Icon color follows humidity color */ --icon-color: rgba({{ rgb }}, 1); /* Neutral pill so theme blue does not leak through */ background-color: rgba(77,77,77,0.2) !important; box-shadow: none !important; border: 1px solid rgba(255,255,255,0.06); opacity: 1; position: relative; transform-origin: 50% 60%; animation: var(--shape-animation); } /* Glow layers */ .shape::before, .shape::after { content: ''; position: absolute; border-radius: inherit; pointer-events: none; } .shape::before { inset: -8px; animation: var(--hum-glow-animation); } .shape::after { inset: -22px; animation: var(--hum-halo-animation); mix-blend-mode: screen; } /* ========== GOOD - light blue ========== */ @keyframes hum-good-breathe { 0% { transform: scale(0.98); } 50% { transform: scale(1.04); } 100% { transform: scale(0.98); } } @keyframes hum-good-glow { 0% { box-shadow: 0 0 18px 0 rgba(var(--hum-rgb), 0.55), 0 0 30px 4 rgba(var(--hum-rgb), 0.6); } 50% { box-shadow: 0 0 24px 4 rgba(var(--hum-rgb), 0.9), 0 0 44px 10px rgba(var(--hum-rgb), 0.85); } 100% { box-shadow: 0 0 18px 0 rgba(var(--hum-rgb), 0.55), 0 0 30px 4 rgba(var(--hum-rgb), 0.6); } } @keyframes hum-good-halo { 0% { box-shadow: 0 0 80px 24px rgba(var(--hum-rgb), 0.35), 0 18px 70px -12px rgba(180,230,255,0.3); } 50% { box-shadow: 0 0 120px 40px rgba(var(--hum-rgb), 0.45), 0 26px 90px -10px rgba(200,240,255,0.45); } 100% { box-shadow: 0 0 80px 24px rgba(var(--hum-rgb), 0.35), 0 18px 70px -12px rgba(180,230,255,0.3); } } /* ========== MIDDLE / humid - medium blue ========== */ @keyframes hum-mid-wave { 0% { transform: translateX(0); } 25% { transform: translateX(-1px); } 50% { transform: translateX(1px) translateY(-1px); } 75% { transform: translateX(-1px); } 100% { transform: translateX(0); } } @keyframes hum-mid-glow { 0% { box-shadow: 0 0 20px 0 rgba(var(--hum-rgb), 0.6), 0 0 32px 4 rgba(var(--hum-rgb), 0.7); } 50% { box-shadow: 0 0 28px 3 rgba(var(--hum-rgb), 0.95), 0 0 48px 10px rgba(var(--hum-rgb), 0.85); } 100% { box-shadow: 0 0 20px 0 rgba(var(--hum-rgb), 0.6), 0 0 32px 4 rgba(var(--hum-rgb), 0.7); } } @keyframes hum-mid-halo { 0% { box-shadow: 0 0 90px 26px rgba(var(--hum-rgb), 0.4), 0 18px 80px -12px rgba(80,190,255,0.35); } 50% { box-shadow: 0 0 135px 42px rgba(var(--hum-rgb), 0.5), 0 28px 105px -10px rgba(100,210,255,0.5); } 100% { box-shadow: 0 0 90px 26px rgba(var(--hum-rgb), 0.4), 0 18px 80px -12px rgba(80,190,255,0.35); } } /* ========== BAD - dry - dark blue ========== */ @keyframes hum-bad-pulse { 0% { transform: scale(0.97); } 40% { transform: scale(1.03); } 100% { transform: scale(0.97); } } @keyframes hum-bad-glow { 0% { box-shadow: 0 0 18px 0 rgba(var(--hum-rgb), 0.6), 0 0 28px 4 rgba(var(--hum-rgb), 0.7); } 50% { box-shadow: 0 0 26px 4 rgba(var(--hum-rgb), 0.95), 0 0 44px 12px rgba(var(--hum-rgb), 0.9); } 100% { box-shadow: 0 0 18px 0 rgba(var(--hum-rgb), 0.6), 0 0 28px 4 rgba(var(--hum-rgb), 0.7); } } @keyframes hum-bad-halo { 0% { box-shadow: 0 0 80px 22px rgba(var(--hum-rgb), 0.45), 0 18px 75px -10px rgba(0,70,160,0.5); } 50% { box-shadow: 0 0 130px 40px rgba(var(--hum-rgb), 0.6), 0 26px 100px -8px rgba(0,90,190,0.65); } 100% { box-shadow: 0 0 80px 22px rgba(var(--hum-rgb), 0.45), 0 18px 75px -10px rgba(0,70,160,0.5); } } .: | mushroom-shape-icon { --icon-size: 48px; --icon-color: rgba(var(--hum-rgb),1) !important; display: flex; margin: -16px 0 10px -20px !important; padding-right: 22px; padding-bottom: 18px; } ha-card { clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 14px)); /* FONT SIZE & SPACING SETTINGS */ --card-primary-font-size: 1.4rem !important; /* Increases vertical space between primary and secondary */ --card-primary-line-height: 1.3 !important; } - type: custom:vertical-stack-in-card cards: - type: custom:mini-graph-card entities: - >- sensor.xiaomi_cn_blt_3_1ni9qhv584c03_mini_relative_humidity_p_2_1002 line_color: lightblue line_width: 5 hours_to_show: 24 show: name: false icon: false state: false labels: false legend: false card_mod: style: | ha-card { background: none; box-shadow: none; opacity: 50%; border: none; width: 250px; mask-image: radial-gradient( ellipse at center, rgba(0,0,0,1) 0%, rgba(0,0,0,0) 90% ); } card_mod: style: .: | ha-card { background: none; box-shadow: none; border: none; margin: 8px 12px; position: absolute; bottom: -10px; right: -10px; } columns: 2 - type: vertical-stack cards: - type: custom:bubble-card card_type: separator icon: '' card_layout: large rows: '0.5' - type: custom:mushroom-entity-card entity: binary_sensor.lumi_cn_775597154_acn001_contact_state_p_2_1 tap_action: action: more-info icon: mdi:door name: 机柜门 icon_color: red primary_info: state secondary_info: name card_mod: style: mushroom-shape-icon$: | .shape { {% set is_open = is_state(config.entity, 'on') %} /* LOGIC: Define colors and animations based on state */ {% if is_open %} /* OPEN: Red, Dark Red Shape, Animated */ --icon-color-set: rgb(244, 67, 54); --shape-color-set: rgba(160, 0, 0, 0.15); --shape-animation: door-soft-open 1.7s ease-in-out infinite; /* Increased duration slightly for smoother persistent glow */ --glow-animation: door-soft-glow 2.5s ease-in-out infinite; --beam-animation: door-soft-beam 2.5s ease-in-out infinite; --icon-filter: drop-shadow(0 0 6px rgba(160, 0, 0, 0.95)); {% else %} /* CLOSED: Green, Dark Green Shape, Static */ --icon-color-set: rgb(76, 175, 80); --shape-color-set: rgba(0, 80, 0, 0.4); --shape-animation: none; --glow-animation: none; --beam-animation: none; --icon-filter: none; {% endif %} /* Apply the variable colors defined above */ background-color: var(--shape-color-set) !important; /* Standard positioning */ position: relative; transform-origin: 25% 50%; animation: var(--shape-animation); } /* Color and Filter for the Icon itself */ .shape ha-icon { color: var(--icon-color-set) !important; filter: var(--icon-filter); } /* --- ANIMATION LAYERS --- */ .shape::before, .shape::after { content: ''; position: absolute; border-radius: inherit; pointer-events: none; } /* Inner Glow */ .shape::before { inset: -10px; animation: var(--glow-animation); } /* Outer Beam */ .shape::after { inset: -15px; animation: var(--beam-animation); mix-blend-mode: screen; } /* --- KEYFRAMES --- */ @keyframes door-soft-open { 0% { transform: rotate(0deg); } 40% { transform: rotate(-9deg); } 70% { transform: rotate(-6deg); } 100% { transform: rotate(0deg); } } @keyframes door-soft-glow { 0% { box-shadow: 0 0 20px 0 rgba(160, 0, 0, 0.7), 0 0 40px 6 rgba(160, 0, 0, 0.6), 0 0 80px 14px rgba(160, 0, 0, 0.4); } 50% { box-shadow: 0 0 30px 4 rgba(200, 0, 0, 1), 0 0 70px 16px rgba(200, 0, 0, 0.95), 0 0 120px 28px rgba(200, 0, 0, 0.7); } 100% { box-shadow: 0 0 20px 0 rgba(160, 0, 0, 0.7), 0 0 40px 6 rgba(160, 0, 0, 0.6), 0 0 80px 14px rgba(160, 0, 0, 0.4); } } /* UPDATED: Huge halo now never fully disappears */ @keyframes door-soft-beam { 0% { /* Small, persistent base glow */ box-shadow: 0 0 40px 10px rgba(160, 0, 0, 0.3), 0 0 60px 20px rgba(100, 0, 0, 0.2); opacity: 0.4; } 50% { /* Maximum Intense Glow */ box-shadow: 0 0 160px 60px rgba(230, 20, 20, 0.8), 0 0 230px 100px rgba(160, 0, 0, 0.7); opacity: 1; } 100% { /* Return to base glow */ box-shadow: 0 0 40px 10px rgba(160, 0, 0, 0.3), 0 0 60px 20px rgba(100, 0, 0, 0.2); opacity: 0.4; } } .: | mushroom-shape-icon { --icon-size: 48px; display: flex; margin: -5px 0 10px -14px !important; padding-right: 22px; } ha-card { clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 14px)); } grid_options: columns: 12 rows: 1 - type: vertical-stack cards: - type: custom:bubble-card card_type: separator icon: '' card_layout: large rows: '0.5' - type: custom:mushroom-light-card entity: light.lemesh_cn_2077009002_wy0d02_s_2_light use_light_color: true show_color_temp_control: true show_brightness_control: true collapsible_controls: false show_color_control: true name: 机柜灯 icon_color: auto grid_options: columns: 12 rows: 2 card_mod: style: mushroom-shape-icon$: | .shape { {# ========== USER CONFIG ========== #} {% set state_entity = 'light.lemesh_cn_2077009002_wy0d02_s_2_light' %} {% set active_value = 'on' %} {# ======== TRIGGER ======== #} {% set trigger_active = (states(state_entity) == active_value) %} {# ======== COLOR FROM ENTITY (rgb_color) ======== #} {% set rgb = state_attr(config.entity, 'rgb_color') %} {% if rgb is not none %} {% set r = (rgb[0] | int) %} {% set g = (rgb[1] | int) %} {% set b = (rgb[2] | int) %} {% else %} {# fallback for CT-only lights #} {% set r = 255 %} {% set g = 240 %} {% set b = 200 %} {% endif %} {% if trigger_active %} --shape-animation: lamp-sweep 1.8s ease-in-out infinite; opacity: 1; {% else %} --shape-animation: none; opacity: 0.5; {% endif %} position: relative; transform-origin: 50% 60%; } @keyframes lamp-sweep { 0% { filter: brightness(1.1); box-shadow: 0 0 12px 4px rgba({{ r }}, {{ g }}, {{ b }}, 0.9), 0 30px 40px -10px rgba({{ r }}, {{ g }}, {{ b }}, 0.0); transform: rotate(-4deg) scale(1); } 25% { filter: brightness(1.4); box-shadow: 0 0 18px 8px rgba({{ r }}, {{ g }}, {{ b }}, 1), -8px 35px 45px -12px rgba({{ r }}, {{ g }}, {{ b }}, 0.5); transform: rotate(3deg) scale(1.02); } 50% { filter: brightness(1.2); box-shadow: 0 0 24px 10px rgba({{ r }}, {{ g }}, {{ b }}, 0.9), 8px 35px 45px -12px rgba({{ r }}, {{ g }}, {{ b }}, 0.5); transform: rotate(-2deg) scale(1.03); } 75% { filter: brightness(1.5); box-shadow: 0 0 18px 8px rgba({{ r }}, {{ g }}, {{ b }}, 1), -6px 30px 40px -12px rgba({{ r }}, {{ g }}, {{ b }}, 0.4); transform: rotate(2deg) scale(1.01); } 100% { filter: brightness(1.1); box-shadow: 0 0 12px 4px rgba({{ r }}, {{ g }}, {{ b }}, 0.8), 0 30px 40px -10px rgba({{ r }}, {{ g }}, {{ b }}, 0.0); transform: rotate(-4deg) scale(1); } } .: | mushroom-shape-icon { --icon-size: 65px; display: flex; margin: -18px 0px 0px -18px !important; } ha-card { clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 12px)); } icon: mdi:led-strip-variant - type: vertical-stack cards: - type: custom:bubble-card card_type: separator icon: '' card_layout: large rows: '0.5' - type: custom:mushroom-entity-card entity: switch.cuco_cn_2006579195_v3_on_p_2_1 tap_action: action: none icon: mdi:power-socket-au icon_color: light-blue name: Nas 插座 card_mod: style: mushroom-shape-icon$: | .shape { {# ========== USER CONFIG ========== #} {# true = number mode, false = state mode #} {% set use_number = false %} {# STATE MODE SETTINGS #} {% set state_entity = 'switch.cuco_cn_2006579195_v3_on_p_2_1' %} {% set active_value = 'on' %} {# OPTIONAL: NUMBER MODE SETTINGS #} {% set number_entity = 'sensor.plug_power' %} {# '>' '<' '=' '>=' '<=' #} {% set number_operator = '>' %} {% set threshold = 0.0 %} {# ========== END USER CONFIG ====== #} {# ======== TRIGGER DECISION LOGIC ======== #} {% if use_number %} {% set num = states(number_entity) | float(0) %} {% if number_operator == '>' %} {% set trigger_active = (num > threshold) %} {% elif number_operator == '<' %} {% set trigger_active = (num < threshold) %} {% elif number_operator == '=' %} {% set trigger_active = (num == threshold) %} {% elif number_operator == '>=' %} {% set trigger_active = (num >= threshold) %} {% elif number_operator == '<=' %} {% set trigger_active = (num <= threshold) %} {% else %} {% set trigger_active = false %} {% endif %} {% else %} {% set trigger_active = (states(state_entity) == active_value) %} {% endif %} {# =========== END TRIGGER LOGIC =========== #} {% if trigger_active %} {# adjust speed based on this plug's own power attribute #} {% set p = state_attr(config.entity, 'current_power_w') | float(0) %} {% set dur = 1.6 - (p / 800) %} --shape-animation: ultra-plug-on {{ [0.4, dur] | max | round(2) }}s ease-in-out infinite; --plug-glow-animation: ultra-plug-glow 1.8s ease-in-out infinite; --plug-arcs-animation: ultra-plug-arcs 1.2s linear infinite; opacity: 1; {% else %} --shape-animation: none; --plug-glow-animation: none; --plug-arcs-animation: none; opacity: 0.7; {% endif %} transform-origin: 50% 50%; position: relative; } .shape::before, .shape::after { content: ''; position: absolute; inset: -4px; border-radius: inherit; pointer-events: none; } .shape::before { animation: var(--plug-glow-animation); } .shape::after { animation: var(--plug-arcs-animation); } @keyframes ultra-plug-on { 0% { transform: scale(1); } 25% { transform: scale(1.05) translateY(-1px); } 50% { transform: scale(1.08) translateY(-2px); } 75% { transform: scale(1.04) translateY(-1px); } 100% { transform: scale(1); } } @keyframes ultra-plug-glow { 0% { box-shadow: 0 0 10px 3px rgba(var(--rgb-{{ config.icon_color }}), 0.6), 0 0 20px 8px rgba(var(--rgb-{{ config.icon_color }}), 0.3); } 50% { box-shadow: 0 0 18px 6px rgba(var(--rgb-{{ config.icon_color }}), 0.9), 0 0 32px 12px rgba(var(--rgb-{{ config.icon_color }}), 0.4); } 100% { box-shadow: 0 0 10px 3px rgba(var(--rgb-{{ config.icon_color }}), 0.6), 0 0 20px 8px rgba(var(--rgb-{{ config.icon_color }}), 0.3); } } @keyframes ultra-plug-arcs { 0% { box-shadow: -10px -6px 0 -4px rgba(var(--rgb-{{ config.icon_color }}), 0.0), 12px 4px 0 -4px rgba(var(--rgb-{{ config.icon_color }}), 0.0); } 25% { box-shadow: -10px -6px 0 -4px rgba(var(--rgb-{{ config.icon_color }}), 0.7), 12px 4px 0 -4px rgba(var(--rgb-{{ config.icon_color }}), 0.4); } 50% { box-shadow: -6px 2px 0 -4px rgba(var(--rgb-{{ config.icon_color }}), 0.3), 10px -8px 0 -4px rgba(var(--rgb-{{ config.icon_color }}), 0.7); } 75% { box-shadow: -12px 4px 0 -4px rgba(var(--rgb-{{ config.icon_color }}), 0.5), 8px 0 0 -4px rgba(var(--rgb-{{ config.icon_color }}), 0.2); } 100% { box-shadow: -10px -6px 0 -4px rgba(var(--rgb-{{ config.icon_color }}), 0.0), 12px 4px 0 -4px rgba(var(--rgb-{{ config.icon_color }}), 0.0); } } .: | mushroom-shape-icon { --icon-size: 65px; display: flex; margin: -18px 0 10px -20px !important; padding-right: 10px; } ha-card { clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 12px)); } grid_options: columns: 12 rows: 1.5 - type: custom:mushroom-entity-card entity: sensor.cuco_cn_2006579195_v3_electric_power_p_11_2 icon: mdi:nas icon_color: red hold_action: action: more-info double_tap_action: action: none name: Nas Plug card_mod: style: .: | ha-card { /* ================= USER SETTINGS ================= */ {% set power_entity = 'sensor.cuco_cn_2006579195_v3_electric_power_p_11_2' %} {% set max_w = 60 %} /* ================================================= */ /* --- LOGIC --- */ {% set current_w = states(power_entity) | float(0) %} /* ACTIVE determines if animations/glows are ON (depends only on power) */ {% set active = current_w > 0 %} /* Calculate Load Percentage */ {% set width_pct = (current_w / max_w * 100) | round(2) %} {% if width_pct > 100 %}{% set width_pct = 100 %}{% endif %} /* --- PASS VARIABLES TO CSS --- */ /* Define the color we want the effects to use (from config) */ --active-color: var(--rgb-{{ config.icon_color }}); --bar-width: {{ width_pct }}%; --bar-opacity: {{ 1 if active else 0 }}; /* Text color: If power > 0, show colored text. Else dim. */ --text-color: {{ 'rgba(var(--active-color), 1)' if active else 'rgba(255,255,255,0.5)' }}; /* PASS ANIMATION VARIABLES DOWN TO SHADOW DOM */ --shape-animation: {{ 'ultra-plug-on 3s ease-in-out infinite' if active else 'none' }}; --plug-glow-animation: {{ 'ultra-plug-glow 3s ease-in-out infinite' if active else 'none' }}; --plug-arcs-animation: {{ 'ultra-plug-arcs 3s linear infinite' if active else 'none' }}; --effect-opacity: {{ 1 if active else 0 }}; /* --- CARD STYLING --- */ {% if active %} background-color: #1c1c1c !important; border: none !important; background-image: radial-gradient(circle at 24px 24px, rgba(var(--active-color), 0.35) 0%, rgba(var(--active-color), 0.1) 40%, transparent 80%), linear-gradient(to right, rgba(255,255,255,0.1), rgba(255,255,255,0.1)) !important; background-size: 100% 100%, 100% 6px !important; background-position: top left, bottom left !important; background-repeat: no-repeat !important; {% else %} /* When Power is 0: Clean slate */ background-image: none !important; box-shadow: none !important; {% endif %} border-radius: 12px; position: relative; overflow: hidden; transition: all 0.5s ease; } /* --- WATTAGE BADGE (Top Right) --- */ ha-card::before { content: '{{ current_w | round(1) }} W'; position: absolute; top: 12px; right: 12px; font-size: 11px; font-weight: 700; letter-spacing: 0.5px; color: var(--text-color); /* Only show badge background if active */ background: {{ 'rgba(0, 0, 0, 0.2)' if active else 'transparent' }}; border: {{ '1px solid rgba(255, 255, 255, 0.1)' if active else 'none' }}; padding: 4px 8px; border-radius: 6px; backdrop-filter: blur(2px); transition: all 0.5s ease; z-index: 2; } /* --- ACTIVE PROGRESS BAR (BEAM) --- */ ha-card::after { content: ''; position: absolute; bottom: 0; left: 0; height: 6px; width: var(--bar-width); background: linear-gradient(90deg, rgba(var(--active-color), 0.4) 0%, rgba(var(--active-color), 1) 100% ); box-shadow: 0 -2px 15px rgba(var(--active-color), 0.9); opacity: var(--bar-opacity); transition: width 0.5s ease-out, opacity 0.5s ease; animation: current-flow 1.5s infinite linear; } @keyframes current-flow { 0% { filter: brightness(1); opacity: 0.8; } 50% { filter: brightness(1.5); opacity: 1; } 100% { filter: brightness(1); opacity: 0.8; } } mushroom-shape-icon { --icon-size: 65px; display: flex; margin: -18px 0 10px -20px !important; padding-right: 15px; padding-bottom: 15px; } mushroom-shape-icon$: > .shape { /* Receive animation variables from Main Card logic */ animation: var(--shape-animation) !important; overflow: visible !important; position: relative; } /* Create the Pseudo-Elements for Glow and Arcs */ .shape::before, .shape::after { content: ''; position: absolute; inset: -4px; border-radius: inherit; pointer-events: none; opacity: var(--effect-opacity); } /* Glow Layer */ .shape::before { animation: var(--plug-glow-animation); } /* Electric Arcs Layer */ .shape::after { animation: var(--plug-arcs-animation); } /* --- ANIMATION KEYFRAMES --- */ /* Note: We use var(--active-color) so the glow stays green even if icon is gray */ @keyframes ultra-plug-on { 0% { transform: scale(1); } 25% { transform: scale(1.05) translateY(-1px); } 50% { transform: scale(1.08) translateY(-2px); } 75% { transform: scale(1.04) translateY(-1px); } 100% { transform: scale(1); } } @keyframes ultra-plug-glow { 0% { box-shadow: 0 0 10px 3px rgba(var(--active-color), 0.6), 0 0 20px 8px rgba(var(--active-color), 0.3); } 50% { box-shadow: 0 0 18px 6px rgba(var(--active-color), 0.9), 0 0 32px 12px rgba(var(--active-color), 0.4); } 100% { box-shadow: 0 0 10px 3px rgba(var(--active-color), 0.6), 0 0 20px 8px rgba(var(--active-color), 0.3); } } @keyframes ultra-plug-arcs { 0% { box-shadow: -10px -6px 0 -4px rgba(var(--active-color), 0.0), 12px 4px 0 -4px rgba(var(--active-color), 0.0); } 25% { box-shadow: -10px -6px 0 -4px rgba(var(--active-color), 0.7), 12px 4px 0 -4px rgba(var(--active-color), 0.4); } 50% { box-shadow: -6px 2px 0 -4px rgba(var(--active-color), 0.3), 10px -8px 0 -4px rgba(var(--active-color), 0.7); } 75% { box-shadow: -12px 4px 0 -4px rgba(var(--active-color), 0.5), 8px 0 0 -4px rgba(var(--active-color), 0.2); } 100% { box-shadow: -10px -6px 0 -4px rgba(var(--active-color), 0.0), 12px 4px 0 -4px rgba(var(--active-color), 0.0); } } grid_options: columns: 12 rows: 1.5 - type: custom:mushroom-entity-card entity: sensor.cuco_cn_2006579195_v3_power_consumption_p_11_1 tap_action: action: more-info name: 用电量 icon: mdi:lightning-bolt primary_info: state secondary_info: name icon_color: light-grey card_mod: style: | ha-card { /* ===== LOGIC & SETTINGS ===== */ {% set state = states(config.entity) %} /* 1. Get the Grass Sensor Data */ {% set grass = states('sensor.cuco_cn_2006579195_v3_power_consumption_p_11_1') %} /* 2. Define Colors based on state */ {% if state in ['high', 'very-high', 'red'] %} {% set c1 = '255, 65, 108' %} /* Red RGB */ {% set c2 = '255, 75, 43' %} /* Orange RGB */ {% set speed = '4s' %} {% elif state in ['moderate', 'medium', 'orange'] %} {% set c1 = '247, 151, 30' %} /* Orange RGB */ {% set c2 = '255, 210, 0' %} /* Yellow RGB */ {% set speed = '7s' %} {% else %} {% set c1 = '0, 242, 96' %} /* Green RGB */ {% set c2 = '5, 117, 230' %} /* Blue RGB */ {% set speed = '12s' %} {% endif %} /* 3. Pass variables to CSS */ --aura-color-1: rgba({{ c1 }}, 0.6); --aura-color-2: rgba({{ c2 }}, 0.6); --speed: {{ speed }}; /* 4. Card Body Styling */ background: #101010 !important; border-radius: 25px; border: 1px solid rgba(255,255,255,0.08); position: relative; overflow: hidden; box-shadow: inset 0 0 20px rgba(0,0,0,0.5); } ha-card::before { content: ""; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; z-index: 0; /* Two radial gradients in one element */ background-image: radial-gradient(circle at 50% 50%, var(--aura-color-1) 0%, transparent 50%), radial-gradient(circle at 80% 80%, var(--aura-color-2) 0%, transparent 50%); filter: blur(60px); opacity: 0.8; animation: rotate-aura var(--speed) linear infinite; } ha-card::after { /* INJECT THE DATA HERE */ content: '{{ grass }}'; position: absolute; top: 50%; right: 16px; transform: translateY(-50%); z-index: 10; /* Badge Styling (Like the battery example) */ color: white; font-weight: 700; font-size: 14px; background: rgba(0, 0, 0, 0.4); border: 1px solid rgba(255, 255, 255, 0.15); backdrop-filter: blur(4px); padding: 4px 10px; border-radius: 12px; text-shadow: 0 1px 2px black; } /* --- GLASS SURFACE OVERLAY --- */ mushroom-shape-icon { --icon-size: 68px; --icon-color: rgba(var(--voc-rgb),1) !important; display: flex; margin: -18px 0 10px -15px !important; padding-right: 22px; padding-bottom: 10px; } ha-card { clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 14px)); --card-primary-font-size: 1.2rem !important; --card-primary-line-height: 1.3 !important; } /* Typography */ .mushroom-state-info span.primary { color: white !important; font-weight: 600 !important; font-size: 16px !important; text-shadow: 0 2px 4px rgba(0,0,0,0.5); } .mushroom-state-info span.secondary { color: rgba(255,255,255,0.8) !important; } /* Icon Styling */ mushroom-shape-icon { --icon-size: 60px; --icon-color: white !important; } ha-state-icon { color: white !important; } /* Animation */ @keyframes rotate-aura { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } grid_options: columns: 12 rows: 1.5 column_span: 1 cards: [] visible: - user: 7a6c93d08acc4692bfd561154bb386df - user: 7809f2c31fda449b8e7c5a0d2eaf5fd5 - type: masonry path: wash cards: - type: custom:mushroom-entity-card entity: sensor.875060396221041554_bsh_common_setting_powerstate name: 洗衣机 icon: mdi:washing-machine primary_info: name secondary_info: state tap_action: action: more-info icon_color: light-grey fill_container: false card_mod: style: .: | ha-card { /* ======================== */ /* USER CONFIGURATION */ /* ======================== */ /* 1. ENTITIES (Update these!) */ {% set ent_status = 'sensor.bshcn_cn_x_13164_37533621_875060396221041554_e0ec0342_k7d00w_status_p_2_24' %} {% set ent_timerem = 'sensor.bshcn_cn_x_13164_37533621_875060396221041554_e0ec0342_k7d00w_left_time_p_2_1' %} {% set max_time = 120 %} {% set ent_power = 'sensor.smart_plug_power' %} /* OPTIONAL Progress Percentage Sensor (if exists) */ {% set ent_percent = 'sensor.875060396221041554_bsh_common_option_programprogress' %} /* 2. SIZES (Px) */ --config-icon-size: 65px; --config-font-primary: 15px; --config-font-secondary: 12px; --config-font-badge: 12px; /* ======================== */ /* --- SENSORS & TIME --- */ {% set status = states(ent_status) %} {% set status_clean = status | replace('-', ' ') | title %} {% set time_rem = states(ent_timerem) | int(0) %} {% set raw_percent = states(ent_percent) | float(-1) %} /* --- POWER CALCULATION --- */ {% set power_w = states(ent_power) | float(0) | round %} {% set power_text = ' • ' ~ power_w ~ 'W' if power_w > 0 else '' %} /* Format Time (min -> Xh Ym) */ {% set hours = (time_rem / 60) | int %} {% set mins = time_rem % 60 %} {% set time_formatted = '%dh %02dm' | format(hours, mins) %} /* --- PROGRESS CALCULATION --- */ {% if status | lower in ['idle', 'off', 'standby', 'unknown', 'unavailable'] %} {% set progress = 0 %} {% set badge_text = status_clean ~ power_text %} {% else %} /* LOGIC: Use Sensor if available, otherwise Calculate */ {% if raw_percent >= 0 %} /* Use the sensor provided percentage */ {% set progress = raw_percent | int %} {% else %} /* Fallback: Calculate based on max_time */ {% set max_cycle_time = max_time %} {% set calc_prog = ((max_cycle_time - time_rem) / max_cycle_time * 100) | int %} {% set progress = [5, [calc_prog, 100] | min] | max %} {% endif %} {% set badge_text = status_clean ~ ' • ' ~ time_formatted ~ power_text %} {% endif %} /* --- STATE DEFINITIONS --- */ {% set s_lower = status | lower %} {% set is_running = s_lower in ['wash', 'washing', 'rinse', 'rinsing', 'pre-wash', 'soak'] %} {% set is_spinning = s_lower in ['spin', 'spinning'] %} {% set is_drying = s_lower in ['dry', 'drying'] %} {% set is_done = s_lower in ['finished', 'complete', 'end'] %} /* --- ASSIGN ANIMATIONS --- */ {% if is_drying %} {% set color = '255, 152, 0' %} /* Orange */ {% set anim_type = 'steam-rise 2s ease-in-out infinite' %} {% set icon_shake = 'none' %} {% set wave_anim = 'wave 4s linear infinite' %} {% set overlay_img = 'linear-gradient(0deg, transparent, rgba(255,255,255,0.5), transparent)' %} {% elif is_spinning %} {% set color = '0, 255, 255' %} /* cyan */ {% set anim_type = 'none' %} {% set icon_shake = 'washer-spin-smooth 0.8s linear infinite' %} {% set wave_anim = 'wave 2s linear infinite' %} /* Fast Wave */ {% set overlay_img = 'radial-gradient(circle, rgba(255,255,255,0.3) 10%, transparent 60%)' %} {% elif is_done %} {% set color = '76, 175, 80' %} /* Green */ {% set anim_type = 'sparkle 2s infinite' %} {% set icon_shake = 'none' %} {% set wave_anim = 'wave 4s linear infinite' %} {% set overlay_img = 'radial-gradient(circle, rgba(255,255,255,0.8) 10%, transparent 60%)' %} {% elif is_running %} {% set color = '33, 150, 243' %} /* Blue */ {% set anim_type = 'bubbles 1s linear infinite' %} {% set icon_shake = 'shake 1.5s ease-in-out infinite' %} /* Slow Shake */ {% set wave_anim = 'wave 4s linear infinite' %} {% set overlay_img = 'radial-gradient(2px 2px at 20% 80%, white, transparent), radial-gradient(2px 2px at 50% 70%, white, transparent)' %} {% else %} {% set color = '158, 158, 158' %} /* Grey */ {% set anim_type = 'none' %} {% set icon_shake = 'none' %} {% set wave_anim = 'none' %} {% set overlay_img = 'none' %} {% endif %} /* --- OUTPUT VARIABLES --- */ --wm-color: {{ color }}; --wm-level: {{ progress }}%; --wm-anim-overlay: {{ anim_type }}; --wm-anim-shake: {{ icon_shake }}; --wm-anim-wave: {{ wave_anim }}; --wm-overlay-bg: {{ overlay_img }}; --wm-badge-content: "{{ badge_text }}"; transition: all 0.5s ease; overflow: hidden; } /* BADGE */ ha-card::before { content: var(--wm-badge-content); position: absolute; top: 10px; right: 10px; background: rgba(var(--wm-color), 0.15); color: rgb(var(--wm-color)); border: 1px solid rgba(var(--wm-color), 0.3); padding: 2px 10px; border-radius: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: var(--config-font-badge); } /* BAR */ ha-card::after { content: ''; position: absolute; bottom: 0; left: 0; height: 4px; width: var(--wm-level); background: rgb(var(--wm-color)); box-shadow: 0 0 10px rgb(var(--wm-color)); transition: width 0.5s ease; } mushroom-shape-icon$: | .shape { --icon-size: var(--config-icon-size) !important; background: rgba(255, 255, 255, 0.05) !important; overflow: hidden; position: relative; border: 1px solid rgba(255,255,255,0.1); /* Apply the animation determined by the Logic below */ animation: var(--wm-anim-shake) !important; transform-origin: center center; } /* Wave Layer */ .shape::before { content: ''; position: absolute; left: -50%; width: 200%; height: 200%; top: calc(100% - var(--wm-level)); background: rgba(var(--wm-color), 0.6); border-radius: 40%; animation: var(--wm-anim-wave); } /* Overlay Layer (Bubbles/Steam) */ .shape::after { content: ''; position: absolute; inset: 0; background-image: var(--wm-overlay-bg); background-size: 100% 100%; animation: var(--wm-anim-overlay); z-index: 2; } /* The Icon Itself */ ha-icon { z-index: 3; mix-blend-mode: overlay; color: white !important; } /* --- KEYFRAMES --- */ @keyframes wave { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes shake { 0%, 100% { transform: rotate(0deg); } 25% { transform: rotate(5deg) translateY(-1px); } 75% { transform: rotate(-5deg) translateY(1px); } } @keyframes bubbles { 0% { transform: translateY(10px); opacity: 0; } 50% { opacity: 1; } 100% { transform: translateY(-20px); opacity: 0; } } @keyframes steam-rise { 0% { opacity: 0; transform: translateY(5px); } 50% { opacity: 0.8; } 100% { opacity: 0; transform: translateY(-10px); } } @keyframes sparkle { 0%, 100% { opacity: 0.3; transform: scale(0.9); } 50% { opacity: 1; transform: scale(1.1); } } @keyframes washer-spin-smooth { 0% { transform: rotate(0deg) translate(0,0); box-shadow: inset 0 0 0 2px rgba(var(--wm-color), 0.7); } 25% { transform: rotate(90deg) translate(0.5px, 0.5px); } 50% { transform: rotate(180deg) translate(0,0); } 75% { transform: rotate(270deg) translate(-0.5px, -0.5px); } 100% { transform: rotate(360deg) translate(0,0); box-shadow: inset 0 0 0 2px rgba(var(--wm-color), 0.7); } } mushroom-state-info$: | .container .primary { font-size: var(--config-font-primary) !important; } .container .secondary { font-size: var(--config-font-secondary) !important; } grid_options: columns: 12 rows: 1 icon: mdi:washing-machine visible: - user: 7a6c93d08acc4692bfd561154bb386df - user: 7809f2c31fda449b8e7c5a0d2eaf5fd5 - type: sections max_columns: 4 title: 测试 path: unknown sections: - type: grid cards: - type: heading heading: 新建部件 visible: - user: 7a6c93d08acc4692bfd561154bb386df - user: 7809f2c31fda449b8e7c5a0d2eaf5fd5 cards: [] - type: sections path: anashost max_columns: 4 title: Anashost icon: mdi:test-tube sections: - type: grid cards: - type: heading heading: 新建部件 - type: custom:stack-in-card mode: vertical keep: outer_padding: false margin: true cards: - type: custom:mushroom-chips-card chips: - type: template entity: >- sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1 icon_color: '{{states(''sensor.livingroom_temp_color_no_rgb'')}}' icon: mdi:thermometer use_entity_picture: true double_tap_action: action: none hold_action: action: none tap_action: action: more-info content: >- {% if is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1','unavailable') %} - {% elif is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1','unknown') %} - {% else %} {{states('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1')}}° {% endif %} - type: template entity: >- sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2 icon_color: light-blue icon: mdi:water-percent name: '' use_entity_picture: true hold_action: action: none double_tap_action: action: none tap_action: action: more-info content: >- {% if is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2','unavailable') %} - {% else %} {{states('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2')}}% {% endif %} - type: template double_tap_action: action: none icon: mdi:lightbulb-group content: |- {% if is_state('sensor.lights_of_count','0') %} {% else %} {{states('sensor.lights_of_count')}} {% endif %} icon_color: |- {% set state = states('sensor.lights_of_count')|float %} {% if state <= 0 %} grey {% else %} amber {% endif %} hold_action: action: none tap_action: action: none entity: sensor.lights_of_count - type: template double_tap_action: action: none icon: mdi:water content: |- {% if is_state('sensor.water_damage_count','0') %} {% else %} {{states('sensor.water_damage_count')}} {% endif %} icon_color: >- {% set state = states('sensor.water_damage_count')|float %} {% if state <= 0 %} grey {% else %} blue {% endif %} hold_action: action: none tap_action: action: none entity: sensor.water_damage_count alignment: center - type: custom:swipe-card mode: vertical keep: outer_padding: false margin: true box_shadow: false background: false cards: - type: horizontal-stack cards: - type: custom:mushroom-entity-card card_mod: style: | ha-card{ box-shadow: none; } entity: input_boolean.on_state double_tap_action: action: none icon: mdi:home icon_color: teal layout: vertical hold_action: action: none tap_action: action: navigate navigation_path: main-home primary_info: none secondary_info: name name: 首页 - type: custom:mushroom-entity-card card_mod: style: | ha-card{ box-shadow: none; } entity: input_boolean.on_state icon: mdi:server icon_color: white layout: vertical primary_info: none secondary_info: name tap_action: action: navigate navigation_path: home-server hold_action: action: none double_tap_action: action: none name: 机房 - type: custom:mushroom-entity-card card_mod: style: | ha-card{ box-shadow: none; } entity: light.quan_wu_zhao_ming icon_color: yellow secondary_info: name layout: vertical name: Lights double_tap_action: action: none hold_action: action: none tap_action: action: more-info primary_info: none icon: mdi:lamps - type: custom:stack-in-card mode: vertical keep: outer_padding: false margin: true cards: - type: custom:mushroom-chips-card chips: - type: template entity: >- sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1 icon_color: '{{states(''sensor.livingroom_temp_color_no_rgb'')}}' icon: mdi:thermometer use_entity_picture: true double_tap_action: action: none hold_action: action: none tap_action: action: more-info content: >- {% if is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1','unavailable') %} - {% elif is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1','unknown') %} - {% else %} {{states('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1')}}° {% endif %} - type: template entity: >- sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2 icon_color: light-blue icon: mdi:water-percent name: '' use_entity_picture: true hold_action: action: none double_tap_action: action: none tap_action: action: more-info content: >- {% if is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2','unavailable') %} - {% else %} {{states('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2')}}% {% endif %} - type: template double_tap_action: action: none icon: mdi:lightbulb-group content: |- {% if is_state('sensor.lights_of_count','0') %} {% else %} {{states('sensor.lights_of_count')}} {% endif %} icon_color: |- {% set state = states('sensor.lights_of_count')|float %} {% if state <= 0 %} grey {% else %} amber {% endif %} hold_action: action: none tap_action: action: none entity: sensor.lights_of_count - type: template double_tap_action: action: none icon: mdi:water content: |- {% if is_state('sensor.water_damage_count','0') %} {% else %} {{states('sensor.water_damage_count')}} {% endif %} icon_color: >- {% set state = states('sensor.water_damage_count')|float %} {% if state <= 0 %} grey {% else %} blue {% endif %} hold_action: action: none tap_action: action: none entity: sensor.water_damage_count alignment: center - type: custom:stack-in-card mode: vertical keep: outer_padding: false margin: true cards: - type: custom:mushroom-chips-card chips: - type: template entity: >- sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1 icon_color: '{{states(''sensor.livingroom_temp_color_no_rgb'')}}' icon: mdi:thermometer use_entity_picture: true double_tap_action: action: none hold_action: action: none tap_action: action: more-info content: >- {% if is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1','unavailable') %} - {% elif is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1','unknown') %} - {% else %} {{states('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1')}}° {% endif %} - type: template entity: >- sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2 icon_color: light-blue icon: mdi:water-percent name: '' use_entity_picture: true hold_action: action: none double_tap_action: action: none tap_action: action: more-info content: >- {% if is_state('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2','unavailable') %} - {% else %} {{states('sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2')}}% {% endif %} - type: template double_tap_action: action: none icon: mdi:lightbulb-group content: |- {% if is_state('sensor.lights_of_count','0') %} {% else %} {{states('sensor.lights_of_count')}} {% endif %} icon_color: |- {% set state = states('sensor.lights_of_count')|float %} {% if state <= 0 %} grey {% else %} amber {% endif %} hold_action: action: none tap_action: action: none entity: sensor.lights_of_count - type: template double_tap_action: action: none icon: mdi:water content: |- {% if is_state('sensor.water_damage_count','0') %} {% else %} {{states('sensor.water_damage_count')}} {% endif %} icon_color: >- {% set state = states('sensor.water_damage_count')|float %} {% if state <= 0 %} grey {% else %} blue {% endif %} hold_action: action: none tap_action: action: none entity: sensor.water_damage_count alignment: center card_mod: style: | ha-card { background-color: rgba(255, 255, 255, 0) !important; box-shadow: none !important; padding: 2px 0px 2px 0px; } visible: - user: 7a6c93d08acc4692bfd561154bb386df - user: 7809f2c31fda449b8e7c5a0d2eaf5fd5 cards: [] - type: sections max_columns: 4 title: 中控 path: control-center icon: mdi:view-dashboard theme: ios-dark-mode-light-blue sections: - type: grid column_span: 4 cards: - type: picture image: media_content_id: /local/images/lbxx.jpg media_content_type: '' metadata: navigateIds: - {} - media_content_type: '' media_content_id: __MANUAL_ENTRY__ grid_options: rows: auto columns: 3 - type: custom:button-card show_icon: false show_name: false show_state: false grid_options: columns: 12 rows: 2 custom_fields: greeting: | [[[ const h = new Date().getHours(); if (h < 6) return "夜深了"; if (h < 11) return "早上好"; if (h < 14) return "中午好"; if (h < 18) return "下午好"; return "晚上好"; ]]] clock: | [[[ return new Date().toLocaleTimeString( 'zh-CN', { hour: '2-digit', minute: '2-digit', hour12: false } ); ]]] date: | [[[ return new Date().toLocaleDateString( 'zh-CN', { month: 'long', day: 'numeric', weekday: 'long' } ); ]]] subtitle: | [[[ const leak = Number(states['sensor.water_damage_count']?.state ?? 0); const lights = Number(states['sensor.lights_of_count']?.state ?? 0); const ac = Number(states['sensor.aircondition_of_count']?.state ?? 0); if (leak > 0) return `⚠ 检测到 ${leak} 个水浸告警`; if (lights === 0 && ac === 0) return "家里一切正常"; return `${lights} 盏灯开启 · ${ac} 台空调运行`; ]]] styles: card: - height: 120px - padding: 20px 24px - border-radius: 24px - border: none - background: >- linear-gradient(135deg, rgba(32,35,42,0.95), rgba(20,22,27,0.95)) - box-shadow: none grid: - grid-template-areas: | "greeting clock" "subtitle date" - grid-template-columns: 1fr auto - grid-template-rows: 1fr 1fr custom_fields: greeting: - justify-self: start - align-self: end - font-size: 30px - font-weight: 700 - color: white subtitle: - justify-self: start - align-self: start - font-size: 14px - color: rgba(255,255,255,0.55) clock: - justify-self: end - align-self: end - font-size: 32px - font-weight: 600 - color: white date: - justify-self: end - align-self: start - font-size: 14px - color: rgba(255,255,255,0.55) - type: grid column_span: 4 cards: - type: custom:button-card entity: weather.he_feng_tian_qi_heweather show_icon: false show_name: false show_state: false grid_options: columns: 6 rows: 3 custom_fields: weather_icon: | [[[ const s = entity?.state; const isNight = states['sun.sun']?.state === 'below_horizon'; if (s === 'sunny') return isNight ? '🌙' : '☀️'; if (s === 'clear-night') return '🌙'; if (s === 'cloudy') return '☁️'; if (s === 'partlycloudy') return isNight ? '☁️' : '⛅'; if (s === 'fog') return '🌫️'; if (s === 'windy' || s === 'windy-variant') return '🌬️'; if (s === 'rainy') return '🌧️'; if (s === 'pouring') return '🌧️'; if (s === 'lightning' || s === 'lightning-rainy') return '⛈️'; if (s === 'hail') return '🌨️'; if (s === 'snowy' || s === 'snowy-rainy') return '❄️'; return '🌤️'; ]]] temp: | [[[ const temp = Number(entity?.attributes?.temperature); return Number.isFinite(temp) ? `${Math.round(temp)}°` : '--°'; ]]] condition: | [[[ const textEntity = states['sensor.he_feng_tian_qi_heweather_text']; if ( textEntity && !['unknown', 'unavailable'].includes(textEntity.state) ) { return textEntity.state; } const map = { sunny: '晴', 'clear-night': '晴', cloudy: '阴', partlycloudy: '多云', fog: '雾', rainy: '小雨', pouring: '大雨', lightning: '雷电', 'lightning-rainy': '雷雨', hail: '冰雹', snowy: '雪', 'snowy-rainy': '雨夹雪', windy: '有风', 'windy-variant': '大风' }; return map[entity?.state] ?? '--'; ]]] forecast: | [[[ const feelsLike = Number(entity?.attributes?.apparent_temperature); if (Number.isFinite(feelsLike)) { return `今天 · 体感 ${Math.round(feelsLike)}°`; } return '今天'; ]]] humidity: | [[[ const humidity = Number(entity?.attributes?.humidity); return Number.isFinite(humidity) ? `湿度 ${Math.round(humidity)}%` : '湿度 --'; ]]] styles: card: - height: 175px - border-radius: 24px - border: none - padding: 22px - overflow: hidden - background: | linear-gradient( 145deg, #334b68 0%, #23334a 55%, #172131 100% ) - box-shadow: none grid: - grid-template-areas: | "weather_icon temp" "weather_icon condition" "forecast humidity" - grid-template-columns: 1.3fr 1fr - grid-template-rows: 2fr 1fr 1fr custom_fields: weather_icon: - font-size: 74px - align-self: center - justify-self: center - animation: weatherFloat 5s ease-in-out infinite temp: - font-size: 46px - font-weight: 700 - justify-self: start - align-self: end - color: white condition: - font-size: 17px - align-self: start - justify-self: start - color: rgba(255,255,255,0.7) forecast: - font-size: 13px - align-self: end - justify-self: center - color: rgba(255,255,255,0.6) humidity: - font-size: 13px - align-self: end - justify-self: start - color: rgba(255,255,255,0.6) extra_styles: | @keyframes weatherFloat { 0% { transform: translateY(0px) scale(1); } 50% { transform: translateY(-6px) scale(1.03); } 100% { transform: translateY(0px) scale(1); } } - square: false type: grid cards: - type: custom:vertical-stack-in-card cards: - type: custom:mushroom-entity-card entity: >- sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_temperature_p_2_1 tap_action: action: more-info icon: mdi:thermometer name: 温度 primary_info: state secondary_info: name card_mod: style: mushroom-shape-icon$: | .shape { {# ========== CONFIG ========== #} {# == Updated: entity auto generated == #} {% set temp = states(config.entity) | float(0) %} {# ------------------------------------------- #} {# TEMPERATURE → COLOR + EFFECT PRESETS #} {# ------------------------------------------- #} {# DEFAULTS (will be overridden by ranges) #} {% set rgb = '0,140,255' %} {% set anim = 'temp-cold-breathe' %} {% set glow_anim = 'temp-cold-glow' %} {% set halo_anim = 'temp-cold-halo' %} {% set duration = 4.0 %} {% set intensity = 0.5 %} {# RANGES / COLORS #} {# You can change temp numbers below if needed #} {% if temp < 16 %} {# BLUE #} {% set rgb = '0,140,255' %} {% set anim = 'temp-cold-breathe' %} {% set glow_anim = 'temp-cold-glow' %} {% set halo_anim = 'temp-cold-halo' %} {% set duration = 4.4 %} {% set intensity = 0.4 %} {% elif temp < 18 %} {# YELLOW #} {% set rgb = '255,210,40' %} {% set anim = 'temp-cool-wave' %} {% set glow_anim = 'temp-cool-glow' %} {% set halo_anim = 'temp-cool-halo' %} {% set duration = 3.4 %} {% set intensity = 0.55 %} {% elif temp < 20 %} {# ORANGE #} {% set rgb = '255,150,40' %} {% set anim = 'temp-comfy-breathe' %} {% set glow_anim = 'temp-comfy-glow' %} {% set halo_anim = 'temp-comfy-halo' %} {% set duration = 3.0 %} {% set intensity = 0.6 %} {% elif temp < 22 %} {# DARK ORANGE #} {% set rgb = '255,115,20' %} {% set anim = 'temp-warm-pulse' %} {% set glow_anim = 'temp-warm-glow' %} {% set halo_anim = 'temp-warm-halo' %} {% set duration = 2.4 %} {% set intensity = 0.8 %} {% else %} {# RED #} {% set rgb = '255,40,40' %} {% set anim = 'temp-hot-shimmer' %} {% set glow_anim = 'temp-hot-glow' %} {% set halo_anim = 'temp-hot-halo' %} {% set duration = 2.0 %} {% set intensity = 1.0 %} {% endif %} {# Apply variables #} --temp-rgb: {{ rgb }}; --temp-intensity: {{ intensity }}; --shape-animation: {{ anim }} {{ duration }}s ease-in-out infinite; --temp-glow-animation: {{ glow_anim }} {{ (duration * 0.9) | round(2) }}s ease-in-out infinite; --temp-halo-animation: {{ halo_anim }} {{ (duration * 1.15) | round(2) }}s ease-in-out infinite; opacity: 1; /* Icon color follows the temperature */ --icon-color: rgba({{ rgb }}, 1); /* KILL THE THEME BLUE & MAKE SHAPE NEUTRAL */ background-color: rgba(77, 77, 77,0.1) !important; box-shadow: none !important; border: 1px solid rgba(255,255,255,0.06); position: relative; transform-origin: 50% 60%; animation: var(--shape-animation); } /* Glow layers */ .shape::before, .shape::after { content: ''; position: absolute; border-radius: inherit; pointer-events: none; } .shape::before { inset: -8px; animation: var(--temp-glow-animation); } .shape::after { inset: -22px; animation: var(--temp-halo-animation); mix-blend-mode: screen; } /* ========== COLD ========== */ @keyframes temp-cold-breathe { 0% { transform: scale(0.96); } 50% { transform: scale(1.03); } 100% { transform: scale(0.96); } } @keyframes temp-cold-glow { 0% { box-shadow: 0 0 20px 0 rgba(var(--temp-rgb), 0.6), 0 0 34px 6 rgba(var(--temp-rgb), 0.55); } 50% { box-shadow: 0 0 30px 4 rgba(var(--temp-rgb), 0.95), 0 0 50px 10px rgba(var(--temp-rgb), 0.85); } 100% { box-shadow: 0 0 20px 0 rgba(var(--temp-rgb), 0.6), 0 0 34px 6 rgba(var(--temp-rgb), 0.55); } } @keyframes temp-cold-halo { 0% { box-shadow: 0 0 80px 20px rgba(var(--temp-rgb), 0.35), 0 -20px 80px -14px rgba(220, 240, 255, 0.55); } 50% { box-shadow: 0 0 130px 36px rgba(var(--temp-rgb), 0.5), 0 -34px 100px -8px rgba(240, 250, 255, 0.8); } 100% { box-shadow: 0 0 80px 20px rgba(var(--temp-rgb), 0.35), 0 -20px 80px -14px rgba(220, 240, 255, 0.55); } } /* ========== COOL ========== */ @keyframes temp-cool-wave { 0% { transform: translateX(0); } 25% { transform: translateX(-1px); } 50% { transform: translateX(1px) translateY(-1px); } 75% { transform: translateX(-1px); } 100% { transform: translateX(0); } } @keyframes temp-cool-glow { 0% { box-shadow: 0 0 22px 0 rgba(var(--temp-rgb), 0.6), 0 0 34px 4 rgba(var(--temp-rgb), 0.7); } 50% { box-shadow: 0 0 28px 2 rgba(var(--temp-rgb), 0.95), 0 0 48px 12px rgba(var(--temp-rgb), 0.85); } 100% { box-shadow: 0 0 22px 0 rgba(var(--temp-rgb), 0.6), 0 0 34px 4 rgba(var(--temp-rgb), 0.7); } } @keyframes temp-cool-halo { 0% { box-shadow: 0 0 90px 26px rgba(var(--temp-rgb), 0.35), 0 18px 80px -12px rgba(0, 220, 255, 0.35); } 50% { box-shadow: 0 0 140px 42px rgba(var(--temp-rgb), 0.45), 0 30px 110px -10px rgba(0, 255, 255, 0.5); } 100% { box-shadow: 0 0 90px 26px rgba(var(--temp-rgb), 0.35), 0 18px 80px -12px rgba(0, 220, 255, 0.35); } } /* ========== COMFY ========== */ @keyframes temp-comfy-breathe { 0% { transform: scale(0.98); } 50% { transform: scale(1.05); } 100% { transform: scale(0.98); } } @keyframes temp-comfy-glow { 50% { box-shadow: 0 0 26px 4 rgba(var(--temp-rgb), 0.9), 0 0 42px 10px rgba(var(--temp-rgb), 0.85); } } @keyframes temp-comfy-halo { 50% { box-shadow: 0 0 120px 40px rgba(var(--temp-rgb), 0.45), 0 26px 80px -10px rgba(180,255,200,0.5); } } /* ========== WARM ========== */ @keyframes temp-warm-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.07); } 100% { transform: scale(1); } } @keyframes temp-warm-glow { 50% { box-shadow: 0 0 30px 4 rgba(var(--temp-rgb), 0.95), 0 0 54px 14px rgba(var(--temp-rgb), 0.9); } } @keyframes temp-warm-halo { 50% { box-shadow: 0 0 140px 48px rgba(var(--temp-rgb), 0.55), 0 26px 100px -10px rgba(255,210,150,0.5); } } /* ========== HOT ========== */ @keyframes temp-hot-shimmer { 0% { transform: scale(1); filter: blur(0); } 50% { transform: scale(1.08); filter: blur(0.6px); } 100% { transform: scale(1); filter: blur(0); } } @keyframes temp-hot-glow { 50% { box-shadow: 0 0 34px 6 rgba(var(--temp-rgb), 1), 0 0 62px 14px rgba(var(--temp-rgb), 0.95); } } @keyframes temp-hot-halo { 50% { box-shadow: 0 0 160px 60px rgba(var(--temp-rgb), 0.6), 0 34px 120px -12px rgba(255,150,100,0.6); } } .: | mushroom-shape-icon { --icon-size: 48px; --icon-color: rgba(var(--hum-rgb),1) !important; display: flex; margin: -16px 0 10px -20px !important; padding-right: 22px; padding-bottom: 18px; } ha-card { clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 14px)); /* FONT SIZE & SPACING SETTINGS */ --card-primary-font-size: 1.4rem !important; /* Increases vertical space between primary and secondary */ --card-primary-line-height: 1.3 !important; } - type: custom:vertical-stack-in-card cards: - type: custom:mini-graph-card entities: - >- sensor.xiaomi_cn_blt_3_1ni9qhv584c03_mini_temperature_p_2_1001 hours_to_show: 24 line_width: 5 show: name: false icon: false state: false labels: false legend: false color_thresholds: - value: 0 color: blue - value: 16 color: lightblue - value: 18 color: orange - value: 21 color: red card_mod: style: | ha-card { background: none; box-shadow: none; opacity: 50%; border: none; width: 250px; mask-image: radial-gradient( ellipse at center, rgba(0,0,0,1) 0%, rgba(0,0,0,0) 90% ); } card_mod: style: .: | ha-card { background: none; box-shadow: none; border: none; margin: 8px 12px; position: absolute; bottom: -10px; right: -10px; } - type: custom:vertical-stack-in-card cards: - type: custom:mushroom-entity-card entity: >- sensor.miaomiaoc_cn_blt_3_1ndt1bnq04c04_t1_relative_humidity_p_2_2 tap_action: action: more-info icon: mdi:water-percent name: 湿度 primary_info: state secondary_info: name card_mod: style: mushroom-shape-icon$: > .shape { {# ========== CONFIG ========== #} {# == Updated: entity auto generated == #} {% set hum = states(config.entity) | float(0) %} {# DEFAULTS #} {% set rgb = '120,210,255' %} {% set anim = 'hum-good-breathe' %} {% set glow_anim = 'hum-good-glow' %} {% set halo_anim = 'hum-good-halo' %} {% set duration = 3.2 %} {# RANGES < 40 -> BAD (dark blue) 40-60 -> GOOD (light blue) > 60 -> MIDDLE / humid (medium blue) #} {% if hum < 40 %} {# BAD - dry - dark blue #} {% set rgb = '0,80,200' %} {% set anim = 'hum-bad-pulse' %} {% set glow_anim = 'hum-bad-glow' %} {% set halo_anim = 'hum-bad-halo' %} {% set duration = 2.8 %} {% elif hum <= 60 %} {# GOOD - light blue #} {% set rgb = '120,210,255' %} {% set anim = 'hum-good-breathe' %} {% set glow_anim = 'hum-good-glow' %} {% set halo_anim = 'hum-good-halo' %} {% set duration = 3.4 %} {% else %} {# MIDDLE / humid - medium blue #} {% set rgb = '40,140,255' %} {% set anim = 'hum-mid-wave' %} {% set glow_anim = 'hum-mid-glow' %} {% set halo_anim = 'hum-mid-halo' %} {% set duration = 3.0 %} {% endif %} --hum-rgb: {{ rgb }}; --shape-animation: {{ anim }} {{ duration }}s ease-in-out infinite; --hum-glow-animation: {{ glow_anim }} {{ (duration * 0.9) | round(2) }}s ease-in-out infinite; --hum-halo-animation: {{ halo_anim }} {{ (duration * 1.1) | round(2) }}s ease-in-out infinite; /* Icon color follows humidity color */ --icon-color: rgba({{ rgb }}, 1); /* Neutral pill so theme blue does not leak through */ background-color: rgba(77,77,77,0.2) !important; box-shadow: none !important; border: 1px solid rgba(255,255,255,0.06); opacity: 1; position: relative; transform-origin: 50% 60%; animation: var(--shape-animation); } /* Glow layers */ .shape::before, .shape::after { content: ''; position: absolute; border-radius: inherit; pointer-events: none; } .shape::before { inset: -8px; animation: var(--hum-glow-animation); } .shape::after { inset: -22px; animation: var(--hum-halo-animation); mix-blend-mode: screen; } /* ========== GOOD - light blue ========== */ @keyframes hum-good-breathe { 0% { transform: scale(0.98); } 50% { transform: scale(1.04); } 100% { transform: scale(0.98); } } @keyframes hum-good-glow { 0% { box-shadow: 0 0 18px 0 rgba(var(--hum-rgb), 0.55), 0 0 30px 4 rgba(var(--hum-rgb), 0.6); } 50% { box-shadow: 0 0 24px 4 rgba(var(--hum-rgb), 0.9), 0 0 44px 10px rgba(var(--hum-rgb), 0.85); } 100% { box-shadow: 0 0 18px 0 rgba(var(--hum-rgb), 0.55), 0 0 30px 4 rgba(var(--hum-rgb), 0.6); } } @keyframes hum-good-halo { 0% { box-shadow: 0 0 80px 24px rgba(var(--hum-rgb), 0.35), 0 18px 70px -12px rgba(180,230,255,0.3); } 50% { box-shadow: 0 0 120px 40px rgba(var(--hum-rgb), 0.45), 0 26px 90px -10px rgba(200,240,255,0.45); } 100% { box-shadow: 0 0 80px 24px rgba(var(--hum-rgb), 0.35), 0 18px 70px -12px rgba(180,230,255,0.3); } } /* ========== MIDDLE / humid - medium blue ========== */ @keyframes hum-mid-wave { 0% { transform: translateX(0); } 25% { transform: translateX(-1px); } 50% { transform: translateX(1px) translateY(-1px); } 75% { transform: translateX(-1px); } 100% { transform: translateX(0); } } @keyframes hum-mid-glow { 0% { box-shadow: 0 0 20px 0 rgba(var(--hum-rgb), 0.6), 0 0 32px 4 rgba(var(--hum-rgb), 0.7); } 50% { box-shadow: 0 0 28px 3 rgba(var(--hum-rgb), 0.95), 0 0 48px 10px rgba(var(--hum-rgb), 0.85); } 100% { box-shadow: 0 0 20px 0 rgba(var(--hum-rgb), 0.6), 0 0 32px 4 rgba(var(--hum-rgb), 0.7); } } @keyframes hum-mid-halo { 0% { box-shadow: 0 0 90px 26px rgba(var(--hum-rgb), 0.4), 0 18px 80px -12px rgba(80,190,255,0.35); } 50% { box-shadow: 0 0 135px 42px rgba(var(--hum-rgb), 0.5), 0 28px 105px -10px rgba(100,210,255,0.5); } 100% { box-shadow: 0 0 90px 26px rgba(var(--hum-rgb), 0.4), 0 18px 80px -12px rgba(80,190,255,0.35); } } /* ========== BAD - dry - dark blue ========== */ @keyframes hum-bad-pulse { 0% { transform: scale(0.97); } 40% { transform: scale(1.03); } 100% { transform: scale(0.97); } } @keyframes hum-bad-glow { 0% { box-shadow: 0 0 18px 0 rgba(var(--hum-rgb), 0.6), 0 0 28px 4 rgba(var(--hum-rgb), 0.7); } 50% { box-shadow: 0 0 26px 4 rgba(var(--hum-rgb), 0.95), 0 0 44px 12px rgba(var(--hum-rgb), 0.9); } 100% { box-shadow: 0 0 18px 0 rgba(var(--hum-rgb), 0.6), 0 0 28px 4 rgba(var(--hum-rgb), 0.7); } } @keyframes hum-bad-halo { 0% { box-shadow: 0 0 80px 22px rgba(var(--hum-rgb), 0.45), 0 18px 75px -10px rgba(0,70,160,0.5); } 50% { box-shadow: 0 0 130px 40px rgba(var(--hum-rgb), 0.6), 0 26px 100px -8px rgba(0,90,190,0.65); } 100% { box-shadow: 0 0 80px 22px rgba(var(--hum-rgb), 0.45), 0 18px 75px -10px rgba(0,70,160,0.5); } } .: | mushroom-shape-icon { --icon-size: 48px; --icon-color: rgba(var(--hum-rgb),1) !important; display: flex; margin: -16px 0 10px -20px !important; padding-right: 22px; padding-bottom: 18px; } ha-card { clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 14px)); /* FONT SIZE & SPACING SETTINGS */ --card-primary-font-size: 1.4rem !important; /* Increases vertical space between primary and secondary */ --card-primary-line-height: 1.3 !important; } - type: custom:vertical-stack-in-card cards: - type: custom:mini-graph-card entities: - >- sensor.xiaomi_cn_blt_3_1ni9qhv584c03_mini_relative_humidity_p_2_1002 line_color: lightblue line_width: 5 hours_to_show: 24 show: name: false icon: false state: false labels: false legend: false card_mod: style: | ha-card { background: none; box-shadow: none; opacity: 50%; border: none; width: 250px; mask-image: radial-gradient( ellipse at center, rgba(0,0,0,1) 0%, rgba(0,0,0,0) 90% ); } card_mod: style: .: | ha-card { background: none; box-shadow: none; border: none; margin: 8px 12px; position: absolute; bottom: -10px; right: -10px; } - type: custom:mushroom-entity-card entity: sensor.xiaomi_cn_2005161482_va3_air_quality_p_3_3 tap_action: action: more-info icon: mdi:air-filter name: 卧室 primary_info: state secondary_info: name fill_container: false card_mod: style: mushroom-shape-icon$: | .shape { {# ========== CONFIG ========== #} {% set voc = states('sensor.livingroom_air_quality_voc') | float(0) %} {# DEFAULTS (will be overridden by ranges) #} {% set rgb = '40,200,120' %} {% set anim = 'voc-clean-breathe' %} {% set glow_anim = 'voc-clean-glow' %} {% set halo_anim = 'voc-clean-halo' %} {% set duration = 4.0 %} {% set intensity = 0.5 %} {# RANGES / COLORS #} {# You can change numbers below if needed #} {% if voc < 100 %} {# GREEN #} {% set rgb = '40,200,120' %} {% set anim = 'voc-clean-breathe' %} {% set glow_anim = 'voc-clean-glow' %} {% set halo_anim = 'voc-clean-halo' %} {% set duration = 4.4 %} {% set intensity = 0.45 %} {% elif voc < 200 %} {# YELLOW-GREEN #} {% set rgb = '140,220,80' %} {% set anim = 'voc-good-wave' %} {% set glow_anim = 'voc-good-glow' %} {% set halo_anim = 'voc-good-halo' %} {% set duration = 3.6 %} {% set intensity = 0.55 %} {% elif voc < 300 %} {# YELLOW #} {% set rgb = '255,210,40' %} {% set anim = 'voc-fair-breathe' %} {% set glow_anim = 'voc-fair-glow' %} {% set halo_anim = 'voc-fair-halo' %} {% set duration = 3.0 %} {% set intensity = 0.7 %} {% elif voc < 400 %} {# ORANGE #} {% set rgb = '255,140,40' %} {% set anim = 'voc-poor-pulse' %} {% set glow_anim = 'voc-poor-glow' %} {% set halo_anim = 'voc-poor-halo' %} {% set duration = 2.4 %} {% set intensity = 0.9 %} {% else %} {# RED #} {% set rgb = '255,50,50' %} {% set anim = 'voc-bad-shimmer' %} {% set glow_anim = 'voc-bad-glow' %} {% set halo_anim = 'voc-bad-halo' %} {% set duration = 2.0 %} {% set intensity = 1.0 %} {% endif %} {# Apply variables #} --voc-rgb: {{ rgb }}; --voc-intensity: {{ intensity }}; --shape-animation: {{ anim }} {{ duration }}s ease-in-out infinite; --voc-glow-animation: {{ glow_anim }} {{ (duration * 0.9) | round(2) }}s ease-in-out infinite; --voc-halo-animation: {{ halo_anim }} {{ (duration * 1.15) | round(2) }}s ease-in-out infinite; opacity: 1; /* Icon color follows VOC level */ --icon-color: rgba({{ rgb }}, 1); /* Shape neutral base */ background-color: rgba(77, 77, 77,0.1) !important; box-shadow: none !important; border: 1px solid rgba(255,255,255,0.06); position: relative; transform-origin: 50% 60%; animation: var(--shape-animation); } /* Glow layers */ .shape::before, .shape::after { content: ''; position: absolute; border-radius: inherit; pointer-events: none; } .shape::before { inset: -8px; animation: var(--voc-glow-animation); } .shape::after { inset: -22px; animation: var(--voc-halo-animation); mix-blend-mode: screen; } /* ========== CLEAN ========== */ @keyframes voc-clean-breathe { 0% { transform: scale(0.96); } 50% { transform: scale(1.03); } 100% { transform: scale(0.96); } } @keyframes voc-clean-glow { 0% { box-shadow: 0 0 20px 0 rgba(var(--voc-rgb), 0.55), 0 0 34px 6 rgba(var(--voc-rgb), 0.5); } 50% { box-shadow: 0 0 30px 4 rgba(var(--voc-rgb), 0.9), 0 0 50px 10px rgba(var(--voc-rgb), 0.85); } 100% { box-shadow: 0 0 20px 0 rgba(var(--voc-rgb), 0.55), 0 0 34px 6 rgba(var(--voc-rgb), 0.5); } } @keyframes voc-clean-halo { 0% { box-shadow: 0 0 80px 20px rgba(var(--voc-rgb), 0.28), 0 -20px 80px -14px rgba(200, 255, 230, 0.45); } 50% { box-shadow: 0 0 130px 36px rgba(var(--voc-rgb), 0.42), 0 -34px 100px -8px rgba(220, 255, 240, 0.65); } 100% { box-shadow: 0 0 80px 20px rgba(var(--voc-rgb), 0.28), 0 -20px 80px -14px rgba(200, 255, 230, 0.45); } } /* ========== GOOD ========== */ @keyframes voc-good-wave { 0% { transform: translateX(0); } 25% { transform: translateX(-1px); } 50% { transform: translateX(1px) translateY(-1px); } 75% { transform: translateX(-1px); } 100% { transform: translateX(0); } } @keyframes voc-good-glow { 0% { box-shadow: 0 0 22px 0 rgba(var(--voc-rgb), 0.55), 0 0 34px 4 rgba(var(--voc-rgb), 0.6); } 50% { box-shadow: 0 0 28px 2 rgba(var(--voc-rgb), 0.9), 0 0 48px 12px rgba(var(--voc-rgb), 0.8); } 100% { box-shadow: 0 0 22px 0 rgba(var(--voc-rgb), 0.55), 0 0 34px 4 rgba(var(--voc-rgb), 0.6); } } @keyframes voc-good-halo { 0% { box-shadow: 0 0 90px 26px rgba(var(--voc-rgb), 0.3), 0 18px 80px -12px rgba(140, 255, 120, 0.25); } 50% { box-shadow: 0 0 140px 42px rgba(var(--voc-rgb), 0.4), 0 30px 110px -10px rgba(160, 255, 140, 0.4); } 100% { box-shadow: 0 0 90px 26px rgba(var(--voc-rgb), 0.3), 0 18px 80px -12px rgba(140, 255, 120, 0.25); } } /* ========== FAIR ========== */ @keyframes voc-fair-breathe { 0% { transform: scale(0.98); } 50% { transform: scale(1.05); } 100% { transform: scale(0.98); } } @keyframes voc-fair-glow { 50% { box-shadow: 0 0 26px 4 rgba(var(--voc-rgb), 0.85), 0 0 42px 10px rgba(var(--voc-rgb), 0.8); } } @keyframes voc-fair-halo { 50% { box-shadow: 0 0 120px 40px rgba(var(--voc-rgb), 0.42), 0 26px 80px -10px rgba(255, 245, 180, 0.5); } } /* ========== POOR ========== */ @keyframes voc-poor-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.07); } 100% { transform: scale(1); } } @keyframes voc-poor-glow { 50% { box-shadow: 0 0 30px 4 rgba(var(--voc-rgb), 0.95), 0 0 54px 14px rgba(var(--voc-rgb), 0.9); } } @keyframes voc-poor-halo { 50% { box-shadow: 0 0 140px 48px rgba(var(--voc-rgb), 0.52), 0 26px 100px -10px rgba(255, 210, 150, 0.5); } } /* ========== BAD ========== */ @keyframes voc-bad-shimmer { 0% { transform: scale(1); filter: blur(0); } 50% { transform: scale(1.08); filter: blur(0.6px); } 100% { transform: scale(1); filter: blur(0); } } @keyframes voc-bad-glow { 50% { box-shadow: 0 0 34px 6 rgba(var(--voc-rgb), 1), 0 0 62px 14px rgba(var(--voc-rgb), 0.95); } } @keyframes voc-bad-halo { 50% { box-shadow: 0 0 160px 60px rgba(var(--voc-rgb), 0.6), 0 34px 120px -12px rgba(255, 140, 120, 0.6); } } .: | mushroom-shape-icon { --icon-size: 48px; --icon-color: rgba(var(--voc-rgb),1) !important; display: flex; margin: -10px 0 10px -20px !important; padding-right: 22px; padding-bottom: 10px; } ha-card { clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 14px)); --card-primary-font-size: 1.5rem !important; --card-primary-line-height: 1.3 !important; } - type: custom:mushroom-entity-card entity: sensor.water_damage_count tap_action: action: none icon: mdi:water name: 水浸设备数 card_mod: style: mushroom-shape-icon$: | .shape { {# ========== USER CONFIG ========== #} {# true = number mode, false = state mode #} {% set use_number = true %} {# STATE MODE SETTINGS #} {% set state_entity = 'switch.plug_6_local' %} {% set active_value = 'on' %} {# OPTIONAL: NUMBER MODE SETTINGS #} {% set number_entity = 'sensor.water_damage_count' %} {# '>' '<' '=' '>=' '<=' #} {% set number_operator = '>' %} {% set threshold = 0.0 %} {# ========== END USER CONFIG ====== #} {# ======== TRIGGER DECISION LOGIC ======== #} {% if use_number %} {% set num = states(number_entity) | float(0) %} {% if number_operator == '>' %} {% set trigger_active = (num > threshold) %} {% elif number_operator == '<' %} {% set trigger_active = (num < threshold) %} {% elif number_operator == '=' %} {% set trigger_active = (num == threshold) %} {% elif number_operator == '>=' %} {% set trigger_active = (num >= threshold) %} {% elif number_operator == '<=' %} {% set trigger_active = (num <= threshold) %} {% else %} {% set trigger_active = false %} {% endif %} {% else %} {# default: simple equality state trigger #} {% set trigger_active = (states(state_entity) == active_value) %} {% endif %} {# =========== END TRIGGER LOGIC =========== #} {% if trigger_active %} --shape-animation: doorbell-ring 0.9s ease-out infinite; opacity: 1; {% else %} --shape-animation: none; opacity: 0.8; {% endif %} transform-origin: 50% 50%; } @keyframes doorbell-ring { 0% { transform: scale(1.05); box-shadow: 0 0 0 0 rgba(var(--rgb-{{ config.icon_color }}), 1), 0 0 0 0 rgba(var(--rgb-{{ config.icon_color }}), 0.8), 0 0 0 0 rgba(var(--rgb-{{ config.icon_color }}), 0.4); } 30% { transform: scale(0.95); box-shadow: 0 0 0 4px rgba(var(--rgb-{{ config.icon_color }}), 0.9), 0 0 0 10px rgba(var(--rgb-{{ config.icon_color }}), 0.7), 0 0 0 18px rgba(var(--rgb-{{ config.icon_color }}), 0.4); } 60% { transform: scale(1.02); box-shadow: 0 0 0 10px rgba(var(--rgb-{{ config.icon_color }}), 0.0), 0 0 0 18px rgba(var(--rgb-{{ config.icon_color }}), 0.2), 0 0 0 26px rgba(var(--rgb-{{ config.icon_color }}), 0.0); } 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(var(--rgb-{{ config.icon_color }}), 0.0), 0 0 0 0 rgba(var(--rgb-{{ config.icon_color }}), 0.0), 0 0 0 0 rgba(var(--rgb-{{ config.icon_color }}), 0.0); } } @keyframes doorbell-idle { 0% { transform: scale(1); } 50% { transform: scale(1.03); } 100% { transform: scale(1); } } .: | mushroom-shape-icon { --icon-size: 65px; display: flex; margin: -18px 0 10px -20px !important; padding-right: 10px; } ha-card { clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 12px)); } columns: 2 - type: grid column_span: 4 cards: - type: heading heading: 快捷控制 icon: mdi:lightning-bolt heading_style: title - type: custom:mushroom-template-card entity: light.quan_wu_zhao_ming primary: 全屋灯光 secondary: > {% set n = states('sensor.lights_of_count') | int(0) %} {% if n > 0 %}{{ n }} 盏开启{% else %}全部关闭{% endif %} icon: mdi:lightbulb-group icon_color: > {% if states('sensor.lights_of_count') | int(0) > 0 %}amber{% else %}grey{% endif %} tap_action: action: more-info hold_action: action: toggle grid_options: columns: 4 rows: 1 - type: custom:mushroom-template-card entity: climate.qdhkl_cn_2113954983_b19c primary: 空调 secondary: | {% if is_state(config.entity,'off') %} 已关闭 {% else %} {{ state_attr(config.entity,'temperature') }}°C {% endif %} icon: mdi:snowflake icon_color: > {% if is_state(config.entity,'off') %}grey{% else %}blue{% endif %} tap_action: action: more-info grid_options: columns: 4 rows: 1 - type: custom:mushroom-template-card entity: fan.xiaomi_cn_2005161482_va3_s_2_air_purifier primary: 空气净化器 secondary: | {% if is_state(config.entity,'on') %}运行中{% else %}已关闭{% endif %} icon: mdi:air-purifier icon_color: | {% if is_state(config.entity,'on') %}cyan{% else %}grey{% endif %} tap_action: action: toggle hold_action: action: more-info grid_options: columns: 4 rows: 1 - type: custom:mushroom-template-card entity: fan.xiaomi_cn_2196552583_p90_s_2_fan primary: 风扇 secondary: | {% if is_state(config.entity,'on') %}运行中{% else %}已关闭{% endif %} icon: mdi:fan icon_color: > {% if is_state(config.entity,'on') %}light-blue{% else %}grey{% endif %} tap_action: action: toggle hold_action: action: more-info grid_options: columns: 4 rows: 1 - type: custom:mushroom-template-card entity: cover.panpan_cn_876603548_y18_s_2_airer primary: 晾衣架 secondary: | {{ states(config.entity) }} icon: mdi:hanger icon_color: teal tap_action: action: more-info grid_options: columns: 4 rows: 1 - type: custom:mushroom-template-card entity: switch.cuco_cn_2006579195_v3_on_p_2_1 primary: NAS secondary: > {{ states('sensor.cuco_cn_2006579195_v3_electric_power_p_11_2') }} W icon: mdi:nas icon_color: | {% if is_state(config.entity,'on') %}red{% else %}grey{% endif %} tap_action: action: navigate navigation_path: home-server grid_options: columns: 4 rows: 1 - type: grid column_span: 4 cards: - type: heading heading: 房间灯光 icon: mdi:floor-plan heading_style: title - type: custom:mushroom-light-card entity: light.pmfbj_cn_1187112198_xsx340_s_2 name: 客厅 icon: mdi:sofa use_light_color: true show_brightness_control: true show_color_temp_control: true grid_options: columns: 4 rows: 2 - type: custom:mushroom-light-card entity: light.shhf_cn_1129134246_sflt11_s_2_light name: 餐桌 icon: mdi:table-chair use_light_color: true show_brightness_control: true show_color_temp_control: true grid_options: columns: 4 rows: 2 - type: custom:mushroom-light-card entity: light.pmfbj_cn_1186735998_xsx340_s_2 name: 主卧 icon: mdi:bed-king use_light_color: true show_brightness_control: true show_color_temp_control: true grid_options: columns: 4 rows: 2 - type: custom:mushroom-light-card entity: light.pmfbj_cn_1186772227_xsx340_s_2 name: 次卧 icon: mdi:bed-single use_light_color: true show_brightness_control: true show_color_temp_control: true grid_options: columns: 4 rows: 2 - type: custom:mushroom-light-card entity: light.pmfbj_cn_1186744390_xsx340_s_2 name: 书房 icon: mdi:desk use_light_color: true show_brightness_control: true show_color_temp_control: true grid_options: columns: 4 rows: 2 - type: custom:mushroom-light-card entity: light.opple_cn_2005385416_moat_s_2_light name: 阳台 icon: mdi:balcony use_light_color: true show_brightness_control: true show_color_temp_control: true grid_options: columns: 4 rows: 2 header: layout: responsive badges_position: bottom badges_wrap: wrap background: opacity: 80 alignment: center size: cover repeat: repeat attachment: fixed cards: [] - title: 首页 path: home icon: mdi:home type: sections max_columns: 4 sections: - type: grid cards: - type: custom:button-card show_icon: false show_name: false show_state: false grid_options: columns: 12 rows: 2 custom_fields: greeting: | [[[ const h = new Date().getHours(); if (h < 6) return "夜深了"; if (h < 11) return "早上好"; if (h < 14) return "中午好"; if (h < 18) return "下午好"; return "晚上好"; ]]] clock: | [[[ return new Date().toLocaleTimeString( 'zh-CN', { hour: '2-digit', minute: '2-digit', hour12: false } ); ]]] date: | [[[ return new Date().toLocaleDateString( 'zh-CN', { month: 'long', day: 'numeric', weekday: 'long' } ); ]]] subtitle: | 家里一切正常 styles: card: - height: 130px - padding: 20px 24px - border-radius: 24px - border: none - background: | linear-gradient( 135deg, rgba(32,35,42,0.95), rgba(20,22,27,0.95) ) - box-shadow: none grid: - grid-template-areas: | "greeting clock" "subtitle date" - grid-template-columns: 1fr auto - grid-template-rows: 1fr 1fr custom_fields: greeting: - justify-self: start - align-self: end - font-size: 30px - font-weight: 700 - color: white subtitle: - justify-self: start - align-self: start - font-size: 14px - color: rgba(255,255,255,0.55) clock: - justify-self: end - align-self: end - font-size: 32px - font-weight: 600 - color: white date: - justify-self: end - align-self: start - font-size: 14px - color: rgba(255,255,255,0.55) - type: grid cards: - type: custom:button-card entity: weather.home show_icon: false show_name: false show_state: false grid_options: columns: 6 rows: 4 custom_fields: weather_icon: | [[[ const s = entity?.state; if (s === "sunny") return "☀️"; if (s === "clear-night") return "🌙"; if (s === "cloudy") return "☁️"; if (s === "partlycloudy") return "⛅"; if (["rainy","pouring"].includes(s)) return "🌧️"; if (s === "lightning") return "⛈️"; return "🌤️"; ]]] temp: | [[[ const temp = states['sensor.outdoor_temperature']?.state ?? '--'; return `${temp}°`; ]]] condition: | [[[ const map = { sunny: "晴", cloudy: "多云", partlycloudy: "局部多云", rainy: "下雨", pouring: "大雨", "clear-night": "晴朗" }; return map[entity?.state] ?? entity?.state ?? "--"; ]]] forecast: | [[[ return "今天 · 舒适"; ]]] humidity: | [[[ const hum = states['sensor.outdoor_humidity']?.state ?? '--'; return `湿度 ${hum}%`; ]]] styles: card: - height: 210px - border-radius: 24px - border: none - padding: 22px - overflow: hidden - background: | linear-gradient( 145deg, #334b68 0%, #23334a 55%, #172131 100% ) - box-shadow: none grid: - grid-template-areas: | "weather_icon temp" "weather_icon condition" "forecast humidity" - grid-template-columns: 1fr 1.3fr - grid-template-rows: 1fr auto auto custom_fields: weather_icon: - font-size: 74px - align-self: center - justify-self: center - animation: weatherFloat 5s ease-in-out infinite temp: - font-size: 46px - font-weight: 700 - justify-self: start - align-self: end - color: white condition: - font-size: 17px - justify-self: start - color: rgba(255,255,255,0.7) forecast: - font-size: 13px - justify-self: start - color: rgba(255,255,255,0.6) humidity: - font-size: 13px - justify-self: end - color: rgba(255,255,255,0.6) extra_styles: | @keyframes weatherFloat { 0% { transform: translateY(0px) scale(1); } 50% { transform: translateY(-6px) scale(1.03); } 100% { transform: translateY(0px) scale(1); } } - type: custom:button-card show_icon: false show_name: false grid_options: columns: 6 rows: 4 custom_fields: title: 家庭状态 temperature: | [[[ return ` ${states['sensor.living_room_temperature']?.state ?? '--'}°C `; ]]] humidity: | [[[ return ` ${states['sensor.living_room_humidity']?.state ?? '--'}% `; ]]] door: | [[[ const door = states['binary_sensor.front_door']?.state; if (door === 'on') { return ` 门已打开 `; } return ` 门窗正常 `; ]]] water: | [[[ const leak = states['binary_sensor.water_leak']?.state; if (leak === 'on') { return ` 检测到漏水 `; } return ` 水浸正常 `; ]]] styles: card: - height: 210px - border-radius: 24px - border: none - padding: 22px - background: rgba(30,32,38,0.96) - box-shadow: none grid: - grid-template-areas: | "title title" "temperature humidity" "door water" - grid-template-columns: 1fr 1fr - grid-template-rows: auto 1fr 1fr - gap: 12px custom_fields: title: - justify-self: start - font-size: 17px - font-weight: 600 - color: white - margin-bottom: 5px temperature: - justify-self: stretch - align-self: stretch - display: flex - align-items: center - gap: 10px - padding: 14px - border-radius: 18px - background: rgba(255,255,255,0.05) - color: white - font-size: 17px humidity: - justify-self: stretch - align-self: stretch - display: flex - align-items: center - gap: 10px - padding: 14px - border-radius: 18px - background: rgba(255,255,255,0.05) - color: white - font-size: 17px door: - justify-self: stretch - display: flex - align-items: center - gap: 10px - padding: 14px - border-radius: 18px - background: rgba(255,255,255,0.05) - color: white water: - justify-self: stretch - display: flex - align-items: center - gap: 10px - padding: 14px - border-radius: 18px - background: rgba(255,255,255,0.05) - color: white column_span: 4 - type: grid cards: - type: heading heading: 快捷控制 icon: mdi:lightning-bolt heading_style: title - type: custom:mushroom-template-card entity: light.living_room primary: 客厅灯 secondary: | {% if is_state('light.living_room','on') %} 已开启 {% else %} 已关闭 {% endif %} icon: mdi:ceiling-light icon_color: | {% if is_state('light.living_room','on') %} amber {% else %} grey {% endif %} tap_action: action: toggle hold_action: action: more-info grid_options: columns: 3 rows: 2 card_mod: style: mushroom-shape-icon$: | .shape { {% if is_state(config.entity,'on') %} animation: lightGlow 2.2s ease-in-out infinite; {% endif %} } @keyframes lightGlow { 0%,100% { box-shadow: 0 0 0 rgba(255,190,60,0); } 50% { box-shadow: 0 0 22px rgba(255,190,60,.55); } } .: | ha-card { height: 112px; border-radius: 22px; border: none; background: rgba(30,32,38,.96); } - type: custom:mushroom-template-card entity: climate.living_room primary: 空调 secondary: | {% if is_state('climate.living_room','off') %} 已关闭 {% else %} {{ state_attr('climate.living_room','temperature') }}°C {% endif %} icon: mdi:snowflake icon_color: | {% if is_state('climate.living_room','off') %} grey {% else %} blue {% endif %} tap_action: action: more-info grid_options: columns: 3 rows: 2 card_mod: style: mushroom-shape-icon$: | .shape { {% if not is_state(config.entity,'off') %} animation: airconSpin 8s linear infinite; {% endif %} } @keyframes airconSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .: | ha-card { height: 112px; border-radius: 22px; border: none; background: rgba(30,32,38,.96); } - type: custom:mushroom-template-card entity: media_player.apple_tv primary: 影院 secondary: | {% if is_state('media_player.apple_tv','playing') %} 正在播放 {% elif is_state('media_player.apple_tv','idle') %} 待机 {% else %} 已关闭 {% endif %} icon: mdi:television-play icon_color: | {% if is_state('media_player.apple_tv','playing') %} deep-purple {% else %} grey {% endif %} tap_action: action: more-info grid_options: columns: 3 rows: 2 card_mod: style: | ha-card { height:112px; border-radius:22px; border:none; background:rgba(30,32,38,.96); } - type: custom:mushroom-template-card entity: input_boolean.home_mode primary: 回家模式 secondary: 一键回家 icon: mdi:home-heart icon_color: | {% if is_state(config.entity,'on') %} green {% else %} grey {% endif %} tap_action: action: toggle grid_options: columns: 4 rows: 2 card_mod: style: | ha-card { height:112px; border-radius:22px; border:none; background:rgba(30,32,38,.96); } - type: custom:mushroom-template-card entity: input_boolean.sleep_mode primary: 睡眠模式 secondary: 晚安 icon: mdi:weather-night icon_color: | {% if is_state(config.entity,'on') %} indigo {% else %} grey {% endif %} tap_action: action: toggle grid_options: columns: 4 rows: 2 card_mod: style: | ha-card { height:112px; border-radius:22px; border:none; background:rgba(30,32,38,.96); } - type: custom:mushroom-template-card primary: 全屋关灯 secondary: 一键关闭 icon: mdi:lightbulb-group-off icon_color: grey tap_action: action: call-service service: light.turn_off target: entity_id: light.all_lights grid_options: columns: 4 rows: 2 card_mod: style: | ha-card { height:112px; border-radius:22px; border:none; background:rgba(30,32,38,.96); } column_span: 4 - type: grid cards: - type: heading heading: 房间 icon: mdi:floor-plan heading_style: title - type: custom:button-card grid_options: columns: 5 rows: 3 show_icon: false show_name: false custom_fields: room: 客厅 icon: | temp: | [[[ return `${ states['sensor.living_room_temperature']?.state ?? '--' }°`; ]]] humidity: | [[[ return `${ states['sensor.living_room_humidity']?.state ?? '--' }%`; ]]] lights: | [[[ const on = states['light.living_room']?.state === 'on'; return on ? '💡 开启' : '💡 关闭'; ]]] climate: | [[[ const on = states['climate.living_room']?.state !== 'off'; return on ? '❄ 空调开启' : '❄ 空调关闭'; ]]] tap_action: action: navigate navigation_path: /dashboard-home/living-room styles: card: - height: 160px - border-radius: 24px - border: none - padding: 18px - background: rgba(30,32,38,.96) grid: - grid-template-areas: | "icon room" "temp humidity" "lights climate" - grid-template-columns: auto 1fr - grid-template-rows: auto 1fr auto - column-gap: 12px custom_fields: icon: - width: 44px - height: 44px - border-radius: 14px - background: rgba(255,255,255,.07) - display: flex - align-items: center - justify-content: center - color: white room: - justify-self: start - font-size: 20px - font-weight: 600 - color: white temp: - font-size: 30px - color: white - justify-self: start - align-self: center humidity: - font-size: 15px - color: rgba(255,255,255,.55) - justify-self: end - align-self: center lights: - font-size: 12px - color: rgba(255,255,255,.7) climate: - font-size: 12px - color: rgba(255,255,255,.7) - type: custom:button-card grid_options: columns: 5 rows: 3 show_icon: false show_name: false custom_fields: room: 就餐区 icon: | temp: | [[[ return `${ states['sensor.dining_temperature']?.state ?? '--' }°`; ]]] presence: | [[[ return states['binary_sensor.dining_presence']?.state === 'on' ? '👤 有人' : '○ 无人'; ]]] light: | [[[ return states['light.dining_room']?.state === 'on' ? '💡 灯光开启' : '💡 灯光关闭'; ]]] styles: card: - height: 160px - border-radius: 24px - border: none - padding: 18px - background: rgba(30,32,38,.96) grid: - grid-template-areas: | "icon room" "temp temp" "presence light" - grid-template-columns: auto 1fr custom_fields: icon: - width: 44px - height: 44px - border-radius: 14px - background: rgba(255,255,255,.07) - display: flex - align-items: center - justify-content: center - color: white room: - justify-self: start - font-size: 20px - font-weight: 600 - color: white temp: - justify-self: start - align-self: center - font-size: 30px - color: white presence: - font-size: 12px - color: rgba(255,255,255,.7) light: - font-size: 12px - color: rgba(255,255,255,.7) - type: custom:button-card grid_options: columns: 5 rows: 3 show_icon: false show_name: false custom_fields: room: 主卧 icon: | temp: | [[[ return `${ states['sensor.bedroom_temperature']?.state ?? '--' }°`; ]]] humidity: | [[[ return `${ states['sensor.bedroom_humidity']?.state ?? '--' }%`; ]]] lights: | [[[ return states['light.bedroom']?.state === 'on' ? '💡 开启' : '💡 关闭'; ]]] styles: card: - height: 160px - border-radius: 24px - border: none - padding: 18px - background: rgba(30,32,38,.96) grid: - grid-template-areas: | "icon room" "temp humidity" "lights lights" - grid-template-columns: auto 1fr custom_fields: icon: - width: 44px - height: 44px - border-radius: 14px - background: rgba(255,255,255,.07) - display: flex - align-items: center - justify-content: center - color: white room: - justify-self: start - font-size: 20px - font-weight: 600 - color: white temp: - font-size: 30px - color: white humidity: - justify-self: end - color: rgba(255,255,255,.55) lights: - font-size: 12px - color: rgba(255,255,255,.7) - type: custom:button-card grid_options: columns: 5 rows: 3 show_icon: false show_name: false custom_fields: room: 卫生间 icon: | temp: | [[[ return `${ states['sensor.bathroom_temperature']?.state ?? '--' }°`; ]]] humidity: | [[[ return `${ states['sensor.bathroom_humidity']?.state ?? '--' }%`; ]]] styles: card: - height: 160px - border-radius: 24px - border: none - padding: 18px - background: rgba(30,32,38,.96) grid: - grid-template-areas: | "icon room" "temp humidity" - grid-template-columns: auto 1fr custom_fields: icon: - width: 44px - height: 44px - border-radius: 14px - background: rgba(255,255,255,.07) - display: flex - align-items: center - justify-content: center - color: white room: - justify-self: start - font-size: 20px - font-weight: 600 - color: white temp: - font-size: 30px - color: white humidity: - justify-self: end - color: rgba(255,255,255,.55) column_span: 4 - type: grid cards: - type: heading heading: 正在运行 icon: mdi:motion-play heading_style: title - type: custom:mushroom-template-card entity: climate.living_room primary: 客厅空调 secondary: | {% if is_state(config.entity,'off') %} 已关闭 {% else %} 制冷中 · {{ state_attr(config.entity,'temperature') }}°C {% endif %} icon: mdi:air-conditioner icon_color: | {% if is_state(config.entity,'off') %} grey {% else %} blue {% endif %} tap_action: action: more-info grid_options: columns: 4 rows: 2 card_mod: style: | ha-card { min-height:110px; border-radius:22px; border:none; background:rgba(30,32,38,.96); } - type: custom:mushroom-template-card entity: media_player.apple_tv primary: Apple TV secondary: | {% if is_state(config.entity,'playing') %} {{ state_attr(config.entity,'media_title') | default('正在播放') }} {% else %} 待机 {% endif %} icon: mdi:apple icon_color: | {% if is_state(config.entity,'playing') %} purple {% else %} grey {% endif %} tap_action: action: more-info grid_options: columns: 4 rows: 2 card_mod: style: | ha-card { min-height:110px; border-radius:22px; border:none; background:rgba(30,32,38,.96); } - type: custom:mushroom-template-card entity: sensor.water_purifier_tds primary: 净水器 secondary: | TDS {{ states(config.entity) }} icon: mdi:water-pump icon_color: cyan tap_action: action: more-info grid_options: columns: 4 rows: 2 card_mod: style: |- ha-card { min-height:110px; border-radius:22px; border:none; background:rgba(30,32,38,.96); } column_span: 4 visible: - user: 7a6c93d08acc4692bfd561154bb386df - user: 7809f2c31fda449b8e7c5a0d2eaf5fd5 cards: []