Show off your picture-elements uses

Starting with mcfrojd and his original setup, I created this modified look to provide info for my wife and I, combining life360 and Places. Using the config-template-card, I added the battery icon color change based on percentage to HSL 0 to 220. Pretty happy with it at this point, but may expand upon it in the future.

customized-picture_element_card_01
customized-picture_element_card_02 customized-picture_element_card_03

Also with looking ahead, here’s my floorplan I’ve started to work on for when I get the time to wall mount a tablet.

13 Likes

haha great! A post like that of course comes with the code… especially the setup of the presence images etc, please share?
Ive made up something like this, with images, background colors and overlays depending on presence/location myself, using buttons and a few backend template sensors, so would love to see if I can learn/borrow/use your techniques.

Im not using a picture-elements card so can’t post here, but did so here with the code a few posts below that.

btw, seem to have read elsewhere how you made these avatars, but cant find it, please tell ?

1 Like

Sorry, multiple things at work here, so it’s going to be a lengthy post.

First off, you need life360 and places. Then the images, my wife and I use an app called Bitmoji for those, and using the below png template and photoshop I created the different state images. You’ll want to set the circles to your lovelace background color and the rest to your default card color. Put them all in /www/images/person/ so that the Person_Status sensor can reference them.

ha_frame

Then the sensors:

binary_sensors:
  platform: template
    sensors:
      person_moving:
      friendly_name: "Person Moving"
        value_template: >-
          {% if state_attr('device_tracker.life360_person', 'place') == state_attr('device_tracker.life360_person', 'address') %}
            off
          {% elif is_state_attr('device_tracker.life360_person', 'driving', true) %}
            on
          {% elif is_state_attr('device_tracker.life360_person', 'moving', true) %}
            on
          {% else %}
            off
          {% endif %}

sensors:
  platform: template
    sensors:
      person_location:
        friendly_name: "Person Location"
        value_template: >-
          {% if state_attr('device_tracker.life360_person', 'place') == state_attr('device_tracker.life360_person', 'address') %}
            {{ state_attr('device_tracker.life360_person', 'place') }}
          {% elif states.sensor.person.attributes.place_name != "-" %}
              {{ state_attr('sensor.person', 'place_name') }}
          {% else %}
            {% if is_state('binary_sensor.person_moving', 'on') %}
              {% if state_attr('sensor.person', 'street_number') != '-' %}{{ state_attr('sensor.person', 'street_number')}} {% endif %}{% if state_attr('sensor.person', 'street') != '-' %}{{state_attr('sensor.person', 'street')}}{% endif %}{% if state_attr('sensor.person', 'city') != '-' %}, {{state_attr('sensor.person', 'city')}}, {% if state_attr('sensor.person', 'state_province') != '-' %}{{state_attr('sensor.person', 'state_province')}}{% endif %}{% endif %}
            {% else %}
              {{ state_attr('sensor.michael', 'street_number') + " " + state_attr('sensor.michael', 'street')}}
            {% endif %}  
          {% endif %}

      person_status:
        friendly_name: "Person Status"
        value_template: >-
          {% if is_state_attr('device_tracker.life360_person', 'driving', true) %}
            Driving near {{ states('sensor.person_location') }}
          {% elif is_state_attr('device_tracker.life360_person', 'moving', true) %}
            Moving near {{ states('sensor.person_location') }}
          {% else %}
            {{ states('sensor.person_location') }}
          {% endif %}
        entity_picture_template: >-
          {% if state_attr('sensor.person', 'place_type') == 'supermarket' %}
            /local/images/person/grocery.png
          {% elif state_attr('device_tracker.life360_person', 'place') == 'Work' %}
            /local/images/person/work.png
          {% elif state_attr('device_tracker.life360_person', 'place') == 'Home' %}
            /local/images/person/home.png
          {% elif state_attr('device_tracker.life360_person', 'driving') == true %}
            /local/images/person/driving.png
          {% elif state_attr('device_tracker.life360_person', 'moving') == true %}
            /local/images/person/moving.png
          {%else %} /local/images/person/home.png{%endif%}

      person_at_loc_since:
        friendly_name: "At Location Since"
        value_template: >-
          {% if (as_timestamp(now()) - as_timestamp(states.sensor.person_location.last_changed)) / 3600 < 24 %}
            Since {{ (states.sensor.person_location.last_changed.strftime("%s") | int ) | timestamp_custom("%-I:%M %p") }}
          {% else  %}
            Since {{ (states.sensor.person_location.last_changed.strftime("%s") | int ) | timestamp_custom("%a, %b %-d at %-I:%M %p") }}
          {% endif %}

      person_battery:
        friendly_name: "Battery"
        unit_of_measurement: '%'
        value_template: "{{states.device_tracker.life360_person.attributes.battery }}"
        icon_template: >-
          mdi:battery{% if is_state_attr('device_tracker.life360_person', 'battery_charging', true) %}-charging{% else %}{% endif %}{% if 0<(state_attr('device_tracker.life360_person', 'battery') | float / 10 ) | round(0) * 10 < 100%}-{{ (state_attr('device_tracker.life360_person', 'battery') | float / 10 ) | round(0) * 10 }}{% else %}{% if (state_attr('device_tracker.life360_person', 'battery') | float / 10 ) | round(0) * 10 == 0%}-outline{%else%}{% if is_state_attr('device_tracker.life360_person', 'battery_charging', true) %}-100{% endif %}{% endif %}{% endif %}

      person_wifi:
        friendly_name: "WiFi"
        value_template: >-
          {% if is_state_attr('device_tracker.life360_person', 'wifi_on', true) %}
            on
          {% else %}
            off
          {% endif %}
        icon_template: >-
          {% if is_state_attr('device_tracker.life360_person', 'wifi_on', true) %}
            mdi:wifi
          {% else %}
            mdi:wifi-off
          {% endif %}

      person_height:
        value_template: >-
          {% if is_state('binary_sensor.person_moving', 'on') %}
            70px
          {% else %}
            40px
          {% endif %}

Then the frontend code:

cards:
  - card:
      cards:
        - elements:
            - entity: '${''device_tracker.life360_'' + vars[0]}'
              image: >-
                "${states['sensor.' + vars[0]
                +'_status'].attributes['entity_picture']}"
              style:
                left: 50%
                top: 50%
                width: 100%
              type: image
            - entity: '${''sensor.'' + vars[0] +''_battery''}'
              style:
                '--paper-item-icon-color': >-
                  ${'hsl(' + (states['sensor.' + vars[0] +'_battery'].state*1.1
                  )*((states['sensor.' + vars[0] +'_battery'].state/100)) +
                  ',90%,40%)'}
                left: 4.5%
                top: 3.5%
                transform: 'scale(1.2,1.2)'
              type: state-icon
            - entity: '${''sensor.'' + vars[0] +''_wifi''}'
              style:
                '--paper-item-icon-color': '#2b9af9'
                left: 80.5%
                top: 3.5%
                transform: 'scale(1.2,1.2)'
              type: state-icon
          image: '${''/local/images/'' + vars[0] +''/home.png''}'
          type: 'custom:hui-picture-elements-card'
        - color_type: icon
          entity: '${''sensor.'' + vars[0] +''_status''}'
          show_icon: false
          show_name: false
          show_state: true
          tap_action:
            action: url
            url: '${states[''sensor.'' + vars[0]].attributes[''map_link'']}'
          styles:
            card:
              - height: '${states[''sensor.'' + vars[0] +''_height''].state}'
            state:
              - padding-top: '${vars[2]}'
              - padding-left: 14px
              - padding-right: 14px
              - white-space: '${vars[1]}'
              - text-overflow: '${vars[1]}'
              - word-break: break-word
          type: 'custom:button-card'
        - card:
            color_type: icon
            entity: '${''sensor.'' + vars[0] +''_at_loc_since''}'
            show_icon: false
            show_name: false
            show_state: true
            tap_action:
              action: url
              url: '${states[''sensor.'' + vars[0]].attributes[''map_link'']}'
            styles:
              card:
                - height: 30px
              state:
                - padding-bottom: 14px
                - font-size: 12px
            type: 'custom:button-card'
          conditions:
            - entity: '${''binary_sensor.'' + vars[0] + ''_moving''}'
              state: 'off'
          type: conditional
      type: 'custom:vertical-stack-in-card'
    type: 'custom:config-template-card'
    variables:
      - '''person1'''
      - >-
        {if (states['sensor.' + vars[0] +'_height'].state ===
        '70px')'unset';else 'nowrap'}
      - >-
        {if (states['sensor.' + vars[0] +'_height'].state === '70px')'4px';else
        '14px'}
  - card:
      cards:
        - elements:
            - entity: '${''device_tracker.life360_'' + vars[0]}'
              image: >-
                "${states['sensor.' + vars[0]
                +'_status'].attributes['entity_picture']}"
              style:
                left: 50%
                top: 50%
                width: 100%
              type: image
            - entity: '${''sensor.'' + vars[0] +''_battery''}'
              style:
                '--paper-item-icon-color': >-
                  ${'hsl(' + (states['sensor.' + vars[0] +'_battery'].state*1.1
                  )*((states['sensor.' + vars[0] +'_battery'].state/100)) +
                  ',90%,40%)'}
                left: 4.5%
                top: 3.5%
                transform: 'scale(1.2,1.2)'
              type: state-icon
            - entity: '${''sensor.'' + vars[0] +''_wifi''}'
              style:
                '--paper-item-icon-color': '#2b9af9'
                left: 80.5%
                top: 3.5%
                transform: 'scale(1.2,1.2)'
              type: state-icon
          image: '${''/local/images/'' + vars[0] +''/home.png''}'
          type: 'custom:hui-picture-elements-card'
        - color_type: icon
          entity: '${''sensor.'' + vars[0] +''_status''}'
          show_icon: false
          show_name: false
          show_state: true
          tap_action:
            action: url
            url: '${states[''sensor.'' + vars[0]].attributes[''map_link'']}'
          styles:
            card:
              - height: '${states[''sensor.'' + vars[0] +''_height''].state}'
            state:
              - padding-top: '${vars[2]}'
              - padding-left: 14px
              - padding-right: 14px
              - white-space: '${vars[1]}'
              - text-overflow: '${vars[1]}'
              - word-break: break-word
          type: 'custom:button-card'
        - card:
            color_type: icon
            entity: '${''sensor.'' + vars[0] +''_at_loc_since''}'
            show_icon: false
            show_name: false
            show_state: true
            tap_action:
              action: url
              url: '${states[''sensor.'' + vars[0]].attributes[''map_link'']}'
            styles:
              card:
                - height: 30px
              state:
                - padding-bottom: 14px
                - font-size: 12px
            type: 'custom:button-card'
          conditions:
            - entity: '${''binary_sensor.'' + vars[0] + ''_moving''}'
              state: 'off'
          type: conditional
      type: 'custom:vertical-stack-in-card'
    type: 'custom:config-template-card'
    variables:
      - '''person2'''
      - >-
        {if (states['sensor.' + vars[0] +'_height'].state ===
        '70px')'unset';else 'nowrap'}
      - >-
        {if (states['sensor.' + vars[0] +'_height'].state === '70px')'4px';else
        '14px'}
type: horizontal-stack

Hopefully you can follow all of that. Essentially it’s a horizontal stack with two configurable vertical-stack-in cards where if you’re life360 name and sensors names are all the same the only thing you need to do is drop in your name in the variables: area.

I know there’s probably some cool ways to clean this up or do it better and am open to suggestions. If you have any additional questions feel free to ask.

12 Likes

thanks!
I use life360 and comparable template sensors where I only have to change the name :wink: So understand what you’re saying.

Will study this and thank you again!

A quick one for starters:
I tried using picture-entity before with a sensor that has an image .png for state in the image field, but that doesnt work unfortunately.

How then is this possible:

 - elements:
            - entity: '${''device_tracker.life360_'' + vars[0]}'
              image: >-
                "${states['sensor.' + vars[0]
                +'_status'].attributes['entity_picture']}"
              style:
                left: 50%
                top: 50%
                width: 100%
              type: image

using a template in the image field?

trying it like this:

  - type: 'custom:vertical-stack-in-card'
    cards:
      - type: 'custom:hui-picture-elements-card'
        image: /local/various/presence_frame.png
        elements:

          - type: image
            entity: '${"device_tracker.life360_name"}'
            image: >-
              ${states['sensor.name_picture].state}
            style:
              left: 50%
              top: 50%
              width: 100%

but it cant find the image.

states[‘sensor.name_picture’].state is the image-file including path so referencing that should work. I suspect the syntax is incorrect, so would truly appreciate some assistance :wink:

got it to this, showing the correct image, and frame, though not fitting at all. Still there’s progress :slight_smile:

  - type: 'custom:config-template-card'
    variables:
      - states['sensor.name_picture'].state
    entities:
      - device_tracker.life360_name
    card:
      type: 'custom:hui-picture-elements-card'
      image: /local/various/presence_frame.png
      elements:
        - type: image
          image: "${vars[0]}"
          style:
            left: 50%
            top: 50%
            width: 50%

and even this:

  - type: 'custom:config-template-card'
    variables:
      - "'name'"
    entities:
      - device_tracker.life360_name
    card:
      type: 'custom:hui-picture-elements-card'
      image: /local/various/presence_frame.png
      elements:
        - type: image
          image: >-
            ${states['sensor.' + vars[0] + '_picture'].state}
          style:
            left: 50%
            top: 50%
            width: 100%

took a while to find the correct (and rather unfamiliar) syntax intricacies of the template card …
normally a multiline notation dispenses with the outer quotes, but that doesnt work here, without using the white space cleaner >- and the double quoting of the variable string was new to me (btw you use triple single quotes, where using double quotes outside of inner single quotes is more default)

"'person1'"

since I believed the picture frame was an overlay, I now see t my surprise we have to fit the image exactly in to the center circle? That obviously requires more restraints to the images than I hoped for.

Could you please share the frame image and the size/resolution of the picture images needed for this setup?

thanks!

1 Like

I think it is probably the Bitmoji app.

Sorry, just came back to this.

Here’s the frame with the transparent center. With my images I have them saved as png because I originally started that way, but there’s no transparency to them any more. However, I’m thinking you could first place the updating image and then over top of that image place the transparent frame (just make sure the frame is connected to the the same entity as the picture). This would give you the look your shooting for. Oh, and I’m using 500x500 pixel images with mine.

frame

Full control of the heating and radiator control, this was made family friendly. Top section was used using the button card and the lower section was with the picture elements card.

16 Likes

That’s beautiful, could you share your config please ?

1 Like

Michael love the setup, guess you are using BitEmoji for pics? or did you get those made somewhere?

Yep, bitmoji for the pics of my wife and I, Chief Architect for the home floorplan, and then just cleaning them all up with Photoshop.

1 Like

Hi! How did you make this picture?
ha_frame

I started with the photoshop doc provided by mcfrojd, removed the lower two circles, and then changed up the color to match my main theme.

Could you share how you got the entities to be used with your card? I like that card. I assume each of the png is a change in status correct?

Michael, I am following how you did your settings but a few things. First you say you have to have “places” setup but not sure what you are saying there? I have life360 setup but places is not allowed now. Second I am assuming it is a different png file for each state (home, work, etc). So you took the transparent square and added each state picture behind it? And how does it put the statuses in the other circles? Thanks

Screenshot_Laptop_2019-11-01%2001_40_42
(not using the “distance to home” and “time to home” right now)

########################################################################################################################
# View - Home
########################################################################################################################
id: home
title: Home
cards:
###################################################################################################
  - type: vertical-stack
    cards:
      - type: horizontal-stack
        cards:
#-------------------------------------------------------------------------------
          - type: picture-elements
            image: /local/lovelace/home/ll_matte_home1.png
            elements:
              - style:
                  top: 50%
                  left: 50%
                  width: 100%
                type: image
                entity: input_select.matte_home_status
                state_image:
                  "Home": /local/lovelace/home/ll_matte_home1.png
                  "Just Arrived": /local/lovelace/home/ll_matte_home1.png
                  "Away": /local/lovelace/home/ll_matte_not_home1.png
                  "Just Left": /local/lovelace/home/ll_matte_not_home1.png
                  "Extended Away": /local/lovelace/home/ll_matte_not_home1.png
#---------------------------------------------------------------------------------------------------
# Charging icon
#---------------------------------------------------------------------------------------------------
              - style:
                  top: 50%
                  left: 50%
                  width: 100%
                type: image
                entity: input_boolean.matte_charging
                state_image:
                  "on": /local/lovelace/home/ll_status_charging.png
                  "off": /local/lovelace/home/ll_status_blank.png
#---------------------------------------------------------------------------------------------------
# Battery Icon (Top Left Circle)
#---------------------------------------------------------------------------------------------------
              - style:
                  color: white
                  top: 9%
                  left: 12%
                type: state-icon
                entity: sensor.life360_mathias_frojd_battery
#---------------------------------------------------------------------------------------------------
# Location (Footer Center)
#---------------------------------------------------------------------------------------------------
              - style:
                  color: white
                  top: 92%
                  left: 50%
                type: state-label
                entity: input_select.matte_home_status
#---------------------------------------------------------------------------------------------------
# Battery Label (Top Right Circle)
#---------------------------------------------------------------------------------------------------
              - style:
                  color: white
                  top: 10%
                  left: 89%
                type: state-label
                entity: sensor.life360_mathias_frojd_battery
#---------------------------------------------------------------------------------------------------
# Distance to home (Bottom Right Circle)
#---------------------------------------------------------------------------------------------------
              # - style:
              #     color: white
              #     top: 73%
              #     left: 88%
              #   type: state-label
              #   entity: sensor.waze_matte_distance
#---------------------------------------------------------------------------------------------------
# Time to home (Botton Left Circle)
#---------------------------------------------------------------------------------------------------
              # - style:
              #     color: white
              #     top: 73%
              #     left: 12%
              #   type: state-label
              #   entity: sensor.waze_matte_time
####################################################################################################
6 Likes

Do you have the " ll_status_blank.png" posted somewhere? And do you have to make a PNG for each state, like home, away, etc for each person? I setup all the sensors and stuff to get the results. I am new to parts of HA can you share your “input_select” and “input_boolean” configs?

ll_status_blank.png


Image above. (blank image)
I use 2 images for the states.

Home image


Away image.

And the image for battery charging.

Ok I see now how you are doing it. Each PNG is a state of the user… Roger that, thanks

making progress, but still struggling with the main picture position:

downloaded the bitmoji (which isn’t too straightforward for someone not using snapchat…) but it might not be the correct format?

38

2 Likes

No it’s not. How did you do it? I ended up taking a screen capture which wasn’t ideal.