Person Cards - Show Off Yours

You could use person.person1 and adapt the values to suit your needs. That would probably be the easiest thing to do.

Other than person.xxx, I have two sensors for each person that give more detail on location/status:

  • input_select.person1 - this provides one of five states, Home/Away/Just Left/Just Arrived/Extended Away. These are managed by a Node-RED flow described above.
  • sensor.person1 - I take the value from input_select.person1, and set that as the state of sensor.person1 if it’s Home, Just Arrived, or Just Left. If person.person1 is Away (or not_home, I think it’s changed over time), I set it to the value of what’s listed in the Locality attribute of person1’s geocoded location.If none of those conditions are met, I set it to the states of person.person1, which is usually a zone name. Here’s the template for that:
  - sensor:
    - unique_id: status_person1
      name: Status Person1
      picture: local/person1.jpg
      state: >
        {% if is_state('input_select.person1', 'Just Left') 
          or is_state('input_select.person1', 'Just Arrived')
          or is_state('input_select.person1', 'Home') %}
          {{ states('input_select.person1') }}
        {% elif is_state('person.person1','Away') or is_state('person.person1','not_home') %}
          {{ state_attr('sensor.person1_geocoded_location', 'Locality') }}
        {% else %}
          {{ states('person.person1') }}
        {% endif %}

I could probably do the same thing with just person.person1 and one other sensor, but this thing grew over time, so I started with one and now I have two.

EDIT: I’m constantly changing these cards. I updated my YAML above.

Thank you very much for the quick response. I appreciate that. I like the sensor status idea better than person.person1 entity. However, can this be achieved without having Node-RED?

I’m sure it can, yes. All it’s doing is setting the state of input_select.person1 based on the state of person.person1 and some delays.

Great! Please excuse my lack of knowledge since I am still in the process of learning HA. How does the state of input_select.person1 change? Do have a script or automation that check the state of the entity person.person1?

Well, I’m no programmer. I imported the Node-RED flow from someone else. But what I can tell you is that it watches person.person1 for a state change, and then updates input_select.person1 based on its state and how much time has passed. I had to create an input_select (helper) for each person and define the five states.

Hallo, finally after two nights of playing with it, it’s starting to look like I wanted, thx for this nice card and many useful hints here in the thread. I am only struggling with the “find my phone” function, using the double-tap-action as remotly fired alarm (what is working nicely on Smasung A22 and xiaomi Lite, but not so good on Honor mobiles for my kids) strange is, that without the double-tap action (called as service previously) it used to work fine on all devices, but now when inplemented as double-tap on the face it stopped working for Honor mobiles. Maybe I had to misspell st.
Below is the pic of final layout and some sample of the code. If someone has solved similar problem I will be glad for sharing of his/her solution :slight_smile:
Thanks.
Willy

code sample:

type: custom:button-card
entity: person.xxx
aspect_ratio: 1/1
name: Willy
show_entity_picture: true
show_name: true
double_tap_action:
  action: call-service
  confirmation:
    text: Alarm will sound, OK?
  service: script.find_phone_xxx
state:
  - value: not_home
    styles:
      card:
        - background-color: '#404040'
      custom_fields:
        icon:
          - border-color: '#B0B0B0'
          - opacity: 30%
