Custom Card Ristou Person¶
Light | Dark |
---|---|
Credits¶
- Author: Ristou - 2022
- Version: 1.0.0
Changelog¶
1.0.1
- Fixed image path on documentation - Added new template on card ( `icon_more_info_new` & `ulm_actions_card` )1.0.0
Initial releaseDescription¶
The custom_card_ristou_person
shows if a person is home
or not_home
. If you have setup other zones, it will show these as well (e.g work
, school
, doctor
, etc... ).
Showing driving state is also possible with a binary sensor.
In addition, this card can display a map (either static or using built in map) in a second row.
Icon style¶
As the main icon of this card you can choose the following set up
Variables | UI |
---|---|
ulm_custom_card_ristou_use_badge: true ulm_custom_card_ristou_use_entity_picture: false |
|
ulm_custom_card_ristou_use_badge: true ulm_custom_card_ristou_use_entity_picture: true |
|
ulm_custom_card_ristou_use_badge: false ulm_custom_card_ristou_use_entity_picture: false |
map style¶
Variables | UI |
---|---|
ulm_custom_card_ristou_camera_entity_light != "" and ulm_custom_card_ristou_camera_entity_dark != "" |
|
ulm_custom_card_ristou_map_enable: true |
|
ulm_custom_card_ristou_camera_entity_light = "" and ulm_custom_card_ristou_camera_entity_dark = "" and ulm_custom_card_ristou_map_enable = false |
About Static maps¶
The advantage of static map is that it is easy to custom and non-draggable. For instance when you scroll down and you accidentally press first on map card.
I choose map box for the following reasons:
- Easy to sep it up with static image API playground
- Already existing styles (light & dark) to fit to your theme.
- Add many custom markers, I decided to represent my current location , home, and work.
- Possibility to remove attribution and logo.
URL can be directly used inside a camera entity using dynamic markers as explain here
below is an example of the url I use for mapbox:
https://api.mapbox.com/styles/v1/mapbox/light-v10/static/pin-l-suitcase+f88927({{ state_attr('zone.work', 'longitude') }},{{ state_attr('zone.work', 'latitude') }}),pin-l-home+01C852({{ state_attr('zone.home', 'longitude') }},{{ state_attr('zone.home', 'latitude') }}),pin-l-m+3D5AFE({{ state_attr('device_tracker.mathieu_phone', 'longitude') }},{{ state_attr('device_tracker.mathieu_phone', 'latitude') }})/auto/466x200?attribution=false&logo=false&&access_token=YOUR_TOKEN
Known issues¶
map¶
built in map is not always rendering properly. I observed 2 issues:
- Not displaying if under sub stack like
horizontal stack
orvertical stack
. another map has to be added somewhere else in the page. Github issue - In IOS (never tried with other devices) bottom corner radius is not taken into consideration
Static map¶
Static map can be blurry if ratio does not fit card width. In my case I used developer tool to find out exact width of the card (which is 466px) and then I adjusted the height to my needs.
Variables¶
Variable | Default | Required | Notes |
---|---|---|---|
entity | ✔️ | person entity | |
ulm_custom_card_ristou_use_entity_picture | false | ❌ | If you set this to true, the card shows the entity picture from your user, otherwise (set to false) shows the icon. Default is false. |
ulm_custom_card_ristou_use_badge | true | ❌ | Show a notification badge on the icon. if set to false and not sing entity picture, then icon will be dynamically displayed to (Home, Away, Known place, or CAR) |
ulm_custom_card_ristou_map_enable | false | ❌ | Display built in map as a second row |
ulm_custom_card_ristou_map_aspect_ratio | 16:5 | ❌ | Display built in map as a second row |
ulm_custom_card_ristou_map_hours_to_show | 24 | ❌ | Display built in map as a second row |
ulm_custom_card_ristou_map_default_zoom | 9 | ❌ | Display built in map as a second row |
ulm_custom_card_ristou_camera_entity_light | ❌ | Camera entity picture in light mode | |
ulm_custom_card_ristou_camera_entity_dark | ❌ | Camera entity picture in dark mode | |
ulm_custom_card_ristou_zones | ❌ | Used to display known zone on badge, icon, label or map | |
ulm_custom_card_ristou_find_device_script | ❌ | Show a button to find your device |
Usage¶
- type: "custom:button-card"
template: custom_card_ristou_person
entity: person.mathieu
variables:
ulm_custom_card_ristou_use_entity_picture: true
ulm_custom_card_ristou_find_device_script: script.find_phone_mathieu
ulm_custom_card_ristou_person_driving_entity: binary_sensor.mathieu_driving
ulm_custom_card_ristou_camera_entity_light: "camera.mapbox_mathieu_light"
ulm_custom_card_ristou_camera_entity_dark: "camera.mapbox_mathieu_dark"
ulm_custom_card_ristou_zones:
- person.isabelle
- person.mathieu
- zone.work
- zone.judo
- zone.doctor
- zone.nounou
- zone.work_isabelle
Template code¶
Template Code
---
### custom card ristou person ###
custom_card_ristou_person:
template:
- "ulm_translation_engine"
- "ulm_custom_card_ristou_person_language_variables"
- "icon_more_info_new"
- "ulm_actions_card"
variables:
ulm_custom_card_ristou_name: "[[[ return entity.attributes.friendly_name ]]]"
ulm_custom_card_ristou_icon: "[[[ return entity.attributes.icon ]]]"
ulm_custom_card_ristou_use_entity_picture: false
ulm_custom_card_ristou_use_badge: true
ulm_custom_card_ristou_map_enable: false
ulm_custom_card_ristou_find_device_script: ""
ulm_custom_card_ristou_zones:
ulm_custom_card_ristou_person_driving_entity: ""
ulm_custom_card_ristou_map_aspect_ratio: "466:200"
ulm_custom_card_ristou_map_hours_to_show: 0
ulm_custom_card_ristou_map_default_zoom: 11
ulm_custom_card_ristou_camera_entity_light: ""
ulm_custom_card_ristou_camera_entity_dark: ""
show_icon: false
show_name: false
show_label: false
triggers_update: "all"
styles:
grid:
- grid-template-areas: >
[[[
if (variables.ulm_custom_card_ristou_map_enable) {
return "\"item1\" \"item3\"";
} else if (
variables.ulm_custom_card_ristou_camera_entity_light !== ""
&& variables.ulm_custom_card_ristou_camera_entity_dark !== ""
) {
return "\"item1\" \"item2\"";
} else {
return "\"item1\""
}
]]]
- grid-template-columns: >
[[[
return "1fr";
]]]
- grid-template-rows: >
[[[
return "1fr";
]]]
card:
- border-radius: "var(--border-radius)"
- box-shadow: "var(--box-shadow)"
- padding: "0px"
custom_fields:
item2:
- display: >
[[[
if (
variables.ulm_custom_card_ristou_camera_entity_light !== ""
&& variables.ulm_custom_card_ristou_camera_entity_dark !== ""
&& !variables.ulm_custom_card_ristou_map_enable
) {
return "block";
} else {
return "none";
}
]]]
item3:
- display: >
[[[
if (variables.ulm_custom_card_ristou_map_enable) {
return "block";
} else {
return "none";
}
]]]
custom_fields:
item1:
###############
### 1ST ROW ###
###############
card:
type: "custom:button-card"
template:
- "icon_more_info"
styles:
grid:
- grid-template-areas: "'item1 item2 item3'"
- grid-template-columns: "min-content 1fr auto"
- grid-template-rows: "min-content"
custom_fields:
item3:
- display: >
[[[
if (variables.ulm_custom_card_ristou_find_device_script !== "") {
return "block";
} else {
return "none";
}
]]]
custom_fields:
###################
### PERSON ICON ###
###################
item1:
card:
type: "custom:button-card"
entity: "[[[ return entity.entity_id ]]]"
icon: >
[[[
if (!variables.ulm_custom_card_ristou_use_badge) {
var zones = variables.ulm_custom_card_ristou_zones;
var person_location = entity.state;
var driving_state = "off"
if (variables.ulm_custom_card_ristou_person_driving_entity !== "") {
driving_state = states[variables.ulm_custom_card_ristou_person_driving_entity].state;
}
if (driving_state === "on" || driving_state === "true") {
return "mdi:car";
} else {
if (person_location !== 'home'){
for (const item of zones){
if (person_location == states[item]?.attributes?.friendly_name){
var icon = (states[item].attributes.icon !== null) ? states[item].attributes.icon : 'mdi:help-circle';
return icon ;
} else if (person_location == 'not_home'){
return "mdi:home-minus";
}
}
} else{
return "mdi:home-variant";
}
}
} else {
return "mdi:face-man";
}
]]]
show_entity_picture: "[[[ return variables.ulm_custom_card_ristou_use_entity_picture ]]]"
entity_picture:
"[[[ return variables.ulm_custom_card_ristou_use_entity_picture != false ? states[entity.entity_id].attributes.entity_picture\
\ : null ]]]"
styles:
icon:
- color: >
[[[
if (!variables.ulm_custom_card_ristou_use_badge) {
var zones = variables.ulm_custom_card_ristou_zones;
var person_location = entity.state;
var driving_state = "off"
if (variables.ulm_custom_card_ristou_person_driving_entity !== "") {
driving_state = states[variables.ulm_custom_card_ristou_person_driving_entity].state;
}
if (driving_state === "on" || driving_state === "true") {
return 'rgba(var(--color-red),0.9)';
} else {
if (person_location !== 'home'){
for (const item of zones){
if (person_location == states[item]?.attributes?.friendly_name){
return 'rgba(var(--color-yellow),0.9)';
} else if (person_location == 'not_home'){
return 'rgba(var(--color-blue),0.9)';
}
}
} else{
return 'rgba(var(--color-green),0.9)';
}
}
} else {
return "rgba(var(--color-theme),0.9)";
}
]]]
- width: >
[[[
if (variables.ulm_custom_card_ristou_use_entity_picture !== true){
return "20px";
} else {
return "42px";
}
]]]
- place-self: >
[[[
if (variables.ulm_custom_card_ristou_use_entity_picture !== true){
return "center";
} else {
return "stretch stretch";
}
]]]
img_cell:
- background-color: >
[[[
if (!variables.ulm_custom_card_ristou_use_badge) {
var zones = variables.ulm_custom_card_ristou_zones;
var person_location = entity.state;
var driving_state = "off"
if (variables.ulm_custom_card_ristou_person_driving_entity !== "") {
driving_state = states[variables.ulm_custom_card_ristou_person_driving_entity].state;
}
if (driving_state === "on" || driving_state === "true") {
return 'rgba(var(--color-red),0.2)';
} else {
if (person_location !== 'home'){
for (const item of zones){
if (person_location == states[item]?.attributes?.friendly_name){
return 'rgba(var(--color-yellow),0.2)';
} else if (person_location == 'not_home'){
return 'rgba(var(--color-blue),0.2)';
}
}
} else {
return 'rgba(var(--color-green),0.2)';
}
}
} else {
return 'rgba(var(--color-theme),0.05)';
}
]]]
card:
- box-shadow: "none"
- border-radius: "var(--border-radius) var(--border-radius) 0px 0px"
- padding: "12px 0px 12px 12px"
custom_fields:
notification:
- border-radius: "50%"
- position: "absolute"
- left: "38px"
- top: "8px"
- height: "16px"
- width: "16px"
- border: "2px solid var(--card-background-color)"
- font-size: "12px"
- line-height: "14px"
- background-color: >
[[[
var zones = variables.ulm_custom_card_ristou_zones;
var person_location = entity.state;
var driving_state = "off"
if (variables.ulm_custom_card_ristou_person_driving_entity !== "") {
driving_state = states[variables.ulm_custom_card_ristou_person_driving_entity].state;
}
if (driving_state === "on" || driving_state === "true") {
return "rgba(var(--color-red),1)";
} else {
if (person_location !== 'home'){
for (const item of zones){
if (person_location == states[item]?.attributes?.friendly_name){
return "rgba(var(--color-yellow),1)";
} else if (person_location == 'not_home'){
return "rgba(var(--color-blue),1)";
}
}
} else{
return "rgba(var(--color-green),1)";
}
}
]]]
- display: >
[[[
if (variables.ulm_custom_card_ristou_use_badge) {
return "block";
} else {
return "none";
}
]]]
custom_fields:
notification: >
[[[
var zones = variables.ulm_custom_card_ristou_zones;
var person_location = entity.state;
var driving_state = "off"
var icon = "mdi:help-circle"
if (variables.ulm_custom_card_ristou_person_driving_entity !== "") {
driving_state = states[variables.ulm_custom_card_ristou_person_driving_entity].state;
}
if (driving_state === "on" || driving_state === "true") {
icon = 'mdi:car';
} else {
if (person_location !== 'home'){
for (const item of zones){
if (person_location == states[item]?.attributes?.friendly_name){
icon = (states[item].attributes.icon !== null) ? states[item].attributes.icon : 'mdi:help-circle';
} else if (person_location == 'not_home'){
icon = 'mdi:home-minus';
}
}
} else{
icon = 'mdi:home-variant';
}
}
return '<ha-icon icon="' + icon + '" style="width: 10px; height: 10px; color: var(--primary-background-color);"></ha-icon>';
]]]
#####################
### LABEL + STATE ###
#####################
item2:
card:
type: "custom:button-card"
entity: "[[[ return entity.entity_id ]]]"
name: "[[[ return variables.ulm_custom_card_ristou_name ]]]"
label: >-
[[[
var location = entity.state
var driving_state = "off"
if (variables.ulm_custom_card_ristou_person_driving_entity !== "") {
driving_state = states[variables.ulm_custom_card_ristou_person_driving_entity].state;
}
if (driving_state === "on" || driving_state === "true") {
return variables.ulm_custom_card_ristou_person_driving;
} else {
let state = location;
let option = ["home", "not_home", "unavailable", "unknown"]
return (option.includes(state)) ? variables.ulm_translation_state : state
}
]]]
#####################
### FIND MY PHONE ###
#####################
item3:
card:
template:
- "icon_info_bg"
- "blue"
show_name: false
show_label: false
type: "custom:button-card"
entity: "[[[ return variables.ulm_custom_card_ristou_find_device_script ]]]"
icon: "[[[ return variables.ulm_custom_card_ristou_icon ]]]"
tap_action:
action: "toggle"
styles:
card:
- box-shadow: "none"
- border-radius: "var(--border-radius)"
- padding: "12px"
###############
### 2ND ROW ###
###############
item2:
##################
### STATIC MAP ###
##################
card:
type: "picture-entity"
show_state: false
show_name: false
camera_view: "auto"
entity: >-
[[[
if (hass.themes.darkMode) {
return variables.ulm_custom_card_ristou_camera_entity_dark;
} else {
return variables.ulm_custom_card_ristou_camera_entity_light;
}
]]]
style:
.: |
ha-card {
box-shadow: none;
border-radius: 0px 0px var(--border-radius) var(--border-radius);
}
item3:
###################
### BUILTIN MAP ###
###################
card:
type: "map"
default_zoom: "[[[ return variables.ulm_custom_card_ristou_map_default_zoom ]]]"
aspect_ratio: "[[[ return variables.ulm_custom_card_ristou_map_aspect_ratio ]]]"
hours_to_show: "[[[ return variables.ulm_custom_card_ristou_map_hours_to_show ]]]"
entities: "[[[ return variables.ulm_custom_card_ristou_zones ]]]"
style:
ha-map$: |
.leaflet-control-attribution {
visibility: hidden;
}
.leaflet-control-zoom {
visibility: hidden;
}
.: |
ha-card {
box-shadow: none;
border-radius: 0px 0px var(--border-radius) var(--border-radius);
}