Slide cover entity row

Hi all,

I’ve create a slider/cover entity row based on the slider-entity-row found here My Lovelace Plugins

class SliderEntityCover extends Polymer.Element {
  static get template() {
    let slider = Polymer.html`
      <paper-slider
        min="[[min]]"
        max="[[max]]"
        value="{{value}}"
        step="[[step]]"
        pin
        on-change="selectedValue"
        ignore-bar-touch
        on-click="stopPropagation">
      </paper-slider>
      `
    return Polymer.html`
    <style>
      hui-generic-entity-row {
        margin: var(--ha-themed-slider-margin, initial);
      }
      .flex {
        display: flex;
        align-items: center;
      }
      .second-line paper-slider {
        width: 100%;
      }
	  .status {
	    padding-left: 10px
	  }
    </style>
    <hui-generic-entity-row
      config="[[_config]]"
      hass="[[_hass]]"
      >
      <div class="flex">
		<template is='dom-if' if='{{not(has_icon)}}'>
          <div on-click="open_cover">
			{{open_text}}
		  </div>
		</template>
		<template is='dom-if' if='{{has_icon}}'>
          <div on-click="open_cover">
  		    <ha-icon icon='{{open_icon}}' style="color: {{icon_color}}">
		    </ha-icon>
		  </div>
        </template>
        <template is='dom-if' if='{{has_slider}}'>
          ${slider}
        </template>
		<template is='dom-if' if='{{not(has_icon)}}'>
          <div on-click="close_cover">
			{{close_text}}
		  </div>
	    </template>
		<template is='dom-if' if='{{has_icon}}'>
		  <div on-click="close_cover">
		    <ha-icon icon='{{close_icon}}' style="color: {{icon_color}}">
		    </ha-icon>
		  </div>
        </template>
        <template is='dom-if' if='{{showValue}}'>
          <div class="status">
            [[statusString(stateObj)]]
          </div>
        </template>
      </div>
    </hui-generic-entity-row>
    `
  }

  static get properties() {
    return {
      _hass: Object,
      _config: Object,
      showValue: { type: Boolean, value: false },
      stateObj: { type: Object, value: null },
      min: { type: Number, value: 0 },
      max: { type: Number, value: 100 },
      step: { type: Number, value: 5 },
      attribute: { type: String, value: 'position' },
      attribute_back: { type: String, value: 'current_position' },
      value: Number,
	  open_icon: { type: String, value: 'mdi:arrow-up-bold' },
	  close_icon: { type: String, value: 'mdi:arrow-down-bold' },
	  open_text: { type: String, value: 'Open' },
	  close_text: { type: String, value: 'Close' },
	  has_icon: { type: Boolean, value: 'true' },
	  has_slider: { type: Boolean, value: 'true' },
	  icon_color: { type: String, value: 'rgb(0,0,0)' }
    };
  }

  setConfig(config)
  {
    this._config = config;
    this.showValue = config.show_value || true;
	this.open_icon = config.open_icon || "mdi:arrow-up-bold";
	this.close_icon = config.close_icon || "mdi:arrow-down-bold";
	this.open_text = config.open_text || "Open";
	this.close_text = config.close_text || "Close";
	this.has_icon = config.has_icon || true;
	this.has_slider = config.has_slider || true;
	this.icon_color = config.icon_color || "rgb(0,0,0)";
  }

  statusString(stateObj) {
    let l18n = this._hass.resources[this._hass.language];
    if(this.stateObj.attributes[this.attribute_back] === 0) {
      return l18n['state.cover.open'];
    } else if (this.stateObj.attributes[this.attribute_back] === 100) {
      return l18n['state.cover.closed'];
    } else {
      return Math.ceil(this.stateObj.attributes[this.attribute_back]).toString(10);
    }
  }

  set hass(hass) {
    this._hass = hass;
    this.stateObj = this._config.entity in hass.states ? hass.states[this._config.entity] : null;
    if(this.stateObj) {
      this.value = this.stateObj.attributes[this.attribute_back]
    }
  }

  selectedValue(ev) {
    const value = Math.ceil(parseInt(this.value, 10));
    const param = {entity_id: this.stateObj.entity_id };
    if(Number.isNaN(value)) return;
    if(value === 0) {
      this._hass.callService('cover', 'open_cover', param);
    } else if (value === 100 ) {
      this._hass.callService('cover', 'close_cover', param);
    } else {
      param[this.attribute] = value;
      this._hass.callService('cover', 'set_cover_position', param);
    }
  }
  
  open_cover(ev) {
    const param = {entity_id: this.stateObj.entity_id };
    this._hass.callService('cover', 'open_cover', param);
	this.stopPropagation(ev);
  }

  close_cover(ev) {
    const param = {entity_id: this.stateObj.entity_id };
    this._hass.callService('cover', 'close_cover', param);
	this.stopPropagation(ev);
  }
  
  stopPropagation(ev) {
    ev.stopPropagation();
  }
}

customElements.define('slider-entity-cover', SliderEntityCover);

I changed a bit the options (all optional)

showValue: Boolean default: true; to show to current value on the right side
open_icon: String default: "mdi:arrow-up-bold";
close_icon: String default: "mdi:arrow-down-bold";
open_text: String default: "Open";
close_text: String default: "Close";
has_icon: Boolean default: true; to show the text or the icon for Open/Close commands
has_slider:  default true; to display the slider
icon_color: String RGB  default "rgb(0,0,0)";

The only problem would be to reverse the zwave commands Open/close (at my place it works perfectly)

I don’t have a github account so if someone wants to take it and publish it, I hope it could help

Thanks
Oohcalme

3 Likes