styles:
  card:
    - border-radius: 5%
    - padding: 5%
    - color: lightgray
    - font-size: 11px
  grid:
    - grid-template-areas: '"icon status" "n network" "battery proximity"'
    - grid-template-columns: 1fr 1fr
    - grid-template-rows: 1fr min-content min-content min-content min-content
  name:
    - font-size: 16px
    - justify-self: left
    - padding-bottom: 5px
    - justify-self: left
  custom_fields:
    icon:
      - width: 120%
      - pointer-events: none
      - display: grid
      - border: 3px inset
      - border-color: |
          [[[
            var stav=states['person.xxx'].state;
            if (stav=='home') { 
            return `#77c66e`;
            } 
            if ((stav=='xxx')|(stav=='yyy')) { 
            return `darkorange`;
            } 
            if ((stav=='zzz')|(stav=='yyy')|(stav=='sss')|(stav=='ddd')) { 
            return `deepskyblue`;
            } 
          ]]] 
      - border-radius: 100px
      - margin: 0 0 0 0
      - justify-self: left
      - opacity: 1
    status:
      - align-self: start
      - justify-self: end
      - text-transform: capitalize
      - color: lightgray
    battery:
      - justify-self: left
      - font-size: 11px
      - color: lightgray
      - '--icon-color': |
          [[[ var l = states['sensor.xxx_phone_battery_level'].state;
            if (l < 10) return "#e45649";
            if (l < 20) return "#ff9050";
            if (l < 30) return "#ffb040";
          else return "#77c66e"
          ]]]
    network:
      - justify-self: end
      - font-size: 11px
      - color: lightgray
      - '--icon-color': |
          [[[ var n = states['sensor.xxx_phone_network_type'].state;
            if ((n=='cellular')|(n=='wifi')) return "#77c66e";
          else return "grey"
          ]]]
    proximity:
      - justify-self: end
      - font-size: 11px
      - color: lightgray
      - '--icon-color': |
          [[[ var p = states['proximity.xxxx'].state;
            if (p > 1) return "#ffb040";
            if (p > 20) return "#ff9050";
            if (p > 100) return "#e45649";
          else return "#77c66e"
          ]]]
custom_fields:
  icon: >
    [[[ return entity === undefined ? null : `<img
    src="${states['person.xxx'].attributes.entity_picture}" width="100%">`;
    ]]]
  status: |
    [[[ var stav = states['person.xxx'].state;
        var doma = `<ha-icon icon="mdi:home" style="color: #77c66e;`
        var produkce = `<ha-icon icon="mdi:city-variant-outline" style="color: deepskyblue;`
        var volno = `<ha-icon icon="mdi:gymnastics" style="color: deepskyblue;`
        var nasi = `<ha-icon icon="mdi:home-outline" style="color: darkorange;`
        var pryc = `<ha-icon icon="mdi:home-export-outline" style="color: lightgray;width: 20px; height: 20px;"></ha-icon><span> Pryč</span>`
        var solid = ` width: 20px; height: 20px;"></ha-icon><span> ${entity.state}</span>`
      if (stav=='home') { 
        return doma+solid
      }
      if ((stav=='xxx')|(stav=='yyy')|(stav=='zzz')) { 
        return produkce+solid
      } 
      if ((stav=='ddd')|(stav=='sss')) { 
        return volno+solid
      } 
      if ((stav=='fff')|(stav=='eee')) { 
        return nasi+solid
      } else {
        return pryc
      }
    ]]]
  battery: |
    [[[
      var i = states['sensor.xxx_phone_battery_level'].attributes.icon;
      var b = states['sensor.xxx_phone_battery_level'].state;
      return `<ha-icon icon='${i}' style='width:20px; height: 20px; vertical-align:2px; color: var(--icon-color);'></ha-icon>${b}%`
    ]]] 
  network: |
    [[[
      var i = states['sensor.xxx_phone_network_type'].attributes.icon;
      var s = parseFloat(states['sensor.xxx_phone_mobile_tx_gb'].state).toFixed(1);
      var r = parseFloat(states['sensor.xxx_phone_mobile_rx_gb'].state).toFixed(1);
      return `<ha-icon icon='${i}' style='width:20px; height: 20px; vertical-align:2px; color: var(--icon-color);'></ha-icon> ${r} / ${s} GB`
    ]]] 
  proximity: |
    [[[
      return `<ha-icon
        icon="mdi:map-marker-distance"
        style="width: 20px; height: 20px; color: var(--icon-color)">
        </ha-icon> <span>\<span>${states['proximity.xxx'].state} Km</span></span>`
    ]]]

just don’t forget to replace “xxx”, “yyy”, “zzz”, “sss”, “ddd”, “fff”, “eee” (I hope I didn’t forget somewhere else the original entity names…) with correct entites.
Cheers :slight_smile:

edit: I got it working finally as intended !! (a typo of course in the script…) so working for Samsung and Honor phones without problems. I prefer a double-tap action to fire the script, since long-press doesn’t work well on iPad (sometimes doesn’t fire…)

2 Likes

Strange… I’m trying to get that to work, and I can’t. I can easily call the script from the UI, but this isn’t working:

hold_action:
  action: call-service
  service: script.locate_person1s_iphone
  confirmation:
    text: '[[[ return `Send critical notification to iPhone?` ]]]'

I get the confirmation text, but the script doesn’t fire. Note that I’m doing this with the same device I’m trying to notify. I wonder if that’s the problem.

Hi, did you try to search inside the logs? There might be more reasons for this.
I guess you have s a similar script like I do:

alias: Find the phone
sequence:
  - service: notify.mobile_app_xxx_phone
    data:
      message: Dont leave your phone unattened!
      title: Searching for your phone from the HA app...
      data:
        ttl: 0
        priority: high
        channel: alarm_stream
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
mode: single
icon: mdi:cellphone-sound

If you just dont hear the sound from the phone it also can be caused by the setting.

Settings/apps/HA…/Notifications/ you should see Alarm_Stream and under it just select some longer song, since thge default alarms are just some beeps.

I’ve actually set up the script to trigger a Node-RED flow, which is how I handle all of my other scripts.

I can trigger the flow from Node-RED, but not from the Lovelace call. I have to believe the problem is the YAML in Lovelace.

EDIT: It was my YAML in Lovelace. This works for me:

hold_action:
  action: call-service
  service: script.turn_on
  service_data:
    entity_id: script.locate_person1s_iphone
  confirmation:
    text: '[[[ return `Send critical notification to iPhone?` ]]]'

Hello. Awesome work. “xxx”, “yyy”, “zzz”, “sss”, “ddd”, “fff”, “eee” are zone entities?

Hi, yes, there are different entities to be binded:

  1. person.xxx (created person what is shown at the picture)
  2. zone names (everywhere where is the variable “stav” (in CZ language state, but we can’t use original EN name “state” as variable) it is used for zone names, use your predefined zone names instead),
  3. phone sensors (e.g. “sensor.xxx_phone_battery_level”) replace this with your correct phone sensor for monitoring a battery lvl.
    cheers :slight_smile:

iPhone (my ipad) is not 100% working with this… it beeps just once and even only some times…
iPad is strange imho :wink: buy some android device :wink:

Thanks a lot

I have the HA companion app on my iphone but for some reason, there are no sensors like: sensor.xxx_phone_mobile_tx_gb
sensor.xxx_phone_mobile_rx_gb
Any idea how they are created?

@raub21 , all sensors must be allowed in advance by the app settings (setting of the mobile app lovelace - left menu - settings - setting of the accomp app - sensors…) and also the corresponding sensor must be allowed to read by HA app in the phone permisssion setting. Try different combinations, you will find some working variant for sure (the exact sensor may have different name - not exactly the same like I have - on Android the sensors have many names depending on the phone producer, on iOs I guess sensor names will not be so changing but for sure they will be different from any Android device)

When allowing the permissions just remember to refresh / reload the page (close/open) the app then look under the integration - equipment - sensors page to see if any new sensors apeared.
W.

1 Like

@VB_Master . Thank you for your explanation. Home assistant mobile app has all the permissions. I did check all the sensors it creates but there is none that monitor the data usage of the phone ( from the carrier Tmobile). Maybe it is not applicable to ios devices. Too bad, I was actually hoping I can keep an eye on the kids data usage so that they dont finish it before the month is over. Thank you.

Having troubles getting the battery icon centered like the home any help?

Also wondering if it’s possible to add a phone charging state so the battery icon changes when charging to a battery with the lightning bolt.

then im hoping to set up icloud3 for tracking so i need the home at the top and the distance and time at the bottom. currently confused when the icloud3 guide says install waze route calculator is that different then waze travel time?

type: custom:button-card
entity: person.eric
aspect_ratio: 3/1
name: Eric
show_entity_picture: true
show_name: false
double_tap_action:
  action: none
  confirmation:
    text: Alarm will sound, OK?
  service: script.find_phone_xxx
state:
  - value: not_home
    styles:
      card:
        - background-color: '#404040'
      custom_fields:
        icon:
          - border-color: '#B0B0B0'
          - opacity: 30%
