Lock front-end change requested

At the moment, my mqtt lock shows up as a slider control:

I find this visualisation a little confusing (I get the switch on, means its locked, but I don’t like how it shares the same template as a switch), was wondering if there had been any thought to change this to something that included a locked and unlocked padlock icon.

Maybe like so:

1 Like

Looks like a bug in the mqtt lock, wink locks show a lock/unlocked icon.

Sorry for the poor color, have flux on my phone.

1 Like

As mentioned, standard lock device integrations via ZWave etc will set the icon on the left to a locked or unlocked state. You can accomplish the same thing with an MQTT device using icon_template. If you can post the relevant parts from your configuration.yaml maybe we can put something together that’ll work for you.

edit: after further research it looks like the lock component doesn’t appear to support icon_template. No idea why it’s not switching the icon for you unfortunately.

1 Like

Hi Luma,

I just checked and the icon to the left is switching, its just so subtle that I never even noticed. I always thought those icons where just static.

I would prefer a more obvious lock/unlock icons associated with the slider itself.

Perhaps Custom UI can help you here so you can customize the card to suit your needs :slight_smile:

1 Like

I’ll look into this, thanks @syphernl. This thread was more to understand whether a change to the default template could be beneficial to everyone.

Looking at the screenshot by @w1ll1am23 above, I can see that the power card doesn’t use the switch widget. I feel like this is more like a switch that a door lock.

Adding 2 more locks - looks ugly.
If it is hard to read the state from default visual - it’s quite easy to add a template sensor beneath which will state in text “locked” “unlocked” or show any icon necessary

Fair enough.

I’ve implemented Custom UI and the approach described here with a custom state-card-custom_lock.html file:

<dom-module id="state-card-custom_lock">
  <template>
    <style is="custom-style" include="iron-flex iron-flex-alignment"></style>
    <style>
      :host {
        line-height: 1.5;
      }
      paper-button {
        min-width: 30px;
        height: 30px;
        margin: 5px 0px;
        padding: 5px 0px;
        font-size: 12px;
      }
      .info {
        font-family: var(--paper-font-body1_-_font-family); -webkit-font-smoothing: var(--paper-font-body1_-_-webkit-font-smoothing); font-size: var(--paper-font-body1_-_font-size); font-weight: var(--paper-font-body1_-_font-weight); line-height: var(--paper-font-body1_-_line-height);min-width:10px;white-space:nowrap;float:left
      }
      .info {
        margin-left:16px
      }
      .name {
        white-space: var(--paper-font-common-nowrap_-_white-space); overflow: var(--paper-font-common-nowrap_-_overflow); text-overflow: var(--paper-font-common-nowrap_-_text-overflow);color:var(--primary-text-color);line-height:40px
      }
      .name[in-dialog],:host([secondary-line]) .name {
        line-height:20px
      }
      .time-ago,::content> * {
        white-space: var(--paper-font-common-nowrap_-_white-space); overflow: var(--paper-font-common-nowrap_-_overflow); text-overflow: var(--paper-font-common-nowrap_-_text-overflow);color:var(--secondary-text-color);
      }
      .badge {
        position:relative;display:inline-block;width:40px;color:var(--status-color);border-radius:50%;height:40px;text-align:center;background-size:cover;line-height:40px
      }
    </style>
<div class='horizontal justified layout'>
    <div class='horizontal start-justified layout'>
      <div class="badge">
        <state-badge class="badge" state-obj="[[stateObj]]"></state-badge>
      </div>
      <div class="info">
        <div class="name" in-dialog>[[friendlyName]]</div>
        <div class="time-ago">
          <ha-relative-time datetime='[[stateObj.last_changed]]'></ha-relative-time>
        </div>
      </div>
    </div>
  <paper-button-group>
        <paper-button
        style="width:85px; background-color:#FFFFFF; color: #44739e; border: 1px solid #44739e;"
        on-tap='handleLockedTap'
        hidden$='[[!lockedButtonVisible]]'>Locked</paper-button>
      <paper-button
        style="width:85px; background-color:#FFFFFF; color: #F44336; border: 1px solid #F44336;"
        on-tap='handleUnlockedTap'
        hidden$='[[!unlockedButtonVisible]]'>Unlocked</paper-button>
  </paper-button-group>
</div>
</template>
</dom-module>
<script>
        Polymer({
          is: 'state-card-custom_lock',
          properties: {
            hass: {
              type: Object,
            },
            stateObj: {
              type: Object,
              observer: 'stateObjChanged',
            },
            lockedButtonVisible: {
              type: Boolean,
              value: false,
            },
            unlockedButtonVisible: {
              type: Boolean,
              value: false,
            },
            friendlyName: {
              type: String,
              value: 'unknown',
            },
          },
          stateObjChanged: function (newVal) {
            if (newVal) {
              if (newVal.state == 'locked') {
                this.lockedButtonVisible = true;
                this.unlockedButtonVisible = false;
                this.friendlyName = this.stateObj.attributes.friendly_name;
                this.updateStyles({'--status-color': '#44739e'});
              } else if (newVal.state == 'unlocked') {
                this.lockedButtonVisible = false;
                this.unlockedButtonVisible = true;
                this.friendlyName = this.stateObj.attributes.friendly_name;
                this.timeAgo = this.stateObj.last_changed;
                this.updateStyles({'--status-color': '#F44336'});
              }            
            }
          },
          handleLockedTap: function (ev) {
            var serviceData = {entity_id: this.stateObj.entity_id}
            this.hass.callService('lock', 'unlock', serviceData);
            this.stopProp(ev);
          },
          handleUnlockedTap: function (ev) {
            var serviceData = {entity_id: this.stateObj.entity_id}
            this.hass.callService('lock', 'lock', serviceData);
            this.stopProp(ev);
          },
          stopProp(ev) {
            ev.stopPropagation();
          },
});
</script>

For an end result:

You could modify this file to whatever color/text/etc suits your preferences.

6 Likes

This is awesome, way more obvious than the current rendering