Person Card with Static Map API Background

Hi community,

I have found somewhere on reddit (can not remember the exact link) a very nice person card.
So its actually not my idea, but I couldn’t find it here in the community forum, so I will show it here.
After some modifications my card looks like this:
grafik

It uses geoapify to get a static backround image of your current device_tracker position.
So you will need an geoapify account.
The free plan allows you 3000 requests per day.
For me its more than enough, but if you need more you have to choose a different plan and pay for it.

Additionally you will need some integrations frome the HACS store:

Here is the Code:

type: custom:stack-in-card
card_mod:
  style: |
    ha-card {
      background: url('https://maps.geoapify.com/v1/staticmap?style=osm-bright&width=600&height=230&center=lonlat:{{ state_attr('device_tracker.MY_IPHONE', 'longitude') }},{{ state_attr('device_tracker.MY_IPHONE', 'latitude') }}&zoom=14.0&marker=lonlat:{{ state_attr('device_tracker.MY_IPHONE', 'longitude') }},{{ state_attr('device_tracker.MY_IPHONE', 'latitude') }};type:material;color:%23ff3421;icontype:awesome&scaleFactor=2&apiKey=YOUR_API_KEY');
      background-size: cover;
      background-blend-mode: overlay;
      background-color: rgba(var(--rgb-card-background-color), 0.5);
    }
cards:
  - type: custom:mushroom-template-card
    entity: person.MY_PERSON
    primary: MY_PERSON
    secondary: >-
      {{ iif(states(entity) == 'not_home', 'away', states(entity)) | title }} |
      {{ states('sensor.MY_IPHONE_geocoded_location') }}
    picture: '{{ state_attr(entity, ''entity_picture'') }}'
    badge_icon: >-
      {% set zone = iif(states(entity) == 'not_home', 'away', states(entity)) %}
      {%- if 'home' in zone.lower() -%}
        mdi:home
      {%- elif zone == 'MY_WORK' -%}
        mdi:office-building
      {%- else -%}
        mdi:home-export-outline
      {%- endif -%}
    badge_color: >-
      {% set zone = iif(states(entity) == 'not_home', 'away', states(entity))
      %}  {%- if 'home' in zone.lower() -%}
        green
      {%- elif zone == 'MY_WORK' -%}
        blue
      {%- else -%}
        red
      {%- endif -%}
    fill_container: true
    multiline_secondary: false
    layout: horizontal
    tap_action:
      action: more-info
    card_mod:
      style: |
        :host {
          height: 70px;
          --mush-icon-size: 60px;
          --secondary-text-color: var(--primary-text-color);
        }
  - type: custom:mushroom-chips-card
    chips:
      - type: entity
        entity: sensor.MY_IPHONE_steps
      - type: entity
        entity: sensor.MY_IPHONE_battery_state
    card_mod:
      style: |
        ha-card {
          --chip-box-shadow: 0px 0px 0px 0px;
          --chip-background: none;
        }

To make it work you have to replace the following text:

  • YOUR_API_KEY → This is your API Key from Geoapify
  • MY_IPHONE → This is the name of your device_tracker. I used the device_tracker from the mobile_app integration
  • MY_PERSON → This is the name of your person entity
  • MY_WORK → This is the zone where you work (optional)
8 Likes

Awesome thank you,


I’m just little tweak

    secondary: >-
      {{ iif(states(entity) == 'not_home', 'away', states(entity)) | title }} |
      {{ states('sensor.MY_IPHONE_geocoded_location') }}
    picture: '{{ state_attr(entity, ''entity_picture'') }}'

Text was so long to show on card.

So my looks

    secondary: >-
      {{ iif(states(entity) == 'not_home', 'away', states(entity)) | title }} |
      ul. {{state_attr('sensor.pogo5x_geocoded_location', 'thoroughfare') }}
      čís.{{ state_attr('sensor.pogo5x_geocoded_location', 'premises') }} PSČ {{
      state_attr('sensor.pogo5x_geocoded_location', 'postal_code') }}

Thank you for your improvment :smiley: .
I will add it also into my cards.

Unfortunatelly I can not see the attribute premises, maybe because I am using an iPhone?
But for me the attributes Name, Postal Code and Sub Locality worked quit well.

Hello again , how can I change color text or opacity?
on computer is text barely visible.

I think its the 0.5 in line 8.

background-color: rgba(var(--rgb-card-background-color), 0.5);

that’s for background color and opacity.

Oh so I misunderstood your question.
In my opinion it makes more sense to change the opacity of the background image than the text color opacity.
And also I don’t know how to change the text opacity, sorry.

But you can maybe change the the map style.
Please see the Geoapify Docs for more infos.
Currently I use osm-bright.
Simply change this to a darker style e.g. dark-matter-yellow-roads if you are using a bright text color.

One more improvment from my side:

It is also possible to change the color or icon of the map marker depending on your location.
Simply change the background url for this:

background: url('https://maps.geoapify.com/v1/staticmap?style=osm-bright&width=600&height=230&center=lonlat:{{ state_attr('device_tracker.MY_IPHONE', 'longitude') }},{{ state_attr('device_tracker.MY_IPHONE', 'latitude') }}&zoom=14.0&marker=lonlat:{{ state_attr('device_tracker.MY_IPHONE', 'longitude') }},{{ state_attr('device_tracker.MY_IPHONE', 'latitude') }};type:material;{{ iif(is_state('person.MY_PERSON', 'home'), 'color:green;icon:home;', iif(is_state('person.MY_PERSON', 'MY_WORK'), 'color:blue;icon:building;', 'color:red;')) }}icontype:awesome&scaleFactor=2&apiKey=YOUR_API_KEY');

it wont work for me…whats my fault?

type: custom:stack-in-card
card_mod:
  style: |
    ha-card {
      background: url('https://maps.geoapify.com/v1/staticmap?style=osm-bright&width=600&height=230&center=lonlat:{{ state_attr('device_tracker.s24_ultra_marko', 'longitude') }},{{ state_attr('device_tracker.s24_ultra_marko', 'latitude') }}&zoom=14.0&marker=lonlat:{{ state_attr('device_tracker.s24_ultra_marko', 'longitude') }},{{ state_attr('device_tracker.s24_ultra_marko', 'latitude') }};type:material;color:%23ff3421;icontype:awesome&scaleFactor=2&apiKey=);
      background-size: cover;
      background-blend-mode: overlay;
      background-color: rgba(var(--rgb-card-background-color), 0.5);
    }
cards:
  - type: custom:mushroom-template-card
    entity: person.marko
    primary: MY_PERSON
    secondary: >-
      {{ iif(states(entity) == 'not_home', 'away', states(entity)) | title }} |
      {{ states('sensor.MY_IPHONE_geocoded_location') }}
    picture: '{{ state_attr(entity, ''entity_picture'') }}'
    badge_icon: >-
      {% set zone = iif(states(entity) == 'not_home', 'away', states(entity)) %}
      {%- if 'home' in zone.lower() -%}
        mdi:home
      {%- elif zone == 'MY_WORK' -%}
        mdi:office-building
      {%- else -%}
        mdi:home-export-outline
      {%- endif -%}
    badge_color: >-
      {% set zone = iif(states(entity) == 'not_home', 'away', states(entity))
      %}  {%- if 'home' in zone.lower() -%}
        green
      {%- elif zone == 'MY_WORK' -%}
        blue
      {%- else -%}
        red
      {%- endif -%}
    fill_container: true
    multiline_secondary: false
    layout: horizontal
    tap_action:
      action: more-info
    card_mod:
      style: |
        :host {
          height: 70px;
          --mush-icon-size: 60px;
          --secondary-text-color: var(--primary-text-color);
        }
  - type: custom:mushroom-chips-card
    chips:
      - type: entity
        entity: sensor.MY_IPHONE_steps
      - type: entity
        entity: sensor.MY_IPHONE_battery_state
    card_mod:
      style: |
        ha-card {
          --chip-box-shadow: 0px 0px 0px 0px;
          --chip-background: none;
        }


5rtz

Thank you for this card. I modify mine a little bit using your suggestion about background
image
My code:

type: custom:stack-in-card
mode: vertical
card_mod:
  style: |
    ha-card {
      border: none !important;
     # background: none !important;
      --vertical-stack-card-gap: 10px;
      background: url('https://maps.geoapify.com/v1/staticmap?style=dark-matter-yellow-roads&width=600&height=230&center=lonlat:{{ state_attr('device_tracker.sm_s918u', 'longitude') }},{{ state_attr('device_tracker.sm_s918u', 'latitude') }}&zoom=14.0&marker=lonlat:{{ state_attr('device_tracker.sm_s918u', 'longitude') }},{{ state_attr('device_tracker.sm_s918u', 'latitude') }};type:material;color:%23ff3421;icontype:awesome&scaleFactor=2&apiKey=API KEY');
      background-size: 135%;
    }
cards:
  - type: custom:stack-in-card
    mode: horizontal
    card_mod:
      style: |
        ha-card {
          border: none !important;
          background: none !important;
        }
    cards:
      - type: custom:mushroom-person-card
        name: Yevgeniy
        entity: person.yevgeniy
        layout: vertical
        icon_type: entity-picture
        primary_info: state
        secondary_info: false
        card_mod:
          style:
            mushroom-shape-avatar$: |
              .picture {
               display: flex;
               border-radius: 50%;
               {% if states(config.entity) == 'home' %}
                 animation: pinggreen 6s infinite;
               {% else %}
                 animation: pingred 6s infinite;
               {% endif %}
              }
              @keyframes pinggreen {
               0% {box-shadow: 0 0 5px 3px rgba(var(--rgb-green), 0.9);}
               100% {box-shadow: 0 0 5px 15px transparent;}
              }
              @keyframes pingred {
               0% {box-shadow: 0 0 5px 3px rgba(var(--rgb-red), 0.9);}
               100% {box-shadow: 0 0 5px 15px transparent;}
              }
            .: |
              ha-card { 
              border: none !important;
              background: none !important;
              margin-left: -50px !important;
              }            
      - type: custom:stack-in-card
        mode: vertical
        card_mod:
          style: |
            ha-card {
              border: none !important;
              background: none !important;
              margin-left: -55px !important;
            } 
        cards:
          - type: custom:mushroom-template-card
            primary: >-
              {%- if is_state('sensor.sm_s918u_battery_state', 'charging') %}

              Charging 🔌

              {%- elif is_state('sensor.sm_s918u_battery_state', 'discharging')
              %}

              Discharging 🙃

              {% else %}

              Full 💯

              {% endif %}
            secondary: Battery {{ states('sensor.sm_s918u_battery_level') }}%
            entity: sensor.sm_s918u_battery_state
            icon: |2
                    {% set bl = states('sensor.sm_s918u_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_s918u_battery_level') | int %}
                    {% if bl < 10 %} red
                    {% elif bl < 20 %} red
                    {% elif bl < 30 %} red
                    {% elif bl < 40 %} orange
                    {% elif bl < 50 %} orange
                    {% elif bl < 60 %} green
                    {% elif bl < 70 %} green
                    {% elif bl < 80 %} green
                    {% elif bl < 90 %} green
                    {% elif bl < 100 %} green
                    {% elif bl == 100 %} green
                    {% else %} grey
                    {% endif %}
            card_mod:
              style: |
                ha-card {
                  border: none !important;
                  background: none !important;
                  justify-content: center;
                  --chip-icon-size: 24px;
                  --chip-height: 54px;
                  --chip-with:
                  width: var(--chip-height) !important;
                  border-radius: 50% !important;                      
                }
              alignment: center
  - type: custom:mushroom-chips-card
    chips:
      - type: entity
        card_mod:
          style: |
            ha-card {
              border: none !important;
              background: none !important;
              font-size: 30px !important;
            }
        entity: sensor.sm_s918u_geocoded_location
        icon: mdi:google-maps
        use_entity_picture: false
    card_mod:
      style: |
        ha-card {
          border: none !important;
          background: none !important;
          margin-left: -23px !important;
          
        }
    alignment: center
1 Like

Fantastic card! But why is my map not as dark as yours? The text is barely visible

check this part of url line
Thank you for compliment :grinning:

Problem is that’s another map. I want the original but dark one as elVit and supperka shows in their posts. Not sure where i fail, i copied the same code as in the first post :grimacing:

Try to change font color and opacity

1 Like

Nice! for the step info, does the iphone have to be on the same network as Home-assistant? or can it pull it from the cloud

Awesome looking card!
Unfortunately I don’t see the possibility to create an API on the website of Geoapify (via <Geoapify / My Projects> ).

Hopefully their support can help me out, so I can create this great Person Card!

Maybe this will help you:

text-shadow: 0px 0px 5px white;

Add this code simply in the ha-card context where the background image is set.

For alternative configurations of text-shadow see this link.

1 Like