styles:
  card:
    - border-radius: 5%
    - padding: 13%
    - color: lightgray
    - font-size: 11px
  grid:
    - grid-template-areas: '"icon status" "battery proximity"'
    - grid-template-columns: 1fr 1fr
    - grid-template-rows: 1fr min-content
  name:
    - font-size: 16px
    - justify-self: left
    - padding-bottom: 5px
    - justify-self: left
  custom_fields:
    icon:
      - width: 38%
      - pointer-events: none
      - display: grid
      - border: 10px inset
      - padding-right: 0px
      - border-color: |
          [[[
            var stav=states['person.eric'].state;
            if (stav=='home') { 
            return `#77c66e`;
            } 
            if ((stav=='away')|(stav=='yyy')) { 
            return `darkorange`;
            } 
            if ((stav=='work')|(stav=='yyy')|(stav=='sss')|(stav=='ddd')) { 
            return `deepskyblue`;
            } 
          ]]] 
      - border-radius: 250px
      - margin: 0 0 0 75%
      - justify-self: left
      - opacity: 1
    status:
      - justify-self: end
      - text-transform: capitalize
      - color: lightgray
    battery:
      - justify-self: start
      - font-size: 11px
      - color: lightgray
      - '--icon-color': |
          [[[ var l = states['sensor.iphone_battery_level'].state;
            if (l < 10) return "#e45649";
            if (l < 49) return "#f2db07";
            if (l < 50) return "#25fc12";
          else return "#77c66e"
          ]]]
custom_fields:
  icon: >
    [[[ return entity === undefined ? null : `<img
    src="${states['person.eric'].attributes.entity_picture}" width="100%">`; ]]]
  status: |
    [[[ var stav = states['person.eric'].state;
        var doma = `<ha-icon icon="mdi:home" style="color: #77c66e;`
        var produkce = `<ha-icon icon="mdi:city-variant-outline" style="color: deepskyblue;`
        var volno = `<ha-icon icon="mdi:gymnastics" style="color: deepskyblue;`
        var nasi = `<ha-icon icon="mdi:home-outline" style="color: darkorange;`
        var pryc = `<ha-icon icon="mdi:home-export-outline" style="color: lightgray;width: 20px; height: 20px;"></ha-icon><span> Pryč</span>`
        var solid = ` width: 20px; height: 20px;"></ha-icon><span> ${entity.state}</span>`
      if (stav=='home') { 
        return doma+solid
      }
      if ((stav=='work')|(stav=='xxx')|(stav=='zzz')) { 
        return produkce+solid
      } 
      if ((stav=='yyy')|(stav=='sss')) { 
        return volno+solid
      } 
      if ((stav=='fff')|(stav=='eee')) { 
        return nasi+solid
      } else {
        return pryc
      }
    ]]]
  battery: |
    [[[
      var i = states['sensor.iphone_battery_level'].attributes.icon;
      var b = states['sensor.iphone_battery_level'].state;
      return `<ha-icon icon='${i}' style='width:20px; height: 20px; vertical-align:2px; color: var(--icon-color);'></ha-icon>${b}%`
    ]]] 

This will show when the phone is charging… and it shows what you see in the picture… :slight_smile:

Capture

             - type: conditional
                card_mod:
                style: |
                  ha-card { 
                  border: 0 !important;
                  }
                conditions:
                  - entity: sensor.sm_f926u1_battery_state
                    state: "charging"
                card:
                  type: custom:mushroom-template-card
                  entity: sensor.sm_f926u1_battery_level
                  layout: vertical
                  icon_color: yellow
                  fill_container: true
                  name: Fold3
                  icon: mdi:battery-charging-medium
                  hide_name: true
                  primary: "Phone is charging..."
                  secondary: "Battery Level: {{ states('sensor.sm_f926u1_battery_level') }}%"
                  card_mod:
                    style: |
                      mushroom-shape-icon {
                        animation: blink 1s linear infinite;
                      }          
                      @keyframes blink {
                        50% {opacity: 0;}
                      }
                      ha-card { 
                      border: 0 !important;
                      }
              - type: conditional
                conditions:
                  - entity: sensor.sm_f926u1_battery_state
                    state: "full"
                card:
                  type: custom:mushroom-template-card
                  card_mod:
                    style: |
                      ha-card { 
                      border: 0 !important;
                      }
                  entity: sensor.sm_f926u1_battery_level
                  layout: vertical
                  icon: |2
                      {% set bl = states('sensor.sm_f926u1_battery_level') | int %}
                      {% if bl < 10 %} mdi:battery-outline
                      {% elif bl < 20 %} mdi:battery-10
                      {% elif bl < 30 %} mdi:battery-20
                      {% elif bl < 40 %} mdi:battery-30
                      {% elif bl < 50 %} mdi:battery-40
                      {% elif bl < 60 %} mdi:battery-50
                      {% elif bl < 70 %} mdi:battery-60
                      {% elif bl < 80 %} mdi:battery-70
                      {% elif bl < 90 %} mdi:battery-80
                      {% elif bl < 100 %} mdi:battery-90
                      {% elif bl == 100 %} mdi:battery
                      {% else %} mdi:battery-unknown
                      {% endif %}
                  icon_color: |2-
                      {% set bl = states('sensor.sm_f926u1_battery_level') | int %}
                      {% if bl < 10 %} #cc0c16
                      {% elif bl < 20 %} #e61e28
                      {% elif bl < 30 %} #e3464e
                      {% elif bl < 40 %} orange
                      {% elif bl < 50 %} #f0b93a
                      {% elif bl < 60 %} #f3f56c
                      {% elif bl < 70 %} #f2f536
                      {% elif bl < 80 %} #69f095
                      {% elif bl < 90 %} #2ee669
                      {% elif bl < 100 %} #05ad3b
                      {% elif bl == 100 %} #03872d
                      {% else %} grey
                      {% endif %}
                  primary: "Battery Level: {{ states('sensor.sm_f926u1_battery_level') }}%"
                  secondary: "Battery Temp: {{ states('sensor.sm_f926u1_battery_temperature') }}°"
                  tap_action:
                    action: more-info
                  fill_container: true
              - type: conditional
                card_mod:
                style: |
                  ha-card { 
                  border: 0 !important;
                  }
                conditions:
                  - entity: sensor.sm_f926u1_battery_state
                    state: "discharging"
                card:
                  type: custom:mushroom-template-card
                  card_mod:
                    style: |
                      ha-card { 
                      border: 0 !important;
                      }
                  entity: sensor.sm_f926u1_battery_level
                  layout: vertical
                  icon: |2
                      {% set bl = states('sensor.sm_f926u1_battery_level') | int %}
                      {% if bl < 10 %} mdi:battery-outline
                      {% elif bl < 20 %} mdi:battery-10
                      {% elif bl < 30 %} mdi:battery-20
                      {% elif bl < 40 %} mdi:battery-30
                      {% elif bl < 50 %} mdi:battery-40
                      {% elif bl < 60 %} mdi:battery-50
                      {% elif bl < 70 %} mdi:battery-60
                      {% elif bl < 80 %} mdi:battery-70
                      {% elif bl < 90 %} mdi:battery-80
                      {% elif bl < 100 %} mdi:battery-90
                      {% elif bl == 100 %} mdi:battery
                      {% else %} mdi:battery-unknown
                      {% endif %}
                  icon_color: |2-
                      {% set bl = states('sensor.sm_f926u1_battery_level') | int %}
                      {% if bl < 10 %} #cc0c16
                      {% elif bl < 20 %} #e61e28
                      {% elif bl < 30 %} #e3464e
                      {% elif bl < 40 %} orange
                      {% elif bl < 50 %} #f0b93a
                      {% elif bl < 60 %} #f3f56c
                      {% elif bl < 70 %} #f2f536
                      {% elif bl < 80 %} #69f095
                      {% elif bl < 90 %} #2ee669
                      {% elif bl < 100 %} #05ad3b
                      {% elif bl == 100 %} #03872d
                      {% else %} grey
                      {% endif %}
                  primary: "Battery Level: {{ states('sensor.sm_f926u1_battery_level') }}%"
                  secondary: "Battery Temp: {{ states('sensor.sm_f926u1_battery_temperature') }}°"
                  tap_action:
                    action: more-info
                  fill_container: true
                styles:
                  card:
                    height: 66px;

2 Likes

looks awesome i tried to make this into a card and then was going to add my person card picture posted above your post but i keep getting this error kinda confused…
image

I fixed the example… your “type: conditional” is spaced wrong … Yaml remember indents :slight_smile: