Here is the yaml for one of my cards. This is made to run with my own custom template entities (not provided by the adaptive cover integration, but based on adaptive cover and its earlier source), so you’ll have to rewrite it a bit to work with your own setup. I use a datetime helper to override cover control until the future timestamp in the helper is reached, and my own template sensor has attributes that explain the state (sunset, morning_hold, closed: hot_outside, manual_override, etc.) and if the sun is in direct view or not.
The button makes use of the custom button-card installable via HACS.
type: custom:button-card
variables:
name: Master Bedroom
cover_entity: cover.master_bedroom_window
override_entity: input_datetime.smart_blind_master_bedroom_window_override_until
sensor_entity: sensor.smart_blind_master_bedroom_window_adaptive_position
entity: "[[[ return variables.cover_entity; ]]]"
triggers_update: all
layout: custom
show_icon: true
show_name: false
show_state: false
icon: |
[[[
const pos = Number(states[variables.cover_entity]?.attributes?.current_position ?? -1);
const reason = states[variables.sensor_entity].attributes?.reason ?? '';
if (reason == 'cover_disabled') return 'mdi:lock';
if (pos <= 5) return 'mdi:roller-shade-closed';
if (pos >= 90) return 'mdi:checkbox-blank-outline';
return 'mdi:roller-shade';
]]]
custom_fields:
text_block: |
[[[
const stateObj = states[variables.cover_entity];
const sensorObj = states[variables.sensor_entity];
const override = states[variables.override_entity]?.state;
const state = stateObj?.state ?? '';
const pos = stateObj?.attributes?.current_position ?? '?';
const reason = sensorObj?.attributes?.reason ?? '';
let label = reason;
if (reason === 'manual_override' && override) {
const timePart = override.includes(' ') ? override.split(' ')[1] : override;
const [hour = '', minute = ''] = timePart.split(':');
label = `${reason} until ${hour.padStart(2,'0')}:${minute.padStart(2,'0')}`;
}
return `
<div style="display:flex;flex-direction:column;align-items:flex-start;">
<div style="font-weight:bold;font-size:14px;">${variables.name}</div>
<div style="font-size:12px;font-style:italic;color:var(--secondary-text-color);">${label}</div>
<div style="font-size:12px;color:var(--secondary-text-color);">
${state.charAt(0).toUpperCase() + state.slice(1)} · ${pos}%
</div>
</div>
`;
]]]
sun_icon: |
[[[
return states[variables.sensor_entity]?.attributes?.sun_in_view
? '<ha-icon icon="mdi:sun-angle" style="--mdc-icon-size:20px;color:darkorange;"></ha-icon>'
: '';
]]]
styles:
grid:
- grid-template-areas: "\"i text_block\""
- grid-template-columns: 1fr 3fr
card:
- align-items: center
- padding: 6px
- border-radius: 12px
- background-color: var(--card-background-color)
- box-shadow: 0 2px 6px rgba(0,0,0,0.2)
- position: relative
icon:
- width: 100%
- max-width: 35px
- justify-self: center
- color: |
[[[
const reason = states[variables.sensor_entity]?.attributes?.reason ?? '';
if (reason === 'control_off' || reason === 'cover_disabled') return 'grey';
if (reason === 'manual_override') return 'orangered';
const coverState = states[variables.cover_entity]?.state ?? '';
if (coverState === 'closed' || coverState === 'closing') return 'mediumpurple';
if (coverState === 'open' || coverState === 'opening') return 'orange';
return 'var(--paper-item-icon-color)';
]]]
custom_fields:
text_block:
- justify-self: start
- padding: 4px
sun_icon:
- position: absolute
- top: 1px
- left: 3px
- pointer-events: none
- width: 20px
- height: 20px
tap_action:
action: more-info
double_tap_action:
action: more-info
entity: "[[[ return variables.sensor_entity; ]]]"
hold_action:
action: call-service
service: input_datetime.set_datetime
service_data:
entity_id: "[[[ return variables.override_entity; ]]]"
time: "00:00:00"
date: "[[[ return new Date().toISOString().slice(0,10); ]]]"
grid_options:
columns: 6
