Yes, I have this file and the line in my configuration.yaml.
I reuploaded your file, and try it again, but it doesnt work.
Yes, I have this file and the line in my configuration.yaml.
I reuploaded your file, and try it again, but it doesnt work.
Thanks a million for the help, exactly what I needed
Is this yours? Are you sure you’ve copied all the templates correctly? diff compare
No, this is my error:
ButtonCardJSTemplateError: TypeError: Cannot read properties of undefined (reading 'state') in 'if (entity) {
let links = new RegExp('<a href="([^"]+)"', "g"),
installed = entity...'
So not the same error
Cannot read properties of undefined (reading 'state')
either means that you don’t have all the sensors needed or you’ve made a typo in the sensor name.
Replace updates_hass
with this, open popup and look in your browser console
# button_card_templates/updates.yaml
updates_hass:
template:
- updates
- settings
state_display: |
[[[
function Log(entity_id, state) {
this.entity_id = entity_id;
this.state = state;
}
var obj = {};
obj.entity = new Log(`${entity?.entity_id}`, `${entity?.state}`);
obj.latest = new Log(`${states[variables?.latest]?.entity_id}`, `${states[variables?.latest]?.state}`);
obj.latest_beta = new Log(`${states[variables?.latest_beta]?.entity_id}`, `${states[variables?.latest_beta]?.state}`);
obj.release_notes = new Log(`${states[variables?.release_notes]?.entity_id}`, `${states[variables?.release_notes]?.state} ${states[variables?.release_notes]?.attributes?.body}`);
obj.release_notes_beta = new Log(`${states[variables?.release_notes_beta]?.entity_id}`, `${states[variables?.release_notes_beta]?.state} ${states[variables?.release_notes_beta]?.attributes?.body}`);
obj.translate_no_updates = new Log(`(variable)`, `${variables?.translate_no_updates}`);
obj.translate_available = new Log(`(variable)`, `${variables?.translate_available}`);
console.table(obj);
]]]
Oh, you are right. Had an other error at the beginning.
It seems im missing some sensors:
But if I look at the dev tools in HA, there is a state for the hass_release_latest_beta:
I compared the version_updates.yaml and the button_card_templates/updates.yaml, and I think I have everything. Nad the Version Integration is also there:
but my version-sensors are called: sensor.home_assistant_versions and sensor.homea_assistant_versions_beta.
Could this be a problem?
Thanks a lot, that was my missing piece.
Hi all,
any suggestion how I can add an if else function in the button_card_templates.yaml ?
I do want to change the color of the circle for the person card in dependence of the teams presence status and the original state home <-> not home.
So far it’s working pretty well:
(Red Circle for in a call)
But when not at home and not in a call the circle is not like in the original design from Matthias:
This is obivously because of my moddification in the template file as I don’t know how to implent the if else function:
stroke = states[variables.teams].state == 'Am Telefon' || states[variables.teams].state == 'In einer Besprechung'
? 'red'
: '#b2b2b2',
E.g. if stroke = states[variables.teams].state == ‘Work’ then ‘none’
Furthermore I try to let the circle (just the circle) blink when I’m in a call. I don’t get it, how to select just the circle himself? With the following modification, the hole SVG (so circle and text) start to blink. Any suggestion how to achieve that, just the circle blinks?
circle:
- animation: >
[[[
if (entity) {
return states[variables.teams].state == 'Am Telefon'
? 'blink 2s ease infinite'
: 'none';
}
]]]
Yeah, doing it that way styles the whole div. You can add a new custom_field to set the styles with js
person:
custom_fields:
blink: >
[[[
setTimeout(() => {
let elt = this.shadowRoot,
circle_stroke = elt.getElementById('circle_stroke');
if (
states[variables.teams]?.state == 'Am Telefon' ||
states[variables.teams]?.state == 'In einer Besprechung'
) {
circle_stroke.style.animation = 'blink 2s ease infinite';
circle_stroke.style.stroke = 'red';
} else {
circle_stroke.removeAttribute('style');
}
}, 0);
]]]
Hi @Mattias_Persson, apologies if this was asked and answered, i might be late to the party on this.
I am trying to updated form the old command_line for udm_unifios that was stored in the secrets file (see old command below) to the new python3 implementation, but the script is not running, i just get an error in the logs “Command failed (with return code 1):” followed by the script (see full error message below), i think i am missing a step but with the move of the file i cant find the commit where this was added.
oh and in this commit, use update entities · matt8707/hass-config@1408d40 · GitHub you forgot to remove the use of udm_upgradable
on line 586 in ui-lovelace.yaml
Command failed (with return code 1): python3 << EOF import json, yaml, requests from datetime import datetime from urllib3 import disable_warnings disable_warnings() SECRETS_FILE = "/config/secrets.yaml" def get_secret(secret): try: with open(SECRETS_FILE, "r", encoding="utf8") as file: secrets = yaml.full_load(file) for key, value in secrets.items(): if key == secret: return value except FileNotFoundError: print("secrets.yaml not found") exit() IP = get_secret("unifi_host") PORT = get_secret("unifi_port") USER = get_secret("unifi_username") PASS = get_secret("unifi_password") URL = f"https://{IP}:{PORT}" login = requests.request("POST", f"{URL}/api/auth/login", \ headers={"Content-Type": "application/json"}, \ data=json.dumps({"username": USER, "password": PASS}), verify=False) response = requests.request("GET", f"{URL}/proxy/network/api/s/default/stat/device/", \ cookies=login.cookies, verify=False) data = response.json()["data"][0] print(json.dumps({ "cpu": data["system-stats"]["cpu"], "cpu_temp": round(data["temperatures"][1]["value"], 1), "mem": data["system-stats"]["mem"], "disk": round(data["storage"][1]["used"] / data["storage"][1]["size"] * 100, 1), "internet": data["internet"], "uptime": datetime.fromtimestamp(data["startup_timestamp"]).isoformat(), "version": data["displayable_version"] })) EOF
Note: i did update the keys in the script to match what i have in my secrets
unifi_host is just the IP that i use to connect to my UDM
unifi_port is 433 that was the port used in the old script.
platform: command_line
name: udm_unifios
command: !secret udm_unifios
value_template: |-
{% set json = value_json.data[0] %}
{{ json["system-stats"].cpu }}|
{{ json.temperatures[1].value | round(1) }}|
{{ json["system-stats"].mem }}|
{{ ((json.storage[1].used / json.storage[1].size) * 100) | round(1) }}|
{{ json.internet }}|
{{ json.startup_timestamp | timestamp_local }}|
{{ json.displayable_version }}|
{{ json.upgradable }}
scan_interval: 120
Hello,
Thanks for this great dashboard! I’m currently trying to create a template for a climate (radiator) card, code shown below. The base template is referenced from the original.
climate:
template:
- base
double_tap_action:
action: fire-dom-event
browser_mod:
command: popup
title: >
[[[
return !entity || entity.attributes.friendly_name;
]]]
style:
hui-entities-card:
$: |
#states {
padding-top: 0.8em;
}
card:
type: entities
entities: >
[[[
if (entity) {
let climate = [],
id = Boolean(entity.attributes.entity_id)
? [entity.entity_id].concat(entity.attributes.entity_id)
: [entity.entity_id];
for (let i = 0; i < id.length; i++) {
climate.push({
"type": "custom:mushroom-climate-card",
"entity": id[i],
"fill_container": false,
"primary_info": "name",
"secondary_info": "state",
"icon_type": "icon",
"show_temperature_control": true,
"hvac_modes": ["off","auto","heat"],
"collapsible_controls": true
});
}
return climate;
}
]]]
variables:
circle_current_temp_input: >
[[[ {
const current_temperature = entity.attributes.current_temperature;
return current_temperature;
}
]]]
circle_current_temp_unit: "°"
circle_set_temp_input: >
[[[ {
const set_temperature = entity.attributes.temperature;
return set_temperature;
}
]]]
circle_set_temp_unit: "°"
custom_fields:
circle_current_temp: >
[[[
if (entity) {
let r = 22.1,
c = r * 2 * Math.PI,
tspan = '<tspan dx=".2" dy="-.4">',
domain = entity.entity_id.split('.')[0],
state = variables.state,
input = variables.circle_current_temp_input || ' ',
unit = variables.circle_current_temp_unit || ' ';
/* * * * * * * * * * * * * * * * * *
* *
* CIRCLE *
* *
* * * * * * * * * * * * * * * * * */
let circle = (state, input, unit) => {
return `
<svg viewBox="0 0 50 50">
<style>
circle {
transform: rotate(-90deg);
transform-origin: 50% 50%;
stroke-dasharray: ${c};
stroke-width: var(--c-stroke-width);
stroke: ${state ? 'var(--c-stroke-color-on-current)' : 'var(--c-stroke-color-off-current)'};
fill: ${state ? 'var(--c-fill-color-off-current)' : 'var(--c-fill-color-on-current)'};
}
text {
font-size: var(--c-font-size);
font-weight: var(--c-font-weight);
letter-spacing: var(--c-letter-spacing);
fill: ${state ? 'var(--c-font-color-off)' : 'var(--c-fill-color-on)'};
}
tspan {
font-size: var(--c-unit-font-size);
}
#circle_value, tspan {
text-anchor: middle;
dominant-baseline: central;
}
</style>
<circle id="circle_stroke" cx="25" cy="25" r="${r}"/>
<text id="circle_value" x="50%" y="52%">${input}${tspan}${unit}</tspan></text>
</svg>
`;
}
if (domain === 'climate') {
return circle(state, input, unit);
}
}
]]]
circle_target_temp: >
[[[
if (entity.state === "heat") {
let r = 22.1,
c = r * 2 * Math.PI,
tspan = '<tspan dx=".2" dy="-.4">',
domain = entity.entity_id.split('.')[0],
state = variables.state,
input = variables.circle_set_temp_input || ' ',
unit = variables.circle_set_temp_unit || ' ',
valve_pos = variables.valve,
valve_pos_num = valve_pos.slice(0, -1);
/* * * * * * * * * * * * * * * * * *
* *
* CIRCLE *
* *
* * * * * * * * * * * * * * * * * */
let circle = (state, input, unit) => {
return `
<svg viewBox="0 0 50 50">
<style>
circle {
transform: rotate(-90deg);
transform-origin: 50% 50%;
stroke-dasharray: ${c};
stroke-dashoffset: ${c - valve_pos_num / 100 * c};
stroke-width: var(--c-stroke-width);
stroke: ${state ? 'var(--c-stroke-color-on-target)' : 'var(--c-stroke-color-off-target)'};
fill: ${state ? 'var(--c-fill-color-on-target)' : 'var(--c-fill-color-off-target)'};
}
text {
font-size: var(--c-font-size);
font-weight: var(--c-font-weight);
letter-spacing: var(--c-letter-spacing);
fill: var(--c-font-color);
}
tspan {
font-size: var(--c-unit-font-size);
}
#circle_value, tspan {
text-anchor: middle;
dominant-baseline: central;
}
</style>
<circle id="circle_stroke" cx="25" cy="25" r="${r}"/>
<text id="circle_value" x="50%" y="52%">${input}${tspan}${unit}</tspan></text>
</svg>
`;
}
if (domain === 'climate') {
return circle(state, input, unit);
}
}
]]]
styles:
card:
- --c-stroke-color-on-target: "#b0b0b0"
- --c-stroke-color-off-target: none
- --c-stroke-color-on-current: none
- --c-stroke-color-off-current: none
- --c-fill-color-on-target: none
- --c-fill-color-off-target: rgba(255,255,255,0.04)
- --c-fill-color-on-current: rgba(78,198,110,0.6)
- --c-fill-color-off-current: rgba(255,255,255,0.04)
- --c-stroke-width: 2.3
- --c-stroke-width-current: 0
- --c-stroke-width-dragging: 4
- --c-font-color: "#97989c"
- --c-font-color-off: "#97989c"
- --c-font-color-on: white
- --c-font-size: 14px
- --c-unit-font-size: 10.5px
- --c-font-weight: 700
- --c-letter-spacing: -0.02rem
custom_fields:
circle_target_temp:
- display: initial
- width: 88%
- margin: -3% 2% 0 0
- justify-self: end
- opacity: 1
circle_current_temp:
- display: initial
- width: 88%
- margin: -3% 14% 0 0
- justify-self: end
- opacity: 1
grid:
- grid-template-areas: |
"circle_current_temp circle_target_temp"
"n n"
"s s"
- grid-template-columns: repeat(2, 1fr)
- grid-template-rows: auto repeat(2, min-content)
- gap: 1.3%
- align-items: start
This is what i get when the climate entity state is off, no problems. Current temperature is shown in the top left corner:
When the climate enitity state is heat, this is what i get, but this is not the way i intended:
What i expected is this, with a green fill-color for the circle and the target temperature in the top right corner:
If someone could point me in the rigtht direction, it would be much appriciated!
Yeah, that error doesn’t tell much. Test the most basic form locally then if that works add the json paths and lastly the secrets function.
import json, yaml, requests
from datetime import datetime
from urllib3 import disable_warnings
disable_warnings()
IP = " "
PORT = " "
USER = " "
PASS = " "
URL = f"https://{IP}:{PORT}"
login = requests.request("POST", f"{URL}/api/auth/login", \
headers={"Content-Type": "application/json"}, \
data=json.dumps({"username": USER, "password": PASS}), verify=False)
response = requests.request("GET", f"{URL}/proxy/network/api/s/default/stat/device/", \
cookies=login.cookies, verify=False)
print(response.json())
Thanks! 95c6a1f
Hello There
I have a problem with the footer and I have no idea what it can be. The size of the buttons does not adjust automatically. If I change the with from “fit-content” to 100px in footer.yaml, the buttons scale.
#button_card_templates: !include button_card_templates.yaml
button_card_templates:
!include_dir_merge_named button_card_templates
views:
- type: custom:grid-layout
path: 0
layout:
#default
margin: 0
grid-gap: var(--custom-layout-card-padding)
grid-template-columns: repeat(4, 1fr) 0
grid-template-rows: 0 repeat(2, fit-content(100%)) 0fr
grid-template-areas: |
"sidebar . . . ."
"sidebar wohnzimmer flur schlafzimmer ."
"sidebar media sonos home ."
"sidebar footer footer footer ."
mediaquery:
#phone
"(max-width: 800px)":
grid-gap: calc(var(--custom-layout-card-padding) * 1.7)
grid-template-columns: 0 repeat(2, 1fr) 0
grid-template-rows: 0 repeat(5, fit-content(100%)) 0fr
grid-template-areas: |
". . . ."
". sidebar sidebar ."
". wohnzimmer schlafzimmer ."
". flur home ."
". media sonos ."
". footer footer ."
". . . ."
#portrait
"(max-width: 1200px)":
grid-gap: var(--custom-layout-card-padding)
grid-template-columns: repeat(3, 1fr) 0
grid-template-rows: 0 repeat(3, fit-content(100%)) 0fr
grid-template-areas: |
"sidebar . . ."
"sidebar wohnzimmer schlafzimmer ."
"sidebar flur home ."
"sidebar media sonos ."
"sidebar footer footer ."
cards:
- type: custom:button-card #extra_styles fix
styles: {card: [display: none]}
#################################################
# #
# SIDEBAR #
# #
#################################################
- type: vertical-stack
view_layout:
grid-area: sidebar
cards:
- type: custom:button-card
entity: sensor.template_sidebar
template: sidebar
#################################################
# #
# Wohnzimmer #
# #
#################################################
- type: grid
title: Wohnzimmer
view_layout:
grid-area: wohnzimmer
columns: 2
cards:
- type: custom:button-card
entity: light.new_york
name: New York
template:
- light
- icon_hue
- type: custom:button-card
entity: light.schnapstrue
name: Schnapstruhe
template:
- light
- icon_hue
- type: custom:button-card
entity: sensor.weather_station_temperature
name: Temperatur
tap_action:
action: more-info
custom_fields:
graph:
card:
entities:
- sensor.weather_station_temperature
template:
- temperature
- icon_temp
variables:
popup_name: Temperatur
- type: custom:button-card
entity: light.salzstein
name: Salzstein
template:
- light
- icon_hue
#################################################
# #
# Schlafzimmer #
# #
#################################################
- type: grid
title: Schlafzimmmer
view_layout:
grid-area: schlafzimmer
columns: 2
cards:
- type: custom:button-card
entity: light.schlafzimmer
name: Ständerlampe
template:
- light
- icon_lamp
- type: custom:button-card
entity: fan.luftibert
name: "Lüftibert"
hold_action:
!include popup/schlafzimmer_fan.yaml
tap_action:
action: more-info
template:
- base
- icon_fan
- type: custom:button-card
entity: media_player.hauptschlafzimmer
name: Sonos
hold_action:
!include popup/sonos.yaml
template:
- base
- icon_sonos
- loader
- type: custom:button-card
entity: sensor.luftibert_temperature
name: Temperatur
tap_action:
action: more-info
custom_fields:
graph:
card:
entities:
- sensor.luftibert_temperature
template:
- temperature
- icon_temp
variables:
popup_name: Temperatur
#################################################
# #
# MEDIA #
# #
#################################################
- type: grid
title: Media
view_layout:
grid-area: media
columns: 1
cards:
- type: custom:swipe-card
start_card: 1
parameters:
roundLengths: true
effect: coverflow
speed: 650
spaceBetween: 20
threshold: 7
coverflowEffect:
rotate: 80
depth: 300
cards:
- type: custom:spotify-card
account: default
spotify_entity: media_player.spotify_jan_stager
playlist_type: discover-weekly
grid_covers_per_row: '2'
limit: 4
country_code: DE
default_device: Küche
display_style: grid
known_connect_devices:
- id: d4757ab523224358f9c9052ee4de85ba324c41fa
name: Küche
entity_id: media_player.kuche
- type: custom:mini-media-player
entity: media_player.kuche
hide:
power: true
volume: true
controls: true
source: true
speaker_group:
platform: sonos
show_group_count: true
entities:
- entity_id: media_player.kuche
name: Sonos Küche
- entity_id: media_player.badezimmer
name: Sonos Badezimmer
- entity_id: media_player.buro
name: Sonos Büro
- entity_id: media_player.hauptschlafzimmer
name: Sonos Schlafzimmer
- entity_id: media_player.balkon
name: Sonos Balkon
entities:
- type: custom:mini-media-player
entity: media_player.multiroom_player
group: true
source: icon
artwork: cover
info: scroll
hide:
volume: true
power_state: true
- type: custom:mini-media-player
entity: media_player.kuche
group: true
hide:
controls: true
- type: custom:mini-media-player
entity: media_player.badezimmer
group: true
hide:
controls: true
- type: custom:mini-media-player
entity: media_player.buro
group: true
hide:
controls: true
- type: custom:mini-media-player
entity: media_player.hauptschlafzimmer
group: true
hide:
controls: true
- type: custom:mini-media-player
entity: media_player.balkon
group: true
hide:
controls: true
#################################################
# #
# Sonos #
# #
#################################################
- type: grid
title: Sonos
view_layout:
grid-area: sonos
columns: 1
cards:
- type: entities
entities:
- type: custom:mini-media-player
entity: media_player.kuche
group: true
hide:
controls: true
power: true
icon: true
info: true
source: true
progress: true
- type: custom:mini-media-player
entity: media_player.buro
group: true
hide:
controls: true
power: true
icon: true
info: true
source: true
progress: true
- type: custom:mini-media-player
entity: media_player.badezimmer
group: true
hide:
controls: true
power: true
icon: true
info: true
source: true
progress: true
- type: custom:mini-media-player
entity: media_player.hauptschlafzimmer
name: Schlafzimmer
group: true
hide:
controls: true
power: true
icon: true
info: true
source: true
progress: true
- type: custom:mini-media-player
entity: media_player.balkon
name: Balkon
group: true
hide:
controls: true
power: true
icon: true
info: true
source: true
progress: true
#################################################
# #
# Flur #
# #
#################################################
- type: grid
title: Flur
view_layout:
grid-area: flur
columns: 2
cards:
- type: custom:button-card
entity: light.group_hall
name: Hall
template:
- light
- icon_spot
#################################################
# #
# Home #
# #
#################################################
- type: grid
title: Home
view_layout:
grid-area: home
columns: 2
cards:
- type: custom:button-card
entity: script.home_leave
name: Good Bye
hold_action:
action: none
template:
- base
- icon_away
- type: custom:button-card
entity: script.home_arrive
name: Welcome
hold_action:
action: none
template:
- base
- icon_home
- type: custom:button-card
entity: script.good_night
name: Good Night
hold_action:
action: none
template:
- base
- icon_good_night
- type: custom:button-card
entity: script.music
name: Music
hold_action:
action: none
template:
- base
- icon_music
#################################################
# #
# FOOTER #
# #
#################################################
- type: horizontal-stack
view_layout:
grid-area: footer
cards:
- type: custom:button-card
name: >
<ha-icon icon="mdi:nas"></ha-icon> NAS
tap_action:
!include popup/footer_nas.yaml
triggers_update:
- binary_sensor.jan_home_update_available
- sensor.jan_home_status
- binary_sensor.jan_home_security_status
- sensor.disk_use_percent
variables:
notify: >
[[[
let id = this._config.triggers_update;
if (id.every(e => states[e]))
return states[id[0]].state === 'on'
? 1
: states[id[1]].state === 'background_scrubbing' ||
states[id[2]].state === 'on' ||
parseFloat(states[id[3]].state) >= 85;
]]]
template: footer
- type: custom:button-card
name: >
<ha-icon icon="mdi:arrow-up-bold-circle-outline"></ha-icon> Updates
tap_action:
!include popup/footer_updates.yaml
triggers_update:
- sensor.hacs
- sensor.docker_hub_beta
- sensor.docker_hub
variables:
notify: >
[[[
let id = this._config.triggers_update;
if (id.every(e => states[e])) {
let hacs = parseInt(states[id[0]].state),
installed = hass.config.version,
latest = installed.includes('b')
? states[id[1]].state
: states[id[2]].state;
if (latest.includes('.') && Number.isInteger(hacs))
return hacs + (installed !== latest ? 1 : 0);
}
return 0;
]]]
template: footer
- type: custom:button-card
name: >
<ha-icon icon="custom:roborock-vacuum"></ha-icon> Buddy
tap_action:
!include popup/footer_vacuum.yaml
triggers_update:
- sensor.date
variables:
notify: >
[[[
let id = states['sensor.morty_last_clean_end'];
if (id) return (Date.now() - Date.parse(id.state)) > 6048e5;
]]]
template: footer
- type: custom:button-card
name: >
<ha-icon icon="mdi:chart-line-variant"></ha-icon> Statistik
tap_action:
!include popup/footer_history.yaml
template: footer
- type: custom:button-card
name: >
<ha-icon icon="custom:cupra"></ha-icon> Cupra
tap_action:
!include popup/footer_cupra.yaml
template: footer
I am grateful for every hint
Hi @Mattias_Persson , first thank you for your setup and help. I did everything as listed in Github Installation Instructions. First I got error:
secret Youtube_token not defined
but I fixed it by commenting it in media.yaml.
But now I get the error:
Secret apexcharts_tibber not defined
I dont know how to fix and I already searched this post but didnt find any solution. I already installed the apexcharts repo via hacs.
Can you please give me a solution?
Thank you!
That’s outdated instructions, there’s no secrets anymore. You’ll have to copy the files from my repo again https://github.com/matt8707/hass-config/blob/00de2dd3ce0f3145e20ae0de5adda518b37b0194/INSTALL.md
Okay thank you so much I will try it!
Hi so I´m sure this was asked a lot, but can somebody please tell me which files I need to look at for changing text, language, adding my own entities?
Thanks