Advertisement
Guest User

Untitled

a guest
Oct 21st, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.38 KB | None | 0 0
  1. class XiaomiVacuumCard extends Polymer.Element {
  2.  
  3. static get template() {
  4. return Polymer.html`
  5. <style>
  6. .background {
  7. background-repeat: no-repeat;
  8. background-position: center center;
  9. background-size: cover;
  10. }
  11. .title {
  12. font-size: 20px;
  13. padding: 16px 16px 0;
  14. text-align: center;
  15. white-space: nowrap;
  16. text-overflow: ellipsis;
  17. overflow: hidden;
  18. }
  19. .content {
  20. cursor: pointer;
  21. }
  22. .flex {
  23. display: flex;
  24. align-items: center;
  25. justify-content: space-evenly;
  26. }
  27. .button {
  28. cursor: pointer;
  29. padding: 16px;
  30. }
  31. .grid {
  32. display: grid;
  33. grid-template-columns: repeat(2, auto);
  34. }
  35. .grid-content {
  36. display: grid;
  37. align-content: space-between;
  38. grid-row-gap: 6px;
  39. }
  40. .grid-left {
  41. text-align: left;
  42. font-size: 110%;
  43. padding-left: 10px;
  44. border-left: 2px solid var(--primary-color);
  45. }
  46. .grid-right {
  47. text-align: right;
  48. padding-right: 10px;
  49. border-right: 2px solid var(--primary-color);
  50. }
  51. </style>
  52. <ha-card hass="[[_hass]]" config="[[_config]]" class="background" style="[[backgroundImage]]">
  53. <template is="dom-if" if="{{name}}">
  54. <div class="title" style="[[contentText]]">[[name]]</div>
  55. </template>
  56. <div class="content grid" style="[[contentStyle]]" on-click="moreInfo">
  57. <div class="grid-content grid-left">
  58. <div>[[_config.labels.status]]: [[stateObj.attributes.status]]</div>
  59. <div>[[_config.labels.battery]]: [[stateObj.attributes.battery_level]] %</div>
  60. <div>[[_config.labels.mode]]: [[stateObj.attributes.fan_speed]]</div>
  61. </div>
  62. <template is="dom-if" if="{{showDetails}}">
  63. <div class="grid-content grid-right" >
  64. <div>[[_config.labels.main_brush]]: [[stateObj.attributes.main_brush_left]] [[_config.labels.hours]]</div>
  65. <div>[[_config.labels.side_brush]]: [[stateObj.attributes.side_brush_left]] [[_config.labels.hours]]</div>
  66. <div>[[_config.labels.filter]]: [[stateObj.attributes.filter_left]] [[_config.labels.hours]]</div>
  67. <div>[[_config.labels.sensor]]: [[stateObj.attributes.sensor_dirty_left]] [[_config.labels.hours]]</div>
  68. </div>
  69. </template>
  70. </div>
  71. <template is="dom-if" if="{{showButtons}}">
  72. <div class="flex" style="[[contentText]]">
  73. <template is="dom-if" if="{{_config.buttons.start}}">
  74. <div class="button" on-tap="startVaccum">
  75. <ha-icon icon="mdi:play"></ha-icon>
  76. </div>
  77. </template>
  78. <template is="dom-if" if="{{_config.buttons.pause}}">
  79. <div class="button" on-tap="pauseVacuum">
  80. <ha-icon icon="mdi:pause"></ha-icon>
  81. </div>
  82. </template>
  83. <template is="dom-if" if="{{_config.buttons.stop}}">
  84. <div class="button" on-tap="stopVacuum">
  85. <ha-icon icon="mdi:stop"></ha-icon>
  86. </div>
  87. </template>
  88. <template is="dom-if" if="{{_config.buttons.spot}}">
  89. <div class="button" on-tap="cleanSpot">
  90. <ha-icon icon="mdi:broom"></ha-icon>
  91. </div>
  92. </template>
  93. <template is="dom-if" if="{{_config.buttons.locate}}">
  94. <div class="button" on-tap="locateVacuum">
  95. <ha-icon icon="mdi:map-marker"></ha-icon>
  96. </div>
  97. </template>
  98. <template is="dom-if" if="{{_config.buttons.return}}">
  99. <div class="button" on-tap="returnVacuum">
  100. <ha-icon icon="mdi:home-map-marker"></ha-icon>
  101. </div>
  102. </template>
  103. </div>
  104. </template>
  105. </ha-card>
  106. `;
  107. }
  108.  
  109. moreInfo() { this.fireEvent('hass-more-info'); }
  110. startVaccum() { this.callService(this._config.service.start); }
  111. pauseVacuum() { this.callService(this._config.service.pause); }
  112. stopVacuum() { this.callService(this._config.service.stop); }
  113. locateVacuum() { this.callService(this._config.service.locate); }
  114. returnVacuum() { this.callService(this._config.service.return); }
  115. cleanSpot() { this.callService(this._config.service.spot); }
  116.  
  117. callService(service) {
  118. this._hass.callService('vacuum', service, {entity_id: this._config.entity});
  119. }
  120.  
  121. fireEvent(type, options = {}) {
  122. const event = new Event(type, {
  123. bubbles: options.bubbles || true,
  124. cancelable: options.cancelable || true,
  125. composed: options.composed || true,
  126. });
  127. event.detail = {entityId: this._config.entity};
  128. this.shadowRoot.dispatchEvent(event);
  129. return event;
  130. }
  131.  
  132. getCardSize() {
  133. if (this.name && this.showButtons) return 5;
  134. if (this.name || this.showButtons) return 4;
  135. return 3;
  136. }
  137.  
  138. setConfig(config) {
  139. const labels = {
  140. status: 'Status',
  141. battery: 'Battery',
  142. mode: 'Mode',
  143. main_brush: 'Main Brush',
  144. side_brush: 'Side Brush',
  145. filter: 'Filter',
  146. sensor: 'Sensor',
  147. hours: 'h',
  148. };
  149.  
  150. const services = {
  151. start: 'start',
  152. pause: 'pause',
  153. stop: 'stop',
  154. locate: 'locate',
  155. return: 'return_to_base',
  156. spot: 'clean_spot',
  157. };
  158.  
  159. const buttons = {
  160. start: true,
  161. pause: true,
  162. stop: true,
  163. spot: false,
  164. locate: true,
  165. return: true,
  166. };
  167.  
  168. const vendors = {
  169. xiaomi: {
  170. image: '/local/img/vacuum.png',
  171. details: true,
  172. },
  173. ecovacs: {
  174. image: '/local/img/vacuum_ecovacs.png',
  175. details: false,
  176. buttons: {
  177. stop: false,
  178. spot: true,
  179. },
  180. service: {
  181. start: 'turn_on',
  182. pause: 'stop',
  183. stop: 'turn_off',
  184. },
  185. }
  186. };
  187.  
  188. if (!config.entity) throw new Error('Please define an entity.');
  189. if (config.entity.split('.')[0] !== 'vacuum') throw new Error('Please define a vacuum entity.');
  190. if (config.vendor && !config.vendor in vendors) throw new Error('Please define a valid vendor.');
  191.  
  192. const vendor = vendors[config.vendor] || vendors.xiaomi;
  193.  
  194. this.showDetails = vendor.details;
  195. this.showButtons = config.buttons !== false;
  196.  
  197. config.service = Object.assign({}, services, vendor.service);
  198. config.buttons = Object.assign({}, buttons, vendor.buttons, config.buttons);
  199. config.labels = Object.assign({}, labels, config.labels);
  200.  
  201. this.contentText = `color: ${config.image !== false ? 'white; text-shadow: 0 0 10px black;' : 'var(--primary-text-color)'}`;
  202. this.contentStyle = `padding: ${this.showButtons ? '16px 16px 4px' : '16px'}; ${this.contentText}`;
  203. this.backgroundImage = config.image !== false ? `background-image: url('${config.image || vendor.image}')` : '';
  204.  
  205. this._config = config;
  206. }
  207.  
  208. set hass(hass) {
  209. this._hass = hass;
  210.  
  211. if (hass && this._config) {
  212. this.stateObj = this._config.entity in hass.states ? hass.states[this._config.entity] : null;
  213.  
  214. if (this.stateObj) {
  215. this.name = this._config.name !== false && (this._config.name || this.stateObj.attributes.friendly_name);
  216. }
  217. }
  218. }
  219. }
  220.  
  221. customElements.define('xiaomi-vacuum-card', XiaomiVacuumCard);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement