├── README.md
├── configuration.yaml
├── configuration
├── themes.yaml
└── themes
│ ├── desktop
│ ├── desktop.yaml
│ ├── desktop_dark.yaml
│ └── desktop_light.yaml
│ └── mobile
│ ├── mobile.yaml
│ ├── mobile_dark.yaml
│ └── mobile_light.yaml
├── lovelace
├── button_card_templates
│ └── button_card_templates.yaml
├── resources
│ └── resources.yaml
└── views
│ ├── 01_home.yaml
│ ├── 02_temperature.yaml
│ ├── 03_consommation.yaml
│ └── 04_localisation.yaml
├── screenshots
├── anatomy.png
├── binary_sensor-1.png
├── binary_sensor-2.png
├── cards.png
├── chips.png
├── chips_icon.png
├── chips_localisation_present.png
├── chips_return.png
├── chips_temperature.png
├── cover_buttons.png
├── entity_graph.png
├── generic.png
├── light.png
├── light_slider.png
├── media.png
├── outlet.png
├── person.png
├── playstation.png
├── power_consumption.png
├── thermostat.png
├── title.png
└── water-heater.png
├── ui-lovelace.yaml
└── www
└── community
├── button-card
├── button-card.js
└── button-card.js.gz
├── ha-slider-card
├── slider-card.js
└── slider-card.js.gz
├── lovelace-auto-entities
├── auto-entities.js
├── auto-entities.js.gz
├── rollup.config.js
└── rollup.config.js.gz
├── lovelace-card-mod
├── card-mod.js
├── card-mod.js.gz
├── rollup.config.js
└── rollup.config.js.gz
├── lovelace-state-switch
├── state-switch.js
├── state-switch.js.gz
├── webpack.config.js
└── webpack.config.js.gz
├── mini-graph-card
├── mini-graph-card-bundle.js
└── mini-graph-card-bundle.js.gz
├── mini-media-player
├── mini-media-player-bundle.js
└── mini-media-player-bundle.js.gz
├── swipe-card
├── swipe-card.js
└── swipe-card.js.gz
└── vertical-stack-in-card
├── vertical-stack-in-card.js
└── vertical-stack-in-card.js.gz
/README.md:
--------------------------------------------------------------------------------
1 | # My Home Assistant
2 | At the top of each page we find the [chips](#chips) which allow me to quickly visualize the important information of the page.
3 | Then [title](#title) to separate the different sections
4 | and [cards](#cards) to represent and interact with devices, sensors, etc …
5 | I used the custom component [button-card](https://github.com/custom-cards/button-card) for all these cards.
6 | I drew a lot of inspiration from [7ahang’s work](https://www.behance.net/gallery/88433905/Redesign-Smart-Home) that I found on Behance.
7 |
8 |
9 |
10 |
11 |
12 |
13 | ## Table of Contents
14 | - [Installation](#installation)
15 | - [Design system](#design-system)
16 | - [Chips](#chips)
17 | - [Scene](#scene)
18 | - [Title](#title)
19 | - [Cards](#cards)
20 |
21 | # Installation
22 | 1. Add **button_card_templates** in **ui-lovelace.yaml** file.
23 | ```yaml
24 | button_card_templates: !include lovelace/button_card_templates/button_card_templates.yaml
25 | ```
26 | 4. Add **resources** in your **configuration.yaml** file. You will need at least [button-card](https://github.com/custom-cards/button-card)
27 | ```yaml
28 | lovelace:
29 | mode: yaml
30 | resources: !include lovelace/resources/resources.yaml
31 | ```
32 | 3. Add **themes** in your **configuration.yaml** file
33 | ```yaml
34 | frontend:
35 | themes: !include configuration/themes.yaml
36 | ```
37 |
38 |
39 | # Design system
40 | ## Colors
41 | I tried to set up a consistency between the colors used to represent the entities.
42 |
43 |
44 | Color
45 | Type
46 |
47 |
48 |
49 |
50 | 
51 |
52 |
53 |
54 |
55 | 💡 Light
56 |
57 | ⚡ Electricity
58 |
59 |
60 |
61 |
62 |
63 | 
64 |
65 |
66 |
67 |
68 |
69 | 🔥 Heating
70 |
71 |
72 |
73 |
74 |
75 |
76 | 
77 |
78 |
79 |
80 |
81 |
82 | ☑️ On/off devices
83 |
84 | 🏠 Home
85 |
86 |
87 |
88 |
89 |
90 |
91 | 
92 |
93 |
94 |
95 |
96 |
97 | 🌲 Exterior
98 |
99 |
100 |
101 |
102 |
103 |
104 | # Chips
105 | 
106 | Code template
107 |
108 |
109 | Template
110 |
111 |
112 |
113 |
114 | ```yaml
115 | chips:
116 | tap_action:
117 | action: more-info
118 | show_icon: false
119 | show_name: false
120 | show_state: false
121 | show_label: true
122 | size: 80%
123 | styles:
124 | img_cell:
125 | - width: 24px
126 | card:
127 | - border-radius: 18px
128 | - box-shadow: var(--box-shadow)
129 | - height: 36px
130 | - width: auto
131 | - padding-left: 6px
132 | - padding-right: 6px
133 | grid:
134 | - grid-template-areas: '"l"'
135 | label:
136 | - justify-self: center
137 | - padding: 0px 6px
138 | - font-weight: bold
139 | - font-size: 14px
140 | ```
141 |
142 |
143 |
144 |
145 |
146 |
147 | ## Temperature
148 | 
149 | Code
150 |
151 |
152 | Example
153 | Template
154 |
155 |
156 |
157 |
158 | ```yaml
159 | - template: chips_temperature
160 | type: 'custom:button-card'
161 | ```
162 |
163 |
164 |
165 |
166 | ```yaml
167 | chips_temperature:
168 | template: chips
169 | tap_action:
170 | action: navigate
171 | navigation_path: /lovelace/temperature
172 | label: |
173 | [[[
174 | var inter = states['sensor.fibaro_multisensor_salon_temperature'].state;
175 | var exter = states['sensor.fibaro_multisensor_balcon_temperature'].state;
176 | var icon = '☀️';
177 | if (states['sensor.dark_sky_icon'].state == 'clear-day'){
178 | var icon = '☀️';
179 | } else if(states['sensor.dark_sky_icon'].state == 'clear-night'){
180 | var icon = '🌙';
181 | } else if(states['sensor.dark_sky_icon'].state == 'rain'){
182 | var icon = '🌧️';
183 | } else if(states['sensor.dark_sky_icon'].state == 'snow'){
184 | var icon = '❄️';
185 | } else if(states['sensor.dark_sky_icon'].state == 'sleet'){
186 | var icon = '❄️';
187 | } else if(states['sensor.dark_sky_icon'].state == 'wind'){
188 | var icon = '🌫️';
189 | } else if(states['sensor.dark_sky_icon'].state == 'fog'){
190 | var icon = '🌫️';
191 | } else if(states['sensor.dark_sky_icon'].state == 'cloudy'){
192 | var icon = '☁️';
193 | } else if(states['sensor.dark_sky_icon'].state == 'partly-cloudy-day'){
194 | var icon = '⛅️';
195 | } else if(states['sensor.dark_sky_icon'].state == 'partly-cloudy-night'){
196 | var icon = '⛅';
197 | }
198 | return icon + ' ' + exter + '° / ' + inter + '°' ;
199 | ]]]
200 | ```
201 |
202 |
203 |
204 |
205 |
206 |
207 | ## Electric consumption
208 | 
209 | Code
210 |
211 |
212 | Example
213 | Template
214 |
215 |
216 |
217 |
218 | ```yaml
219 | - template: chips_power_consumption
220 | type: 'custom:button-card'
221 | ```
222 |
223 |
224 |
225 |
226 | ```yaml
227 | chips_power_consumption:
228 | template: chips
229 | tap_action:
230 | action: navigate
231 | navigation_path: /lovelace/consommation
232 | label: |
233 | [[[
234 | var price = states['sensor.atome_price_conso_today'].state;
235 | return '⚡ ' + price + '€' ;
236 | ]]]
237 | ```
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 | ## Presence counter
246 | 
247 | Code
248 |
249 |
250 | Example
251 | Template
252 |
253 |
254 |
255 |
256 | ```yaml
257 | - template: chips_localisation_present
258 | type: 'custom:button-card'
259 | ```
260 |
261 |
262 |
263 |
264 | ```yaml
265 | chips_localisation_present:
266 | tap_action:
267 | action: navigate
268 | navigation_path: /lovelace/localisation
269 | label: |
270 | [[[
271 | var personnes_presentes = states['sensor.people_count_present'].state;
272 | return '🏠 ' + personnes_presentes;
273 | ]]]
274 | template: chips
275 | ```
276 |
277 |
278 |
279 |
280 |
281 |
282 | ## Return button
283 | 
284 |
285 | Code
286 |
287 |
288 | Example
289 | Template
290 |
291 |
292 |
293 |
294 | ```yaml
295 | - template: chips_return
296 | type: 'custom:button-card
297 | ```
298 |
299 |
300 |
301 |
302 | ```yaml
303 | chips_return:
304 | template: chips
305 | show_icon: true
306 | icon: 'mdi:arrow-left'
307 | size: 80%
308 | styles:
309 | grid:
310 | - grid-template-areas: '"i"'
311 | tap_action:
312 | action: navigate
313 | navigation_path: /lovelace/home
314 | ```
315 |
316 |
317 |
318 |
319 |
320 |
321 | # Scene
322 | 
323 | Code
324 |
325 |
326 | Example
327 | Template
328 | Template Blue
329 |
330 |
331 |
332 |
333 | ```yaml
334 | - entity: sensor.present
335 | template: scene_blue
336 | variables:
337 | state: "Present"
338 | type: 'custom:button-card'
339 | ```
340 |
341 |
342 |
343 |
344 | ```yaml
345 | scene:
346 | size: 20px
347 | show_label: true
348 | label: |
349 | [[[ return (entity.attributes.value )]]]
350 | styles:
351 | card:
352 | - border-radius: var(--border-radius)
353 | - box-shadow: var(--box-shadow)
354 | - padding: 10px 0px 8px 0px
355 | grid:
356 | - grid-template-areas: '"i" "n" "l"'
357 | name:
358 | - margin-top: 10px
359 | - justify-self: center
360 | - font-weight: bold
361 | - font-size: 14px
362 | label:
363 | - justify-self: center
364 | - align-self: start
365 | - font-weight: bolder
366 | - font-size: 12px
367 | - filter: opacity(40%)
368 | icon:
369 | - color: 'rgba(var(--color-theme),0.2)'
370 | img_cell:
371 | - background-color: 'rgba(var(--color-theme),0.05)'
372 | - border-radius: 50%
373 | - place-self: center
374 | - width: 42px
375 | - height: 42px
376 | ```
377 |
378 |
379 |
380 |
381 | ```yaml
382 | scene_blue:
383 | variables:
384 | state: "default"
385 | template:
386 | - scene
387 | state:
388 | - operator: template
389 | value: >
390 | [[[
391 | return states['input_select.localisation_thomas'].state == variables.state
392 | ]]]
393 | styles:
394 | icon:
395 | - color: 'rgba(var(--color-blue),1)'
396 | img_cell:
397 | - background-color: 'rgba(var(--color-blue), 0.2)'
398 | card:
399 | - background-color: 'rgba(var(--color-background-blue), var(--opacity-bg))'
400 | name:
401 | - color: 'rgba(var(--color-blue-text),1)'
402 | label:
403 | - color: 'rgba(var(--color-blue-text),1)'
404 | ```
405 |
406 |
407 |
408 |
409 |
410 |
411 | # Title
412 | 
413 | Code
414 |
415 |
416 | Example
417 | Template
418 |
419 |
420 |
421 |
422 | ```yaml
423 | - template: title
424 | name: Title
425 | label: 'Subtitle'
426 | type: 'custom:button-card'
427 |
428 | ```
429 |
430 |
431 |
432 |
433 | ```yaml
434 | title:
435 | tap_action:
436 | action: none
437 | show_icon: false
438 | show_label: true
439 | show_name: true
440 | styles:
441 | card:
442 | - background-color: rgba(0,0,0,0)
443 | - box-shadow: none
444 | - height: auto
445 | - width: auto
446 | - margin-top: 12px
447 | - margin-left: 24px
448 | - margin-bottom: 0px
449 | grid:
450 | - grid-template-areas: '"n" "l"'
451 | - grid-template-columns: 1fr
452 | - grid-template-rows: min-content min-content
453 | name:
454 | - justify-self: start
455 | - font-weight: bold
456 | - font-size: '1.5rem'
457 | label:
458 | - justify-self: start
459 | - font-weight: bold
460 | - font-size: '1rem'
461 | - opacity: '0.4'
462 | ```
463 |
464 |
465 |
466 |
467 |
468 |
469 | # Cards
470 | 
471 |
472 | ### Anatomy
473 | 
474 | 1. **Dot** : Visible when the device is unavailable. Also used on the entity **person**
475 | 2. **Icon** : Icon that represents the device
476 | 3. **Primary line** : Main information
477 | 4. **Secondary line** : Secondary information
478 | 5. **Optionnal part** : Possibility to display buttons to launch actions related to the device. Or display a graph to view the history of a sensor
479 |
480 |
481 | ## Light
482 |
483 | 
484 | Code
485 |
486 |
487 | Example
488 | Template
489 |
490 |
491 |
492 |
493 | ```yaml
494 | - entity: light.example
495 | name: Lumière
496 | template:
497 | - icon_info_bg
498 | - light
499 | type: 'custom:button-card'
500 | ```
501 |
502 |
503 |
504 |
505 | ```yaml
506 | light:
507 | tap_action:
508 | action: toggle
509 | hold_action:
510 | action: more-info
511 | label: >-
512 | [[[ if (entity.state !='unavailable'){
513 | if (entity.state =='off'){
514 | var bri = Math.round(entity.attributes.brightness / 2.55);
515 | return 'Off';
516 | }else{
517 | var bri = Math.round(entity.attributes.brightness / 2.55);
518 | return (bri ? bri : '0') + '%';
519 | }
520 | }else{
521 | return "Indisponible";
522 | }
523 | ]]]
524 | template:
525 | - yellow
526 | ```
527 |
528 |
529 |
530 |
531 |
532 |
533 | ## Light slider
534 |
535 | 
536 | Code
537 |
538 |
539 | Example
540 | Template
541 |
542 |
543 |
544 |
545 | ```yaml
546 | - entity: light.exemple
547 | template:
548 | - light_slider
549 | variables:
550 | entity: "light.exemple"
551 | name: "Light"
552 | type: 'custom:button-card'
553 | ```
554 |
555 |
556 |
557 |
558 | ```yaml
559 | light_slider:
560 | variables:
561 | name: "Default name"
562 | show_icon: false
563 | show_name: false
564 | show_label: false
565 | styles:
566 | card:
567 | - border-radius: var(--border-radius)
568 | - box-shadow: var(--box-shadow)
569 | - padding: 12px
570 | grid:
571 | - grid-template-areas: '"item1" "item2"'
572 | - grid-template-columns: 1fr
573 | - grid-template-rows: min-content min-content
574 | - row-gap: 12px
575 | state:
576 | - operator: template
577 | value: >
578 | [[[
579 | return entity.state == 'on'
580 | ]]]
581 | styles:
582 | card:
583 | - background-color: 'rgba(var(--color-background-yellow),var(--opacity-bg))'
584 | custom_fields:
585 | item1:
586 | card:
587 | entity: '[[[ return variables.entity ]]]'
588 | name: '[[[ return variables.name ]]]'
589 | template:
590 | - icon_info
591 | - light
592 | type: 'custom:button-card'
593 | item2:
594 | card:
595 | type: 'custom:slider-card'
596 | entity: '[[[ return variables.entity ]]]'
597 | radius: 14px
598 | height: 42px
599 | mainSliderColor: rgba(var(--color-yellow),1)
600 | secondarySliderColor: rgba(var(--color-yellow),0.2)
601 | mainSliderColorOff: rgba(var(--color-theme),0.05)
602 | secondarySliderColorOff: rgba(var(--color-theme),0.05)
603 | thumbHorizontalPadding: '0px'
604 | thumbVerticalPadding: '0px'
605 | thumbWidth: 0px
606 | card_mod:
607 | style: |
608 | ha-card {
609 | border-radius: 14px;
610 | box-shadow: none;
611 | }
612 | ```
613 |
614 |
615 |
616 |
617 |
618 |
619 | ## Outlet
620 | 
621 | Code
622 |
623 |
624 | Example
625 | Template
626 |
627 |
628 |
629 |
630 | ```yaml
631 | - entity: switch.exemple
632 | name: Prise
633 | template:
634 | - icon_info_bg
635 | - outlet
636 | label: |-
637 | [[[ if (entity.state =='on')
638 | var etat = "On • " + states["sensor.exemple"].state + "W";
639 | else
640 | var etat = "Off";
641 | return etat ; ]]]
642 | type: 'custom:button-card'
643 | ```
644 |
645 |
646 |
647 |
648 | ```yaml
649 | outlet:
650 | tap_action:
651 | action: more-info
652 | label: |-
653 | [[[ if (entity.state =='on')
654 | var etat = "On";
655 | else
656 | var etat = "Off";
657 | return etat ; ]]]
658 | template:
659 | - yellow
660 | ```
661 |
662 |
663 |
664 |
665 |
666 |
667 | ## Binary sensor
668 |  
669 | Code
670 |
671 |
672 | Example
673 | Template
674 |
675 |
676 |
677 |
678 | ```yaml
679 | - entity: binary_sensor.example
680 | name: Mouvement
681 | icon: 'mdi:run'
682 | template:
683 | - icon_info_bg
684 | - binary_sensor
685 | type: 'custom:button-card'
686 | ```
687 |
688 |
689 |
690 |
691 | ```yaml
692 | binary_sensor:
693 | show_last_changed: true
694 | template:
695 | - blue
696 | ```
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 | ## Cover
705 | 
706 | Code
707 |
708 |
709 | Example
710 | Template
711 |
712 |
713 |
714 |
715 | ```yaml
716 | - template: cover_buttons
717 | variables:
718 | entity: "cover.example"
719 | name: "Volets"
720 | type: 'custom:button-card'
721 | ```
722 |
723 |
724 |
725 |
726 | ```yaml
727 | cover_buttons:
728 | variables:
729 | entity: "cover.fibaro_cover_balcon"
730 | name: "Default name"
731 | styles:
732 | card:
733 | - border-radius: var(--border-radius)
734 | - box-shadow: var(--box-shadow)
735 | - padding: 12px
736 | grid:
737 | - grid-template-areas: '"item1" "item2"'
738 | - grid-template-columns: 1fr
739 | - grid-template-rows: min-content min-content
740 | - row-gap: 12px
741 | custom_fields:
742 | item1:
743 | card:
744 | entity: '[[[ return variables.entity ]]]'
745 | name: '[[[ return variables.name ]]]'
746 | tap_action:
747 | action: more-info
748 | template:
749 | - icon_info
750 | - cover
751 | type: 'custom:button-card'
752 | item2:
753 | card:
754 | template: list_items
755 | type: 'custom:button-card'
756 | custom_fields:
757 | item1:
758 | card:
759 | icon: 'mdi:arrow-down'
760 | tap_action:
761 | action: call-service
762 | service: cover.close_cover
763 | service_data:
764 | entity_id: '[[[ return variables.entity ]]]'
765 | type: 'custom:button-card'
766 | template: widget_icon
767 | item2:
768 | card:
769 | icon: 'mdi:pause'
770 | tap_action:
771 | action: call-service
772 | service: cover.stop_cover
773 | service_data:
774 | entity_id: '[[[ return variables.entity ]]]'
775 | type: 'custom:button-card'
776 | template: widget_icon
777 | item3:
778 | card:
779 | icon: 'mdi:arrow-up'
780 | tap_action:
781 | action: call-service
782 | service: cover.open_cover
783 | service_data:
784 | entity_id: '[[[ return variables.entity ]]]'
785 | type: 'custom:button-card'
786 | template: widget_icon
787 | ```
788 |
789 |
790 |
791 |
792 |
793 |
794 | ## Thermostat
795 | 
796 | Code
797 |
798 |
799 | Example
800 | Template
801 |
802 |
803 |
804 |
805 | ```yaml
806 | - entity: climate.example
807 | template:
808 | - icon_info_bg
809 | - thermostat
810 | type: 'custom:button-card'
811 | ```
812 |
813 |
814 |
815 |
816 | ```yaml
817 | thermostat:
818 | hold_action:
819 | action: more-info
820 | entity: input_boolean.radiateur_arret_force
821 | label: >-
822 | [[[
823 | if (entity.state =='off'){
824 | return 'Off' ;
825 | }else{
826 | if (states['light.qubino'].state == 'on'){
827 | var etat = "Chauffe";
828 | }else{
829 | var etat = "Inactif";
830 | }
831 | return (entity.attributes.temperature ) + '°' + ' • ' + etat ;
832 | }
833 | ]]]
834 | state:
835 | - operator: template
836 | value: >
837 | [[[
838 | return states['light.qubino'].state == 'on'
839 | ]]]
840 | styles:
841 | icon:
842 | - color: 'rgba(var(--color-red),1)'
843 | img_cell:
844 | - background-color: 'rgba(var(--color-red),0.2)'
845 | card:
846 | - background-color: 'rgba(var(--color-background-red),var(--opacity-bg))'
847 | name:
848 | - color: 'rgba(var(--color-red-text),1)'
849 | label:
850 | - color: 'rgba(var(--color-red-text),1)'
851 | ```
852 |
853 |
854 |
855 |
856 |
857 |
858 | ## Water heater
859 | 
860 | Code
861 |
862 |
863 | Example
864 | Template
865 |
866 |
867 |
868 |
869 | ```yaml
870 | - entity: switch.example
871 | name: Chauffe eau
872 | template:
873 | - icon_info_bg
874 | - water_heater
875 | type: 'custom:button-card'
876 | ```
877 |
878 |
879 |
880 |
881 | ```yaml
882 | water_heater:
883 | icon: 'mdi:waves'
884 | tap_action:
885 | action: more-info
886 | hold_action:
887 | action: more-info
888 | label: >-
889 | [[[
890 | if (entity.state == 'off'){
891 | return 'Arrêt forcé';
892 | }else{
893 | if (states["sensor.shelly_prise_salon_conso"].state > 0){
894 | var etat = "Chauffe • " + states["sensor.shelly_prise_salon_conso"].state + "W";
895 | }else{
896 | var etat = "Inactif";
897 | }
898 | return etat ;
899 | }
900 | ]]]
901 | state:
902 | - operator: template
903 | value: >
904 | [[[
905 | return (states['sensor.shelly_prise_salon_conso'].state > 0)
906 | ]]]
907 | styles:
908 | icon:
909 | - color: 'rgba(var(--color-red),1)'
910 | img_cell:
911 | - background-color: 'rgba(var(--color-red),0.2)'
912 | card:
913 | - background-color: 'rgba(var(--color-background-red),var(--opacity-bg))'
914 | name:
915 | - color: 'rgba(var(--color-red-text),1)'
916 | label:
917 | - color: 'rgba(var(--color-red-text),1)'
918 | ```
919 |
920 |
921 |
922 |
923 |
924 |
925 | ## Media player
926 | 
927 | Code
928 |
929 |
930 | Example
931 | Template
932 |
933 |
934 |
935 |
936 | ```yaml
937 | - entity: media_player.example
938 | name: Enceintes
939 | template:
940 | - icon_info_bg
941 | - media
942 | type: 'custom:button-card'
943 | ```
944 |
945 |
946 |
947 |
948 | ```yaml
949 | media:
950 | label: >-
951 | [[[ if (entity.state =='off'){
952 | return "Off";
953 | }else{
954 | return entity.state;
955 | }
956 | ]]]
957 | icon: |
958 | [[[
959 | var application = entity.attributes.app_name;
960 | var icon = 'mdi:speaker';
961 | if (application == 'Oto music'){
962 | var icon = 'mdi:music-circle';
963 | } else if(application == 'Spotify'){
964 | var icon = 'mdi:spotify';
965 | } else if(application == 'Google Podcasts'){
966 | var icon = 'mdi:google-podcast';
967 | } else if(application == 'Plex'){
968 | var icon = 'mdi:plex';
969 | }
970 | return icon ;
971 | ]]]
972 | styles:
973 | label:
974 | - opacity: '0.6'
975 | icon:
976 | - color: 'rgba(var(--color-theme),0.2)'
977 | img_cell:
978 | - background-color: 'rgba(var(--color-theme),0.05)'
979 | card:
980 | - background-blend-mode: multiply
981 | - background: >
982 | [[[
983 | var image = entity.attributes.entity_picture_local;
984 | var bg = entity.attributes.entity_picture_local;
985 | if (image == null){
986 | var bg = '';
987 | } else{
988 | var bg = 'center / cover url(' + image + ') rgba(0, 0, 0, 0.15)';
989 | }
990 | return bg;
991 | ]]]
992 | state:
993 | - operator: template
994 | value: >
995 | [[[
996 | return entity.state !='off'
997 | ]]]
998 | name: >
999 | [[[
1000 | return entity.attributes.media_title;
1001 | ]]]
1002 | label: >
1003 | [[[
1004 | return entity.attributes.media_album_name;
1005 | ]]]
1006 | styles:
1007 | label:
1008 | - color: white
1009 | - filter: opacity(100%)
1010 | img_cell:
1011 | - background-color: 'rgba(var(--color-theme),0.0)'
1012 | icon:
1013 | - color: white
1014 | name:
1015 | - color: white
1016 | ```
1017 |
1018 |
1019 |
1020 |
1021 |
1022 |
1023 | ## Playstation
1024 | 
1025 | Code
1026 |
1027 |
1028 | Example
1029 | Template
1030 |
1031 |
1032 |
1033 |
1034 | ```yaml
1035 | - entity: media_player.example
1036 | template:
1037 | - icon_info_bg
1038 | - ps4
1039 | type: 'custom:button-card'
1040 | ```
1041 |
1042 |
1043 |
1044 |
1045 | ```yaml
1046 | ps4:
1047 | label: >-
1048 | [[[ if (entity.state =='unknown'){
1049 | return "Off";
1050 | }else if (entity.state =='standby'){
1051 | return "En veille";
1052 | }else{
1053 | return "On";
1054 | }
1055 | ]]]
1056 | styles:
1057 | icon:
1058 | - color: 'rgba(var(--color-theme),0.2)'
1059 | img_cell:
1060 | - background-color: 'rgba(var(--color-theme),0.05)'
1061 | state:
1062 | - value: 'idle'
1063 | styles:
1064 | icon:
1065 | - color: 'rgba(var(--color-blue),1)'
1066 | img_cell:
1067 | - background-color: 'rgba(var(--color-blue), 0.2)'
1068 | - value: 'standby'
1069 | styles:
1070 | icon:
1071 | - color: 'rgba(var(--color-theme),0.2)'
1072 | img_cell:
1073 | - background-color: 'rgba(var(--color-theme),0.05)'
1074 | - operator: template
1075 | value: >
1076 | [[[
1077 | return entity.state !='unknown'
1078 | ]]]
1079 | name: >
1080 | [[[
1081 | return entity.attributes.media_title;
1082 | ]]]
1083 | label: >
1084 | [[[
1085 | return entity.attributes.friendly_name;
1086 | ]]]
1087 | styles:
1088 | label:
1089 | - color: white
1090 | - filter: opacity(100%)
1091 | img_cell:
1092 | - background-color: 'none'
1093 | icon:
1094 | - color: white
1095 | name:
1096 | - color: white
1097 | card:
1098 | - background-blend-mode: multiply
1099 | - background: >
1100 | [[[
1101 | var image = entity.attributes.entity_picture;
1102 | return 'center / cover url(' + image + ') rgba(0, 0, 0, 0.15)';
1103 | ]]]
1104 | ```
1105 |
1106 |
1107 |
1108 |
1109 |
1110 |
1111 | ## Person
1112 | 
1113 | Information
1114 |
1115 | **Dot** :
1116 | - At home : Blue
1117 | - Away : Green
1118 |
1119 |
1120 | **Dot icon** :
1121 | - At home : Home
1122 | - Away : Walking man
1123 | - Sleeping : Moon
1124 |
1125 | **Comment** : The sleep state takes over the At home or Away state to display the moon icon
1126 |
1127 | Code
1128 |
1129 |
1130 | Example
1131 | Template
1132 |
1133 |
1134 |
1135 |
1136 | ```yaml
1137 | - entity: input_select.localisation_thomas
1138 | variables:
1139 | personne: "thomas"
1140 | template:
1141 | - icon_info_bg
1142 | - personne-thomas
1143 | name: Thomas
1144 | type: 'custom:button-card'
1145 | ```
1146 |
1147 |
1148 |
1149 |
1150 | ```yaml
1151 | person:
1152 | tap_action:
1153 | action: more-info
1154 | show_label: true
1155 | label: >
1156 | [[[return entity.state]]]
1157 | styles:
1158 | icon:
1159 | - color: 'rgba(var(--color-theme),0.9)'
1160 | custom_fields:
1161 | notification:
1162 | - border-radius: 50%
1163 | - position: absolute
1164 | - left: 38px
1165 | - top: 8px
1166 | - height: 16px
1167 | - width: 16px
1168 | - border: 2px solid var(--card-background-color)
1169 | - font-size: 12px
1170 | - line-height: 14px
1171 |
1172 | ####################################################
1173 |
1174 | person-thomas:
1175 | variables:
1176 | person: "thomas"
1177 | template: person
1178 | hold_action:
1179 | action: more-info
1180 | entity: input_boolean.thomas_nuit
1181 | styles:
1182 | custom_fields:
1183 | notification:
1184 | - background-color: >
1185 | [[[
1186 | if (states['input_select.localisation_thomas'].state == 'Present'){
1187 | return "rgba(var(--color-blue),1)";
1188 | }else{
1189 | return "rgba(var(--color-green),1)";
1190 | }
1191 | ]]]
1192 | custom_fields:
1193 | notification: >
1194 | [[[
1195 | if (states['input_boolean.thomas_nuit'].state == 'on'){
1196 | return ` `
1197 | }else{
1198 | if (states['input_select.localisation_thomas'].state == 'Present'){
1199 | return ` `
1200 | }else{
1201 | return ` `
1202 | }
1203 | }
1204 | ]]]
1205 | ```
1206 |
1207 |
1208 |
1209 |
1210 |
1211 |
1212 | ## Generic
1213 |
1214 | 
1215 | Code
1216 |
1217 |
1218 | Example
1219 | Template
1220 |
1221 |
1222 |
1223 |
1224 | ```yaml
1225 | - entity: sensor.example
1226 | template:
1227 | - icon_info_bg
1228 | - generic
1229 | type: 'custom:button-card'
1230 | ```
1231 |
1232 |
1233 |
1234 |
1235 | ```yaml
1236 | generic:
1237 | label: >
1238 | [[[return entity.state + " " + entity.attributes.unit_of_measurement]]]
1239 | styles:
1240 | icon:
1241 | - color: 'rgba(var(--color-theme),0.9)'
1242 | grid:
1243 | - grid-template-areas: '"i l" "i n"'
1244 | - grid-template-columns: min-content auto
1245 | - grid-template-rows: min-content min-content
1246 | label:
1247 | - align-self: end
1248 | - justify-self: start
1249 | - font-weight: bold
1250 | - font-size: 14px
1251 | - margin-left: 12px
1252 | - filter: opacity(100%)
1253 | name:
1254 | - justify-self: start
1255 | - align-self: start
1256 | - font-weight: bolder
1257 | - font-size: 12px
1258 | - filter: opacity(40%)
1259 | - margin-left: 12px
1260 | ```
1261 |
1262 |
1263 |
1264 |
1265 |
1266 |
1267 | ## Generic + graph
1268 |
1269 | 
1270 | Code
1271 |
1272 |
1273 | Example
1274 | Template
1275 |
1276 |
1277 |
1278 |
1279 | ```yaml
1280 | - type: 'custom:button-card'
1281 | template: graph
1282 | variables:
1283 | entity: "sensor.exemple"
1284 | color: "var(--google-blue)"
1285 | name: "Température"
1286 | ```
1287 |
1288 |
1289 |
1290 |
1291 | ```yaml
1292 | graph:
1293 | variables:
1294 | entity: "sensor.xiaomi_multisensor_salon_humidite"
1295 | color: "var(--info-color)"
1296 | name: "Default name"
1297 | styles:
1298 | card:
1299 | - border-radius: var(--border-radius)
1300 | - box-shadow: var(--box-shadow)
1301 | - padding: 0px
1302 | grid:
1303 | - grid-template-areas: '"item1" "item2"'
1304 | - grid-template-columns: 1fr
1305 | - grid-template-rows: min-content min-content
1306 | custom_fields:
1307 | item1:
1308 | card:
1309 | entity: '[[[ return variables.entity ]]]'
1310 | name: '[[[ return variables.name ]]]'
1311 | template:
1312 | - icon_info
1313 | - generic
1314 | styles:
1315 | card:
1316 | - padding: 12px
1317 | type: 'custom:button-card'
1318 | item2:
1319 | card:
1320 | type: 'custom:mini-graph-card'
1321 | entities:
1322 | - entity: '[[[ return variables.entity ]]]'
1323 | line_color: '[[[ return variables.color ]]]'
1324 | show:
1325 | name: false
1326 | icon: false
1327 | legend: false
1328 | state: false
1329 | style: |
1330 | ha-card {
1331 | box-shadow: none;
1332 | border-radius: var(--border-radius);
1333 | }
1334 | ```
1335 |
1336 |
1337 |
1338 |
1339 |
1340 |
--------------------------------------------------------------------------------
/configuration.yaml:
--------------------------------------------------------------------------------
1 | lovelace:
2 | mode: yaml
3 | resources: !include lovelace/resources/resources.yaml
4 |
5 | frontend:
6 | themes: !include configuration/themes.yaml
7 |
8 |
9 |
--------------------------------------------------------------------------------
/configuration/themes.yaml:
--------------------------------------------------------------------------------
1 | desktop:
2 | !include themes/desktop/desktop.yaml
3 | mobile:
4 | !include themes/mobile/mobile.yaml
--------------------------------------------------------------------------------
/configuration/themes/desktop/desktop.yaml:
--------------------------------------------------------------------------------
1 | # Journal
2 | state-icon-color: 'rgb(var(--color-theme))'
3 | border-radius: '20px'
4 | error-color: 'var(--google-red)'
5 | warning-color: 'var(--google-yellow)'
6 | success-color: 'var(--google-green)'
7 | info-color: 'var(--google-blue)'
8 | divider-color: 'rgba(var(--color-theme),.12)'
9 | accent-color: 'var(--google-yellow)'
10 | modes:
11 | light:
12 | !include desktop_light.yaml
13 | dark:
14 | !include desktop_dark.yaml
--------------------------------------------------------------------------------
/configuration/themes/desktop/desktop_dark.yaml:
--------------------------------------------------------------------------------
1 | ####################################################
2 | # #
3 | # DARK #
4 | # #
5 | ####################################################
6 | #text
7 | primary-text-color: '#DDDDDD'
8 |
9 | #main interface colors
10 | primary-color: '#89B3F8'
11 | google-red : '#F18B82'
12 | google-green : '#80C994'
13 | google-yellow : '#FCD663'
14 | google-blue : '#89B3F8'
15 | google-violet : '#BB86FC'
16 | google-grey: '#BBBBBB'
17 | color-red: 241, 139, 130
18 | color-green: 128, 201, 148
19 | color-yellow: 252, 214, 99
20 | color-blue : 137, 179, 248
21 | color-theme : 221,221,221
22 | color-purple : 102, 31, 255
23 | color-grey : 187, 187, 187
24 | color-pink : 233, 30, 99
25 | color-background-yellow : 'var(--color-yellow)'
26 | color-background-blue : 'var(--color-blue)'
27 | color-background-green : 'var(--color-green)'
28 | color-background-red : 'var(--color-red)'
29 | color-yellow-text: 'var(--color-yellow)'
30 | color-blue-text: 'var(--color-blue)'
31 | color-green-text: 'var(--color-green)'
32 | color-red-text: 'var(--color-red)'
33 | opacity-bg: '0.1'
34 |
35 | #floating button text color
36 | mdc-theme-on-secondary: 'var(--card-background-color)'
37 |
38 | #background and sidebar
39 | card-background-color: '#1D1D1D'
40 | primary-background-color: '#121212'
41 | secondary-background-color: '#121212'
42 |
43 | #header
44 | app-header-text-color: 'var(--primary-text-color)'
45 | app-header-background-color: 'var(--primary-background-color)'
46 | paper-tabs-selection-bar-color: 'var(--primary-text-color)'
47 |
48 | #Sidebar
49 | sidebar-selected-text-color: 'rgb(var(--color-blue))'
50 | sidebar-selected-icon-color: 'rgb(var(--color-blue))'
51 |
52 | #Slider
53 | slider-color: 'rgb(var(--color-blue))'
54 | slider-bar-color: 'rgba(var(--color-blue),0.38)'
55 |
56 | # card
57 | box-shadow: 'none'
58 |
59 | #media player
60 | mini-media-player-accent-color: 'var(--google-blue)'
61 |
62 | # Journal
63 | state-icon-color: 'rgb(var(--color-theme))'
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/configuration/themes/desktop/desktop_light.yaml:
--------------------------------------------------------------------------------
1 | ####################################################
2 | # #
3 | # LIGHT #
4 | # #
5 | ####################################################
6 | #text
7 | primary-text-color: '#212121'
8 |
9 | #main interface colors
10 | primary-color: '#434343'
11 | google-red : '#F54436'
12 | google-green : '#01C852'
13 | google-yellow : '#FF9101'
14 | google-blue : '#3D5AFE'
15 | google-violet : '#661FFF'
16 | google-grey: '#BBBBBB'
17 | color-red : 245, 68, 54
18 | color-green : 1, 200, 82
19 | color-yellow : 255, 145, 1
20 | color-blue : 61, 90, 254
21 | color-purple : 102, 31, 255
22 | color-grey : 187, 187, 187
23 | color-pink : 233, 30, 99
24 | color-theme : 51,51,51
25 | color-background-yellow : 250, 250, 250
26 | color-background-blue : 250, 250, 250
27 | color-background-green : 250, 250, 250
28 | color-background-red : 250, 250, 250
29 |
30 | color-yellow-text: 'var(--primary-text-color)'
31 | color-blue-text: 'var(--primary-text-color)'
32 | color-green-text: 'var(--primary-text-color)'
33 | color-red-text: 'var(--primary-text-color)'
34 | opacity-bg: '1'
35 |
36 | #background and sidebar
37 | card-background-color: '#FAFAFA'
38 | primary-background-color: '#EFEFEF'
39 | secondary-background-color: '#EFEFEF'
40 |
41 | #header
42 | app-header-text-color: 'var(--primary-text-color)'
43 | app-header-background-color: 'var(--primary-background-color)'
44 | # paper-tabs-selection-bar-color: 'var(--primary-text-color)'
45 |
46 | #slider
47 | slider-color: 'rgb(var(--color-blue))'
48 | slider-bar-color: 'rgba(var(--color-blue),0.38)'
49 |
50 | #cards
51 | box-shadow: '0px 2px 4px 0px rgba(0,0,0,0.16)'
52 | ha-card-box-shadow: 'var(--box-shadow)'
53 |
54 | #sidebar
55 | sidebar-selected-text-color: 'var(--google-red)'
56 | sidebar-selected-icon-color: 'var(--google-red)'
57 | sidebar-text-color: '#80868b'
58 |
59 | #switch
60 | switch-checked-color: 'var(--google-blue)'
61 |
62 | #media player
63 | mini-media-player-accent-color: 'var(--google-red)'
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/configuration/themes/mobile/mobile.yaml:
--------------------------------------------------------------------------------
1 | # Journal
2 | state-icon-color: 'rgb(var(--color-theme))'
3 | border-radius: '20px'
4 | error-color: 'var(--google-red)'
5 | warning-color: 'var(--google-yellow)'
6 | success-color: 'var(--google-green)'
7 | info-color: 'var(--google-blue)'
8 | divider-color: 'rgba(var(--color-theme),.12)'
9 | accent-color: 'var(--google-yellow)'
10 | card-mod-theme: mobile
11 | card-mod-root: |
12 | app-toolbar {
13 | display: none;
14 | }
15 | modes:
16 | light:
17 | !include mobile_light.yaml
18 | dark:
19 | !include mobile_dark.yaml
--------------------------------------------------------------------------------
/configuration/themes/mobile/mobile_dark.yaml:
--------------------------------------------------------------------------------
1 | ####################################################
2 | # #
3 | # DARK #
4 | # #
5 | ####################################################
6 | #text
7 | primary-text-color: '#DDDDDD'
8 |
9 | #main interface colors
10 | primary-color: '#89B3F8'
11 | google-red : '#F18B82'
12 | google-green : '#80C994'
13 | google-yellow : '#FCD663'
14 | google-blue : '#89B3F8'
15 | google-violet : '#BB86FC'
16 | google-grey: '#BBBBBB'
17 | color-red: 241, 139, 130
18 | color-green: 128, 201, 148
19 | color-yellow: 252, 214, 99
20 | color-blue : 137, 179, 248
21 | color-theme : 221,221,221
22 | color-purple : 102, 31, 255
23 | color-grey : 187, 187, 187
24 | color-pink : 233, 30, 99
25 | color-background-yellow : 'var(--color-yellow)'
26 | color-background-blue : 'var(--color-blue)'
27 | color-background-green : 'var(--color-green)'
28 | color-background-red : 'var(--color-red)'
29 | color-yellow-text: 'var(--color-yellow)'
30 | color-blue-text: 'var(--color-blue)'
31 | color-green-text: 'var(--color-green)'
32 | color-red-text: 'var(--color-red)'
33 | opacity-bg: '0.1'
34 |
35 | #floating button text color
36 | mdc-theme-on-secondary: 'var(--card-background-color)'
37 |
38 | #background and sidebar
39 | card-background-color: '#1D1D1D'
40 | primary-background-color: '#121212'
41 | secondary-background-color: '#121212'
42 |
43 | #header
44 | app-header-text-color: 'var(--primary-text-color)'
45 | app-header-background-color: 'var(--primary-background-color)'
46 | paper-tabs-selection-bar-color: 'var(--primary-text-color)'
47 |
48 | #Sidebar
49 | sidebar-selected-text-color: 'rgb(var(--color-blue))'
50 | sidebar-selected-icon-color: 'rgb(var(--color-blue))'
51 |
52 | #Slider
53 | slider-color: 'rgb(var(--color-blue))'
54 | slider-bar-color: 'rgba(var(--color-blue),0.38)'
55 |
56 | # card
57 | box-shadow: 'none'
58 |
59 | #media player
60 | mini-media-player-accent-color: 'var(--google-blue)'
61 |
62 | # Journal
63 | state-icon-color: 'rgb(var(--color-theme))'
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/configuration/themes/mobile/mobile_light.yaml:
--------------------------------------------------------------------------------
1 | ####################################################
2 | # #
3 | # LIGHT #
4 | # #
5 | ####################################################
6 | #text
7 | primary-text-color: '#212121'
8 |
9 | #main interface colors
10 | primary-color: '#434343'
11 | google-red : '#F54436'
12 | google-green : '#01C852'
13 | google-yellow : '#FF9101'
14 | google-blue : '#3D5AFE'
15 | google-violet : '#661FFF'
16 | google-grey: '#BBBBBB'
17 | color-red : 245, 68, 54
18 | color-green : 1, 200, 82
19 | color-yellow : 255, 145, 1
20 | color-blue : 61, 90, 254
21 | color-purple : 102, 31, 255
22 | color-grey : 187, 187, 187
23 | color-pink : 233, 30, 99
24 | color-theme : 51,51,51
25 | color-background-yellow : 250, 250, 250
26 | color-background-blue : 250, 250, 250
27 | color-background-green : 250, 250, 250
28 | color-background-red : 250, 250, 250
29 |
30 | color-yellow-text: 'var(--primary-text-color)'
31 | color-blue-text: 'var(--primary-text-color)'
32 | color-green-text: 'var(--primary-text-color)'
33 | color-red-text: 'var(--primary-text-color)'
34 | opacity-bg: '1'
35 |
36 | #background and sidebar
37 | card-background-color: '#FAFAFA'
38 | primary-background-color: '#EFEFEF'
39 | secondary-background-color: '#EFEFEF'
40 |
41 | #header
42 | app-header-text-color: 'var(--primary-text-color)'
43 | app-header-background-color: 'var(--primary-background-color)'
44 | # paper-tabs-selection-bar-color: 'var(--primary-text-color)'
45 |
46 | #slider
47 | slider-color: 'rgb(var(--color-blue))'
48 | slider-bar-color: 'rgba(var(--color-blue),0.38)'
49 |
50 | #cards
51 | box-shadow: '0px 2px 4px 0px rgba(0,0,0,0.16)'
52 | ha-card-box-shadow: 'var(--box-shadow)'
53 |
54 | #sidebar
55 | sidebar-selected-text-color: 'var(--google-red)'
56 | sidebar-selected-icon-color: 'var(--google-red)'
57 | sidebar-text-color: '#80868b'
58 |
59 | #switch
60 | switch-checked-color: 'var(--google-blue)'
61 |
62 | #media player
63 | mini-media-player-accent-color: 'var(--google-red)'
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/lovelace/resources/resources.yaml:
--------------------------------------------------------------------------------
1 | - type: module
2 | url: /hacsfiles/mini-graph-card/mini-graph-card-bundle.js
3 | - type: module
4 | url: /hacsfiles/mini-media-player/mini-media-player-bundle.js
5 | - type: module
6 | url: /hacsfiles/button-card/button-card.js
7 | - type: module
8 | url: /hacsfiles/lovelace-card-mod/card-mod.js
9 | - type: module
10 | url: /hacsfiles/swipe-card/swipe-card.js
11 | - type: module
12 | url: /hacsfiles/vertical-stack-in-card/vertical-stack-in-card.js
13 | - type: module
14 | url: /hacsfiles/lovelace-state-switch/state-switch.js
15 | - type: module
16 | url: /hacsfiles/lovelace-auto-entities/auto-entities.js
17 | - type: module
18 | url: /hacsfiles/ha-slider-card/slider-card.js
--------------------------------------------------------------------------------
/lovelace/views/01_home.yaml:
--------------------------------------------------------------------------------
1 | - title: Home
2 | icon: 'mdi:home-variant'
3 | path: home
4 | cards:
5 | - cards:
6 | - cards:
7 | - template: edge
8 | type: 'custom:button-card'
9 | - template: chips_temperature
10 | type: 'custom:button-card'
11 | - template: chips_icon
12 | label: Activée
13 | variables:
14 | icon: "mdi:shield-check"
15 | type: 'custom:button-card'
16 | - template: chips_localisation_present
17 | type: 'custom:button-card'
18 | - card:
19 | entity: input_boolean.invite_present
20 | template: chips
21 | label : "😃"
22 | type: 'custom:button-card'
23 | conditions:
24 | - entity: input_boolean.invite_present
25 | state_not: 'off'
26 | type: conditional
27 | - card:
28 | entity: input_boolean.mode_vacances
29 | template: chips
30 | label : "⛱️"
31 | type: 'custom:button-card'
32 | conditions:
33 | - entity: input_boolean.mode_vacances
34 | state_not: 'off'
35 | type: conditional
36 | - template: edge
37 | type: 'custom:button-card'
38 | type: horizontal-stack
39 |
40 | ####################################################
41 | # #
42 | # SCENES #
43 | # #
44 | ####################################################
45 | - type: custom:state-switch
46 | entity: user
47 | default: default
48 | states:
49 | Thomas:
50 | type: vertical-stack
51 | cards:
52 | - type: 'custom:button-card'
53 | name: Scènes
54 | template: title
55 | - cards:
56 | - template: edge
57 | type: 'custom:button-card'
58 | - entity: sensor.present
59 | template: scene_blue
60 | variables:
61 | state: "Present"
62 | type: 'custom:button-card'
63 | - entity: sensor.absent
64 | template: scene_green
65 | variables:
66 | state: "Absent"
67 | type: 'custom:button-card'
68 | - entity: sensor.travail
69 | template: scene_green
70 | variables:
71 | state: "Travail"
72 | type: 'custom:button-card'
73 | - entity: sensor.nuit
74 | template:
75 | - scene
76 | - blue
77 | tap_action:
78 | action: more-info
79 | entity: input_boolean.thomas_nuit
80 | type: 'custom:button-card'
81 | - template: edge
82 | type: 'custom:button-card'
83 | type: horizontal-stack
84 |
85 | ####################################################
86 | # #
87 | # PS4 #
88 | # #
89 | ####################################################
90 |
91 | - card:
92 | cards:
93 | - type: 'custom:button-card'
94 | name: Media
95 | template: title
96 | - cards:
97 | - template: edge
98 | type: 'custom:button-card'
99 | - artwork: full-cover
100 | entity: media_player.playstation_4
101 | style: |
102 | :host {
103 | --ha-card-border-radius: var(--border-radius);
104 | --ha-card-box-shadow: var(--box-shadow);
105 | }
106 | type: 'custom:mini-media-player'
107 | - template: edge
108 | type: 'custom:button-card'
109 | type: horizontal-stack
110 | type: vertical-stack
111 | conditions:
112 | - entity: media_player.playstation_4
113 | state_not: 'unknown'
114 | type: conditional
115 |
116 | ####################################################
117 | # #
118 | # MEDIA #
119 | # #
120 | ####################################################
121 |
122 | - card:
123 | cards:
124 | - type: 'custom:button-card'
125 | name: Media
126 | template: title
127 | - cards:
128 | - template: edge
129 | type: 'custom:button-card'
130 |
131 |
132 | - artwork: full-cover
133 | entity: media_player.cuisine
134 | style: |
135 | :host {
136 | --ha-card-border-radius: var(--border-radius);
137 | --ha-card-box-shadow: var(--box-shadow);
138 | }
139 | type: 'custom:mini-media-player'
140 | - template: edge
141 | type: 'custom:button-card'
142 | type: horizontal-stack
143 | type: vertical-stack
144 | conditions:
145 | - entity: media_player.cuisine
146 | state_not: 'off'
147 | type: conditional
148 |
149 | ####################################################
150 | # #
151 | # SALON #
152 | # #
153 | ####################################################
154 | - type: 'custom:button-card'
155 | name: Salon
156 | label: '4 appareils'
157 | template: title
158 | - cards:
159 | - template: edge
160 | type: 'custom:button-card'
161 | - type: grid
162 | columns: 2
163 | square: false
164 | cards:
165 | - entity: light.hue_light_table
166 | name: Principale
167 | template:
168 | - icon_info_bg
169 | - light
170 | type: 'custom:button-card'
171 |
172 | - entity: switch.shelly_prise_salon
173 | name: Prise
174 | template:
175 | - icon_info_bg
176 | - outlet
177 | label: |-
178 | [[[ if (entity.state =='on')
179 | var etat = "On • " + states["sensor.shelly_prise_salon_conso"].state + "W";
180 | else
181 | var etat = "Off";
182 | return etat ; ]]]
183 | type: 'custom:button-card'
184 |
185 | - entity: binary_sensor.fibaro_multisensor_salon_mouvement
186 | name: Mouvement
187 | icon: 'mdi:run'
188 | template:
189 | - icon_info_bg
190 | - binary_sensor
191 | type: 'custom:button-card'
192 |
193 | - entity: climate.thermostat
194 | name: Thermostat
195 | template:
196 | - icon_info_bg
197 | - thermostat
198 | type: 'custom:button-card'
199 |
200 | - entity: switch.nas
201 | name: NAS
202 | template:
203 | - icon_info_bg
204 | - nas
205 | type: 'custom:button-card'
206 |
207 | - entity: switch.shelly_prise_salon
208 | name: Chauffe eau
209 | template:
210 | - icon_info_bg
211 | - water_heater
212 | type: 'custom:button-card'
213 |
214 | - template: cover_buttons
215 | variables:
216 | entity: "cover.fibaro_cover_fenetre"
217 | name: "Fenêtre"
218 | type: 'custom:button-card'
219 |
220 | - template: cover_buttons
221 | variables:
222 | entity: "cover.fibaro_cover_balcon"
223 | name: "Balcon"
224 | type: 'custom:button-card'
225 |
226 | - entity: media_player.playstation_4
227 | template:
228 | - icon_info_bg
229 | - ps4
230 | type: 'custom:button-card'
231 |
232 | - template: edge
233 | type: 'custom:button-card'
234 | type: horizontal-stack
235 |
236 | ####################################################
237 | # #
238 | # CHAMBRE #
239 | # #
240 | ####################################################
241 |
242 | - type: 'custom:button-card'
243 | name: Chambre
244 | label: '2 appareils'
245 | template: title
246 | - cards:
247 | - template: edge
248 | type: 'custom:button-card'
249 | - type: grid
250 | columns: 2
251 | square: false
252 | cards:
253 | - entity: light.hue_light_chambre
254 | name: Lumière
255 | template:
256 | - icon_info_bg
257 | - light
258 | type: 'custom:button-card'
259 |
260 | - entity: light.hue_light_go_chambre
261 | template:
262 | - light_slider
263 | variables:
264 | entity: "light.hue_light_go_chambre"
265 | name: "Hue Go"
266 | type: 'custom:button-card'
267 |
268 | - template: edge
269 | type: 'custom:button-card'
270 | type: horizontal-stack
271 |
272 | ####################################################
273 | # #
274 | # CUISINE #
275 | # #
276 | ####################################################
277 |
278 | - type: 'custom:button-card'
279 | name: Cuisine
280 | label: '2 appareils'
281 | template: title
282 | - cards:
283 | - template: edge
284 | type: 'custom:button-card'
285 | - type: grid
286 | columns: 2
287 | square: false
288 | cards:
289 | - entity: light.cuisine
290 | name: Lumière
291 | template:
292 | - icon_info_bg
293 | - light
294 | type: 'custom:button-card'
295 | - entity: media_player.cuisine
296 | name: Enceintes
297 | template:
298 | - icon_info_bg
299 | - media
300 | type: 'custom:button-card'
301 | - template: edge
302 | type: 'custom:button-card'
303 | type: horizontal-stack
304 |
305 | ####################################################
306 | # #
307 | # SALLE DE BAIN #
308 | # #
309 | ####################################################
310 | - type: 'custom:button-card'
311 | name: Salle de bain
312 | label: '1 appareils'
313 | template: title
314 | - cards:
315 | - template: edge
316 | type: 'custom:button-card'
317 | - type: grid
318 | columns: 2
319 | square: false
320 | cards:
321 | - entity: light.hue_light_salle_de_bain
322 | name: Lumière
323 | template:
324 | - icon_info_bg
325 | - light
326 | type: 'custom:button-card'
327 | - template: edge
328 | type: 'custom:button-card'
329 | type: horizontal-stack
330 |
331 | type: vertical-stack
332 |
--------------------------------------------------------------------------------
/lovelace/views/02_temperature.yaml:
--------------------------------------------------------------------------------
1 | - title: temperature
2 | icon: 'mdi:thermometer'
3 | path: temperature
4 | cards:
5 | - cards:
6 | - cards:
7 | - template: edge
8 | type: 'custom:button-card'
9 | - template: chips_return
10 | type: 'custom:button-card'
11 | - template: chips_temperature
12 | type: 'custom:button-card'
13 | - template: edge
14 | type: 'custom:button-card'
15 | type: horizontal-stack
16 | - type: 'custom:button-card'
17 | name: Températures
18 | template: title
19 | - cards:
20 | - template: edge
21 | type: 'custom:button-card'
22 | - type: weather-forecast
23 | style: |
24 | ha-card {
25 | box-shadow: var(--box-shadow);
26 | border-radius: 20px;
27 | padding: 12px !important;
28 | }
29 | .icon-image{
30 | min-width: 42px !important;
31 | margin-right: 12px !important;
32 | }
33 | .icon-image > *{
34 | height: 42px !important;
35 | width: 42px;
36 | flex: 0 0 42px !important;
37 | }
38 | .state {
39 | font-size: 14px !important;
40 | font-weight: bold;
41 | }
42 | .name{
43 | font-weight: bolder;
44 | font-size: 12px !important;
45 | filter: opacity(40%);
46 | color: var(--primary-text-color) !important;
47 | }
48 | .temp{
49 | font-size: 14px !important;
50 | font-weight: bold;
51 | margin-right: 14px !important;
52 | }
53 | .attribute{
54 | font-size: 12px !important;
55 | font-weight: bolder;
56 | filter: opacity(40%);
57 | color: var(--primary-text-color) !important;
58 | }
59 | span{
60 | font-size: 14px !important;
61 | font-weight: bold;
62 | }
63 | entity: weather.dark_sky
64 | show_forecast : false
65 | name: Toulouse
66 | - template: edge
67 | type: 'custom:button-card'
68 | type: horizontal-stack
69 | - type: 'custom:button-card'
70 | label: 'Salon'
71 | template: title
72 |
73 | - type: 'custom:button-card'
74 | label: 'Intérieur'
75 | template: title
76 |
77 | - cards:
78 | - template: edge
79 | type: 'custom:button-card'
80 | - type: grid
81 | columns: 2
82 | square: false
83 | cards:
84 | - type: 'custom:button-card'
85 | template: graph
86 | variables:
87 | entity: "sensor.fibaro_multisensor_salon_temperature"
88 | color: "var(--google-blue)"
89 | name: "Température"
90 | - type: 'custom:button-card'
91 | template: graph
92 | variables:
93 | entity: "sensor.fibaro_multisensor_salon_luminosite"
94 | color: "var(--google-blue)"
95 | name: "Luminosité"
96 | - type: 'custom:button-card'
97 | template: graph
98 | variables:
99 | entity: "sensor.xiaomi_multisensor_chambre_humidite"
100 | color: "var(--google-blue)"
101 | name: "Humidité"
102 |
103 | - type: 'custom:button-card'
104 | template: graph
105 | variables:
106 | entity: "sensor.xiaomi_multisensor_chambre_pression"
107 | color: "var(--google-blue)"
108 | name: "Pression"
109 | - template: edge
110 | type: 'custom:button-card'
111 | type: horizontal-stack
112 |
113 | - type: 'custom:button-card'
114 | label: 'Extérieur'
115 | template: title
116 |
117 | - cards:
118 | - template: edge
119 | type: 'custom:button-card'
120 | - type: grid
121 | columns: 2
122 | square: false
123 | cards:
124 | - type: 'custom:button-card'
125 | template: graph
126 | variables:
127 | entity: "sensor.fibaro_multisensor_balcon_temperature"
128 | color: "var(--google-green)"
129 | name: "Température"
130 |
131 | - type: 'custom:button-card'
132 | template: graph
133 | variables:
134 | entity: "sensor.fibaro_multisensor_balcon_luminosite"
135 | color: "var(--google-green)"
136 | name: "Luminosité"
137 | - template: edge
138 | type: 'custom:button-card'
139 | type: horizontal-stack
140 |
141 | type: vertical-stack
142 |
143 |
--------------------------------------------------------------------------------
/lovelace/views/03_consommation.yaml:
--------------------------------------------------------------------------------
1 | - title: Consommation
2 | icon: 'mdi:flash'
3 | path: consommation
4 | cards:
5 | - cards:
6 | - cards:
7 | - template: edge
8 | type: 'custom:button-card'
9 | - template: chips_return
10 | type: 'custom:button-card'
11 | - template: edge
12 | type: 'custom:button-card'
13 | type: horizontal-stack
14 |
15 | - type: 'custom:button-card'
16 | name: Batterie
17 | template: title
18 |
19 | - cards:
20 | - template: edge
21 | type: 'custom:button-card'
22 | - type: 'custom:auto-entities'
23 | sort:
24 | method: state
25 | numeric: true
26 | card:
27 | type: grid
28 | columns: 1
29 | square: false
30 | card_param: cards
31 | filter:
32 | exclude: null
33 | include:
34 | - entity_id: sensor.*battery_level
35 | options:
36 | type: 'custom:button-card'
37 | template:
38 | - icon_info_bg
39 | - generic
40 | - template: edge
41 | type: 'custom:button-card'
42 | type: horizontal-stack
43 | type: vertical-stack
--------------------------------------------------------------------------------
/lovelace/views/04_localisation.yaml:
--------------------------------------------------------------------------------
1 | - title: Localisation
2 | icon: 'mdi:map-marker'
3 | path: localisation
4 | cards:
5 | - cards:
6 | - cards:
7 | - template: bordures
8 | type: 'custom:button-card'
9 | - template: return_button
10 | type: 'custom:button-card'
11 | - template: pilule_localisation_present
12 | type: 'custom:button-card'
13 | - template: pilule_localisation_absent
14 | type: 'custom:button-card'
15 | - template: pilule_localisation_nuit
16 | type: 'custom:button-card'
17 | - card:
18 | entity: input_boolean.invite_present
19 | template: pilule
20 | label : "😃"
21 | type: 'custom:button-card'
22 | conditions:
23 | - entity: input_boolean.invite_present
24 | state_not: 'off'
25 | type: conditional
26 | - card:
27 | entity: input_boolean.mode_vacances
28 | template: pilule
29 | label : "⛱️"
30 | type: 'custom:button-card'
31 | conditions:
32 | - entity: input_boolean.mode_vacances
33 | state_not: 'off'
34 | type: conditional
35 | - template: bordures
36 | type: 'custom:button-card'
37 | type: horizontal-stack
38 |
39 | ####################################################
40 | # #
41 | # LOCALISATION #
42 | # #
43 | ####################################################
44 |
45 | - type: 'custom:button-card'
46 | name: Localisation
47 | label: '2 personnes'
48 | template: titre
49 | - cards:
50 | - template: bordures
51 | type: 'custom:button-card'
52 | - type: grid
53 | columns: 2
54 | square: false
55 | cards:
56 | - entity: input_select.localisation_thomas
57 | variables:
58 | personne: "thomas"
59 | template:
60 | - icon_info_bg
61 | - personne-thomas
62 | name: Thomas
63 | type: 'custom:button-card'
64 | - entity: input_select.localisation_milena
65 | template:
66 | - icon_info_bg
67 | - personne-milena
68 | name: Miléna
69 | type: 'custom:button-card'
70 |
71 | - template: bordures
72 | type: 'custom:button-card'
73 |
74 | type: horizontal-stack
75 | - type: 'custom:button-card'
76 | label: 'Modes'
77 | template: titre
78 | - cards:
79 | - template: bordures
80 | type: 'custom:button-card'
81 | - type: grid
82 | columns: 2
83 | square: false
84 | cards:
85 | - entity: input_boolean.invite_present
86 | template:
87 | - icon_info_bg
88 | - personne-invite
89 | type: 'custom:button-card'
90 | - entity: input_boolean.mode_vacances
91 | name: "Vacances"
92 | show_last_changed: false
93 | label: >
94 | [[[return entity.state]]]
95 | template:
96 | - icon_info_bg
97 | - mouvement
98 | type: 'custom:button-card'
99 | icon: 'mdi:white-balance-sunny'
100 | - template: bordures
101 | type: 'custom:button-card'
102 |
103 | type: horizontal-stack
104 | type: vertical-stack
105 |
106 |
--------------------------------------------------------------------------------
/screenshots/anatomy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/anatomy.png
--------------------------------------------------------------------------------
/screenshots/binary_sensor-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/binary_sensor-1.png
--------------------------------------------------------------------------------
/screenshots/binary_sensor-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/binary_sensor-2.png
--------------------------------------------------------------------------------
/screenshots/cards.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/cards.png
--------------------------------------------------------------------------------
/screenshots/chips.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/chips.png
--------------------------------------------------------------------------------
/screenshots/chips_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/chips_icon.png
--------------------------------------------------------------------------------
/screenshots/chips_localisation_present.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/chips_localisation_present.png
--------------------------------------------------------------------------------
/screenshots/chips_return.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/chips_return.png
--------------------------------------------------------------------------------
/screenshots/chips_temperature.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/chips_temperature.png
--------------------------------------------------------------------------------
/screenshots/cover_buttons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/cover_buttons.png
--------------------------------------------------------------------------------
/screenshots/entity_graph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/entity_graph.png
--------------------------------------------------------------------------------
/screenshots/generic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/generic.png
--------------------------------------------------------------------------------
/screenshots/light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/light.png
--------------------------------------------------------------------------------
/screenshots/light_slider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/light_slider.png
--------------------------------------------------------------------------------
/screenshots/media.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/media.png
--------------------------------------------------------------------------------
/screenshots/outlet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/outlet.png
--------------------------------------------------------------------------------
/screenshots/person.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/person.png
--------------------------------------------------------------------------------
/screenshots/playstation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/playstation.png
--------------------------------------------------------------------------------
/screenshots/power_consumption.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/power_consumption.png
--------------------------------------------------------------------------------
/screenshots/thermostat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/thermostat.png
--------------------------------------------------------------------------------
/screenshots/title.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/title.png
--------------------------------------------------------------------------------
/screenshots/water-heater.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/screenshots/water-heater.png
--------------------------------------------------------------------------------
/ui-lovelace.yaml:
--------------------------------------------------------------------------------
1 | button_card_templates: !include lovelace/button_card_templates/button_card_templates.yaml
2 | title: 'Home'
3 | views: !include_dir_merge_list lovelace/views/
4 |
5 |
--------------------------------------------------------------------------------
/www/community/button-card/button-card.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/button-card/button-card.js.gz
--------------------------------------------------------------------------------
/www/community/ha-slider-card/slider-card.js:
--------------------------------------------------------------------------------
1 | import {
2 | LitElement,
3 | html,
4 | css
5 | } from "https://unpkg.com/lit-element@2.0.1/lit-element.js?module";
6 | class SliderCard extends LitElement {
7 |
8 | static get properties() {
9 | return {
10 | hass: {},
11 | config: {},
12 | active: {}
13 | };
14 | }
15 |
16 | constructor() {
17 | super();
18 | // console.log("SLIDER-CARD V36 INSTALLED--------------------------------------------------------------");
19 | }
20 |
21 | render() {
22 | // Size Variables
23 | var minBar = this.config.minBar ? this.config.minBar : 0;
24 | var maxBar = this.config.maxBar ? this.config.maxBar : 100;
25 | var minSet = this.config.minSet ? this.config.minSet : 0;
26 | var maxSet = this.config.maxSet ? this.config.maxSet : 100;
27 | var width = this.config.width ? this.config.width : "100%";
28 | var height = this.config.height ? this.config.height : "50px";
29 | var radius = this.config.radius ? this.config.radius : "4px";
30 | var top = this.config.top ? this.config.top : "0px";
31 | var bottom = this.config.bottom ? this.config.bottom : "0px";
32 | var right = this.config.right ? this.config.right : "0px";
33 | var left = this.config.left ? this.config.left : "0px";
34 | var rotate = this.config.rotate ? this.config.rotate : "0";
35 | var containerHeight = this.config.containerHeight ? this.config.containerHeight : height;
36 | if (rotate != "0") {
37 | rotate = rotate + "deg";
38 | }
39 | // Slider Background Color Variables
40 | var mainSliderColor = this.config.mainSliderColor ? this.config.mainSliderColor : "var(--accent-color)";
41 | var secondarySliderColor = this.config.secondarySliderColor ? this.config.secondarySliderColor : "#4d4d4d";
42 | var mainSliderColorOff = this.config.mainSliderColorOff ? this.config.mainSliderColorOff : "#636363";
43 | var secondarySliderColorOff = this.config.secondarySliderColorOff ? this.config.secondarySliderColorOff : "#4d4d4d";
44 | var border = this.config.border ? this.config.border : "0";
45 | // Slider Thumb Variables
46 | var thumbWidth = this.config.thumbWidth ? this.config.thumbWidth : "25px";
47 | var thumbHeight = this.config.thumbHeight ? this.config.thumbHeight : "80px";
48 | var thumbColor = this.config.thumbColor ? this.config.thumbColor : "#FFFFFF";
49 | var thumbColorOff = this.config.thumbColorOff ? this.config.thumbColorOff : "#969696";
50 | var thumbHorizontalPadding = this.config.thumbHorizontalPadding ? this.config.thumbHorizontalPadding : "10px";
51 | var thumbVerticalPadding = this.config.thumbVerticalPadding ? this.config.thumbVerticalPadding : "20px";
52 | var thumbTop = this.config.thumpTop ? this.config.thumpTop : "calc((var(--slider-width) - var(--thumb-height)) / 2)";
53 | var thumbBorderRight = this.config.thumbBorderRight ? this.config.thumbBorderRight : "var(--thumb-horizontal-padding) solid var(--slider-main-color)";
54 | var thumbBorderLeft = this.config.thumbBorderLeft ? this.config.thumbBorderLeft : "var(--thumb-horizontal-padding) solid var(--slider-main-color)";
55 | var thumbBorderTop = this.config.thumbBorderTop ? this.config.thumbBorderTop : "var(--thumb-vertical-padding) solid var(--slider-main-color)";
56 | var thumbBorderBotton = this.config.thumbBorderBotton ? this.config.thumbBorderBotton : "var(--thumb-vertical-padding) solid var(--slider-main-color)";
57 | // top: calc((var(--slider-width) - var(--thumb-height)) / 2);
58 | // border-right: var(--thumb-horizontal-padding) solid var(--slider-main-color);
59 | // border-left: var(--thumb-horizontal-padding) solid var(--slider-main-color);
60 | // border-top: var(--thumb-vertical-padding) solid var(--slider-main-color);
61 | // border-bottom: var(--thumb-vertical-padding) solid var(--slider-main-color);
62 |
63 |
64 | var entity = this.config.entity;
65 | var entityClass = this.hass.states[entity]
66 |
67 | var isLight = false;
68 | var isInputNumber = false;
69 | var isMediaPlayer= false;
70 | var isCover = false;
71 | var isFan = false;
72 | var isSwitch = false;
73 | var isLock = false;
74 |
75 | // Check if entity is light or input_number
76 | if (this.config.entity.includes("light.")) {
77 | isLight = true;
78 | var step = this.config.step ? this.config.step: "1";
79 | }
80 | else if (this.config.entity.includes("input_number.")) {
81 | isInputNumber = true;
82 | var step = this.config.step ? this.config.step: entityClass.attributes.step;
83 | }
84 | else if (this.config.entity.includes("media_player.")) {
85 | isMediaPlayer = true;
86 | var step = this.config.step ? this.config.step: "1";
87 | }
88 | else if (this.config.entity.includes("cover.")) {
89 | isCover = true;
90 | var step = this.config.step ? this.config.step: "1";
91 | }
92 | else if (this.config.entity.includes("fan.")) {
93 | isFan = true;
94 | var step = this.config.step ? this.config.step: "1";
95 | }
96 | else if (this.config.entity.includes("switch.")) {
97 | isSwitch = true;
98 | var step = this.config.step ? this.config.step: "1";
99 | }
100 | else if (this.config.entity.includes("lock.")) {
101 | isLock = true;
102 | var step = this.config.step ? this.config.step: "1";
103 | }
104 |
105 | var styleStr = `
106 | --slider-width: ${width};
107 | --slider-width-inverse: -${width};
108 | --slider-height: ${height};
109 | --slider-main-color: ${(entityClass.state === "off" || entityClass.state === "locked" || entityClass.state == undefined) ? "var(--slider-main-color-off)" : "var(--slider-main-color-on)"};
110 | --slider-main-color-on: ${mainSliderColor};
111 | --slider-main-color-off: ${mainSliderColorOff};
112 | --slider-secondary-color: ${(entityClass.state === "off" || entityClass.state === "locked" || entityClass.state == undefined) ? "var(--slider-secondary-color-off)" : "var(--slider-secondary-color-on)"};
113 | --slider-secondary-color-on: ${secondarySliderColor};
114 | --slider-secondary-color-off: ${secondarySliderColorOff};
115 | --slider-radius: ${radius};
116 | --border: ${border};
117 |
118 | --thumb-width: ${thumbWidth};
119 | --thumb-height: ${thumbHeight};
120 | --thumb-color: ${(entityClass.state === "off" || entityClass.state == undefined) ? "var(--thumb-color-off)" : "var(--thumb-color-on)"};
121 | --thumb-color-on: ${thumbColor};
122 | --thumb-color-off: ${thumbColorOff};
123 | --thumb-horizontal-padding: ${thumbHorizontalPadding};
124 | --thumb-vertical-padding: ${thumbVerticalPadding};
125 |
126 | --rotate: ${rotate};
127 | --top: ${top};
128 | --bottom: ${bottom};
129 | --right: ${right};
130 | --left: ${left};
131 | --container-height: ${containerHeight};
132 | --thumb-top: ${thumbTop};
133 | --thumb-border-right: ${thumbBorderRight};
134 | --thumb-border-left: ${thumbBorderLeft};
135 | --thumb-border-top: ${thumbBorderTop};
136 | --thumb-border-bottom: ${thumbBorderBotton};
137 | `;
138 | if (isLight) {
139 | if (this.config.function == "Warmth") {
140 | return html`
141 |
142 |
143 | this._setWarmth(entityClass, e.target, minSet, maxSet)}>
144 |
145 |
146 | `;
147 | }
148 | else {
149 | return html`
150 |
151 |
152 | this._setBrightness(entityClass, e.target, minSet, maxSet)}>
153 |
154 |
155 | `;
156 | }
157 | }
158 |
159 | if (isInputNumber) {
160 | return html`
161 |
162 |
163 | this._setInputNumber(entityClass, e.target, minSet, maxSet)}>
164 |
165 |
166 | `;
167 | }
168 |
169 | if (isMediaPlayer) {
170 | var num = 0;
171 | if (entityClass.attributes.volume_level != undefined) {
172 | var num = Number(entityClass.attributes.volume_level * 100)
173 | }
174 |
175 | return html`
176 |
177 |
178 | this._setMediaVolume(entityClass, e.target, minSet, maxSet)}>
179 |
180 |
181 | `;
182 | }
183 |
184 | if (isCover) {
185 | return html`
186 |
187 |
188 | this._setCover(entityClass, e.target, minSet, maxSet)}>
189 |
190 |
191 | `;
192 | }
193 |
194 | if (isFan) {
195 | return html`
196 |
197 |
198 | this._setFan(entityClass, e.target, minSet, maxSet)}>
199 |
200 |
201 | `;
202 | }
203 |
204 | if (isSwitch) {
205 | return html`
206 |
207 |
208 | this._setSwitch(entityClass, e.target, minSet, maxSet, minBar, maxBar)}>
209 |
210 |
211 | `;
212 | }
213 |
214 | if (isLock) {
215 | return html`
216 |
217 |
218 | this._setLock(entityClass, e.target, minSet, maxSet, minBar, maxBar)}>
219 |
220 |
221 | `;
222 | }
223 | }
224 |
225 |
226 | updated() {}
227 |
228 |
229 | _setFan(entityClass, target, minSet, maxSet) {
230 | var value = target.value;
231 | if (value > maxSet) {
232 | var value = maxSet;
233 | } else if (value < minSet) {
234 | var value = minSet;
235 | }
236 |
237 | this.hass.callService("fan", "set_percentage", {
238 | entity_id: entityClass.entity_id,
239 | percentage: value
240 | });
241 |
242 | target.value = value;
243 | }
244 |
245 | _setCover(entityClass, target, minSet, maxSet) {
246 | var value = target.value;
247 | if (value > maxSet) {
248 | var value = maxSet;
249 | } else if (value < minSet) {
250 | var value = minSet;
251 | }
252 | // console.log("Setting Cover to: " + value);
253 | // console.log("From Position: " + entityClass.attributes.current_position);
254 | this.hass.callService("cover", "set_cover_position", {
255 | entity_id: entityClass.entity_id,
256 | position: value
257 | });
258 |
259 | target.value = value;
260 | }
261 |
262 | _setMediaVolume(entityClass, target, minSet, maxSet) {
263 | var value = target.value;
264 | if (value > maxSet) {
265 | var value = maxSet;
266 | } else if (value < minSet) {
267 | var value = minSet;
268 | }
269 |
270 | this.hass.callService("media_player", "volume_set", {
271 | entity_id: entityClass.entity_id,
272 | volume_level: value / 100
273 | });
274 |
275 | target.value = value;
276 | }
277 |
278 | _setInputNumber(entityClass, number, minSet, maxSet) {
279 | var value = target.value;
280 | if (value > maxSet) {
281 | var value = maxSet;
282 | } else if (value < minSet) {
283 | var value = minSet;
284 | }
285 |
286 | this.hass.callService("input_number", "set_value", {
287 | entity_id: entityClass.entity_id,
288 | value: value
289 | });
290 |
291 | target.value = value;
292 | }
293 |
294 | _setBrightness(entityClass, target, minSet, maxSet) {
295 | var value = target.value;
296 | if (value > maxSet) {
297 | var value = maxSet;
298 | } else if (value < minSet) {
299 | var value = minSet;
300 | }
301 |
302 | this.hass.callService("homeassistant", "turn_on", {
303 | entity_id: entityClass.entity_id,
304 | brightness: value * 2.55
305 | });
306 |
307 | // console.dir(this)
308 | target.value = value;
309 |
310 | }
311 |
312 | _setWarmth(entityClass, target, minSet, maxSet) {
313 | var value = target.value;
314 | if (value > maxSet) {
315 | var value = maxSet;
316 | } else if (value < minSet) {
317 | var value = minSet;
318 | }
319 |
320 | this.hass.callService("homeassistant", "turn_on", {
321 | entity_id: entityClass.entity_id,
322 | color_temp: value
323 | });
324 |
325 | target.value = value;
326 | }
327 |
328 | _setSwitch(entityClass, target, minSet, maxSet, minBar, maxBar) {
329 | var value = target.value;
330 | var threshold = Math.min(maxSet,maxBar) //pick lesser of the two
331 | if (Number(threshold) <= value) {
332 | this.hass.callService("homeassistant", "toggle", {
333 | entity_id: entityClass.entity_id
334 | });
335 | }
336 |
337 | target.value = Number(Math.max(minSet, minBar));
338 | }
339 |
340 | _setLock(entityClass, target, minSet, maxSet, minBar, maxBar) {
341 | var value = target.value;
342 | var threshold = Math.min(maxSet,maxBar) //pick lesser of the two
343 | if (Number(threshold) <= value) {
344 | var newLockState = entityClass.state === "locked" ? 'unlock' : 'lock'
345 | this.hass.callService("lock", newLockState, {
346 | entity_id: entityClass.entity_id
347 | });
348 | }
349 |
350 | target.value = Number(Math.max(minSet, minBar));
351 | }
352 |
353 | _switch(entityClass) {
354 | this.hass.callService("homeassistant", "toggle", {
355 | entity_id: entityClass.entity_id
356 | });
357 | }
358 |
359 | _navigate(path) {
360 | window.location.href = path;
361 | }
362 |
363 | setConfig(config) {
364 | if (!config.entity) {
365 | throw new Error("You need to define entity");
366 | }
367 |
368 | if (!config.entity.includes("input_number.") && !config.entity.includes("light.") && !config.entity.includes("media_player.") && !config.entity.includes("cover.") && !config.entity.includes("fan.") && !config.entity.includes("switch.") && !config.entity.includes("lock.") ) {
369 | throw new Error("Entity has to be a light, input_number, media_player, cover or a fan.");
370 | }
371 |
372 | this.config = config;
373 | }
374 |
375 | getCardSize() {
376 | return 0;
377 | }
378 |
379 | // -webkit-transform: rotate(270deg);
380 | // -moz-transform: rotate(270deg);
381 | // -o-transform: rotate(270deg);
382 | // -ms-transform: rotate(270deg);
383 | // transform: rotate(270deg);
384 | static get styles() {
385 | return css`
386 | .slider-container {
387 | height: var(--container-height);
388 | position: relative;
389 | overflow: hidden;
390 | border-radius: var(--slider-radius);
391 | }
392 |
393 | .slider-container input[type="range"] {
394 | outline: 0;
395 | border: var(--border);
396 | width: var(--slider-width);
397 | height: var(--slider-height);
398 | border-radius: var(--slider-radius);
399 | background-color: var(--slider-secondary-color); /*Remaining Slider color*/
400 | margin: 0;
401 | transition: box-shadow 0.2s ease-in-out;
402 | overflow: hidden;
403 | -webkit-appearance: none;
404 | position: absolute;
405 | top: var(--top);
406 | bottom: var(--bottom);
407 | right: var(--right);
408 | left: var(--left);
409 | -webkit-transform: rotate(var(--rotate));
410 | -moz-transform: rotate(var(--rotate));
411 | -o-transform: rotate(var(--rotate));
412 | -ms-transform: rotate(var(--rotate));
413 | transform: rotate(var(--rotate));
414 | }
415 |
416 | .slider-container input[type="range"]::-webkit-slider-runnable-track {
417 | height: var(--slider-height);
418 | -webkit-appearance: none;
419 | color: var(--slider-main-color);
420 | transition: box-shadow 0.2s ease-in-out;
421 | }
422 |
423 | .slider-container input[type="range"]::-webkit-slider-thumb {
424 | width: var(--thumb-width);
425 | height: var(--thumb-height);
426 | -webkit-appearance: none;
427 | cursor: ew-resize;
428 | border-radius: 0;
429 | transition: box-shadow 0.2s ease-in-out;
430 | position: relative;
431 |
432 | box-shadow: -3500px 0 0 3500px var(--slider-main-color), inset 0 0 0 25px var(--thumb-color);
433 |
434 | top: var(--thumb-top);
435 | border-right: var(--thumb-border-right);
436 | border-left: var(--thumb-border-left);
437 | border-top: var(--thumb-border-top);
438 | border-bottom: var(--thumb-border-bottom);
439 | }
440 |
441 | .slider-container input[type=range]::-moz-range-thumb {
442 | width: calc(var(--thumb-width) / 4);
443 | height: calc(var(--thumb-height) / 2);
444 | box-shadow: -3500px 10px 0 3500px var(--slider-main-color), inset 0 0 0 25px var(--thumb-color);
445 | top: var(--thumb-top);
446 | cursor: ew-resize;
447 | border-radius: 0;
448 | transition: box-shadow 0.2s ease-in-out;
449 | position: relative;
450 | border-radius: 0;
451 | border-right: var(--thumb-border-right);
452 | border-left: var(--thumb-border-left);
453 | border-top: var(--thumb-border-top);
454 | border-bottom: var(--thumb-border-bottom);
455 | }
456 |
457 | .slider-container input[type="range"]::-webkit-slider-thumb:hover {
458 | cursor: default;
459 | }
460 |
461 | .slider-container input[type="range"]:hover {
462 | cursor: default;
463 | }
464 | `;
465 | }
466 |
467 | }
468 |
469 | customElements.define('slider-card', SliderCard);
470 |
--------------------------------------------------------------------------------
/www/community/ha-slider-card/slider-card.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/ha-slider-card/slider-card.js.gz
--------------------------------------------------------------------------------
/www/community/lovelace-auto-entities/auto-entities.js:
--------------------------------------------------------------------------------
1 | function t(t,e,i,s){var n,o=arguments.length,r=o<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,i,s);else for(var a=t.length-1;a>=0;a--)(n=t[a])&&(r=(o<3?n(r):o>3?n(e,i,r):n(e,i))||r);return o>3&&r&&Object.defineProperty(e,i,r),r}const e="undefined"!=typeof window&&null!=window.customElements&&void 0!==window.customElements.polyfillWrapFlushCallback,i=(t,e,i=null)=>{for(;e!==i;){const i=e.nextSibling;t.removeChild(e),e=i}},s=`{{lit-${String(Math.random()).slice(2)}}}`,n=`\x3c!--${s}--\x3e`,o=new RegExp(`${s}|${n}`);class r{constructor(t,e){this.parts=[],this.element=e;const i=[],n=[],r=document.createTreeWalker(e.content,133,null,!1);let l=0,h=-1,u=0;const{strings:p,values:{length:f}}=t;for(;u0;){const e=p[u],i=d.exec(e)[2],s=i.toLowerCase()+"$lit$",n=t.getAttribute(s);t.removeAttribute(s);const r=n.split(o);this.parts.push({type:"attribute",index:h,name:i,strings:r}),u+=r.length-1}}"TEMPLATE"===t.tagName&&(n.push(t),r.currentNode=t.content)}else if(3===t.nodeType){const e=t.data;if(e.indexOf(s)>=0){const s=t.parentNode,n=e.split(o),r=n.length-1;for(let e=0;e{const i=t.length-e.length;return i>=0&&t.slice(i)===e},l=t=>-1!==t.index,c=()=>document.createComment(""),d=/([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;function h(t,e){const{element:{content:i},parts:s}=t,n=document.createTreeWalker(i,133,null,!1);let o=p(s),r=s[o],a=-1,l=0;const c=[];let d=null;for(;n.nextNode();){a++;const t=n.currentNode;for(t.previousSibling===d&&(d=null),e.has(t)&&(c.push(t),null===d&&(d=t)),null!==d&&l++;void 0!==r&&r.index===a;)r.index=null!==d?-1:r.index-l,o=p(s,o),r=s[o]}c.forEach((t=>t.parentNode.removeChild(t)))}const u=t=>{let e=11===t.nodeType?0:1;const i=document.createTreeWalker(t,133,null,!1);for(;i.nextNode();)e++;return e},p=(t,e=-1)=>{for(let i=e+1;i"function"==typeof t&&f.has(t),_={},v={};class m{constructor(t,e,i){this.__parts=[],this.template=t,this.processor=e,this.options=i}update(t){let e=0;for(const i of this.__parts)void 0!==i&&i.setValue(t[e]),e++;for(const t of this.__parts)void 0!==t&&t.commit()}_clone(){const t=e?this.template.element.content.cloneNode(!0):document.importNode(this.template.element.content,!0),i=[],s=this.template.parts,n=document.createTreeWalker(t,133,null,!1);let o,r=0,a=0,c=n.nextNode();for(;rt}),b=` ${s} `;class w{constructor(t,e,i,s){this.strings=t,this.values=e,this.type=i,this.processor=s}getHTML(){const t=this.strings.length-1;let e="",i=!1;for(let o=0;o-1||i)&&-1===t.indexOf("--\x3e",r+1);const a=d.exec(t);e+=null===a?t+(i?b:n):t.substr(0,a.index)+a[1]+a[2]+"$lit$"+a[3]+s}return e+=this.strings[t],e}getTemplateElement(){const t=document.createElement("template");let e=this.getHTML();return void 0!==y&&(e=y.createHTML(e)),t.innerHTML=e,t}}const S=t=>null===t||!("object"==typeof t||"function"==typeof t),C=t=>Array.isArray(t)||!(!t||!t[Symbol.iterator]);class O{constructor(t,e,i){this.dirty=!0,this.element=t,this.name=e,this.strings=i,this.parts=[];for(let t=0;t{try{const t={get capture(){return N=!0,!1}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){}})();class T{constructor(t,e,i){this.value=void 0,this.__pendingValue=void 0,this.element=t,this.eventName=e,this.eventContext=i,this.__boundHandleEvent=t=>this.handleEvent(t)}setValue(t){this.__pendingValue=t}commit(){for(;g(this.__pendingValue);){const t=this.__pendingValue;this.__pendingValue=_,t(this)}if(this.__pendingValue===_)return;const t=this.__pendingValue,e=this.value,i=null==t||null!=e&&(t.capture!==e.capture||t.once!==e.once||t.passive!==e.passive),s=null!=t&&(null==e||i);i&&this.element.removeEventListener(this.eventName,this.__boundHandleEvent,this.__options),s&&(this.__options=k(t),this.element.addEventListener(this.eventName,this.__boundHandleEvent,this.__options)),this.value=t,this.__pendingValue=_}handleEvent(t){"function"==typeof this.value?this.value.call(this.eventContext||this.element,t):this.value.handleEvent(t)}}const k=t=>t&&(N?{capture:t.capture,passive:t.passive,once:t.once}:t.capture);function A(t){let e=M.get(t.type);void 0===e&&(e={stringsArray:new WeakMap,keyString:new Map},M.set(t.type,e));let i=e.stringsArray.get(t.strings);if(void 0!==i)return i;const n=t.strings.join(s);return i=e.keyString.get(n),void 0===i&&(i=new r(t,t.getTemplateElement()),e.keyString.set(n,i)),e.stringsArray.set(t.strings,i),i}const M=new Map,U=new WeakMap;const F=new class{handleAttributeExpressions(t,e,i,s){const n=e[0];if("."===n){return new j(t,e.slice(1),i).parts}if("@"===n)return[new T(t,e.slice(1),s.eventContext)];if("?"===n)return[new P(t,e.slice(1),i)];return new O(t,e,i).parts}handleTextExpression(t){return new x(t)}};"undefined"!=typeof window&&(window.litHtmlVersions||(window.litHtmlVersions=[])).push("1.3.0");const V=(t,...e)=>new w(t,e,"html",F),I=(t,e)=>`${t}--${e}`;let R=!0;void 0===window.ShadyCSS?R=!1:void 0===window.ShadyCSS.prepareTemplateDom&&(console.warn("Incompatible ShadyCSS version detected. Please update to at least @webcomponents/webcomponentsjs@2.0.2 and @webcomponents/shadycss@1.3.1."),R=!1);const D=t=>e=>{const i=I(e.type,t);let n=M.get(i);void 0===n&&(n={stringsArray:new WeakMap,keyString:new Map},M.set(i,n));let o=n.stringsArray.get(e.strings);if(void 0!==o)return o;const a=e.strings.join(s);if(o=n.keyString.get(a),void 0===o){const i=e.getTemplateElement();R&&window.ShadyCSS.prepareTemplateDom(i,t),o=new r(e,i),n.keyString.set(a,o)}return n.stringsArray.set(e.strings,o),o},q=["html","svg"],W=new Set,G=(t,e,i)=>{W.add(t);const s=i?i.element:document.createElement("template"),n=e.querySelectorAll("style"),{length:o}=n;if(0===o)return void window.ShadyCSS.prepareTemplateStyles(s,t);const r=document.createElement("style");for(let t=0;t{q.forEach((e=>{const i=M.get(I(e,t));void 0!==i&&i.keyString.forEach((t=>{const{element:{content:e}}=t,i=new Set;Array.from(e.querySelectorAll("style")).forEach((t=>{i.add(t)})),h(t,i)}))}))})(t);const a=s.content;i?function(t,e,i=null){const{element:{content:s},parts:n}=t;if(null==i)return void s.appendChild(e);const o=document.createTreeWalker(s,133,null,!1);let r=p(n),a=0,l=-1;for(;o.nextNode();)for(l++,o.currentNode===i&&(a=u(e),i.parentNode.insertBefore(e,i));-1!==r&&n[r].index===l;){if(a>0){for(;-1!==r;)n[r].index+=a,r=p(n,r);return}r=p(n,r)}}(i,r,a.firstChild):a.insertBefore(r,a.firstChild),window.ShadyCSS.prepareTemplateStyles(s,t);const l=a.querySelector("style");if(window.ShadyCSS.nativeShadow&&null!==l)e.insertBefore(l.cloneNode(!0),e.firstChild);else if(i){a.insertBefore(r,a.firstChild);const t=new Set;t.add(r),h(i,t)}};window.JSCompiler_renameProperty=(t,e)=>t;const z={toAttribute(t,e){switch(e){case Boolean:return t?"":null;case Object:case Array:return null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){switch(e){case Boolean:return null!==t;case Number:return null===t?null:Number(t);case Object:case Array:return JSON.parse(t)}return t}},L=(t,e)=>e!==t&&(e==e||t==t),B={attribute:!0,type:String,converter:z,reflect:!1,hasChanged:L};class H extends HTMLElement{constructor(){super(),this.initialize()}static get observedAttributes(){this.finalize();const t=[];return this._classProperties.forEach(((e,i)=>{const s=this._attributeNameForProperty(i,e);void 0!==s&&(this._attributeToPropertyMap.set(s,i),t.push(s))})),t}static _ensureClassProperties(){if(!this.hasOwnProperty(JSCompiler_renameProperty("_classProperties",this))){this._classProperties=new Map;const t=Object.getPrototypeOf(this)._classProperties;void 0!==t&&t.forEach(((t,e)=>this._classProperties.set(e,t)))}}static createProperty(t,e=B){if(this._ensureClassProperties(),this._classProperties.set(t,e),e.noAccessor||this.prototype.hasOwnProperty(t))return;const i="symbol"==typeof t?Symbol():`__${t}`,s=this.getPropertyDescriptor(t,i,e);void 0!==s&&Object.defineProperty(this.prototype,t,s)}static getPropertyDescriptor(t,e,i){return{get(){return this[e]},set(s){const n=this[t];this[e]=s,this.requestUpdateInternal(t,n,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this._classProperties&&this._classProperties.get(t)||B}static finalize(){const t=Object.getPrototypeOf(this);if(t.hasOwnProperty("finalized")||t.finalize(),this.finalized=!0,this._ensureClassProperties(),this._attributeToPropertyMap=new Map,this.hasOwnProperty(JSCompiler_renameProperty("properties",this))){const t=this.properties,e=[...Object.getOwnPropertyNames(t),..."function"==typeof Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(t):[]];for(const i of e)this.createProperty(i,t[i])}}static _attributeNameForProperty(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}static _valueHasChanged(t,e,i=L){return i(t,e)}static _propertyValueFromAttribute(t,e){const i=e.type,s=e.converter||z,n="function"==typeof s?s:s.fromAttribute;return n?n(t,i):t}static _propertyValueToAttribute(t,e){if(void 0===e.reflect)return;const i=e.type,s=e.converter;return(s&&s.toAttribute||z.toAttribute)(t,i)}initialize(){this._updateState=0,this._updatePromise=new Promise((t=>this._enableUpdatingResolver=t)),this._changedProperties=new Map,this._saveInstanceProperties(),this.requestUpdateInternal()}_saveInstanceProperties(){this.constructor._classProperties.forEach(((t,e)=>{if(this.hasOwnProperty(e)){const t=this[e];delete this[e],this._instanceProperties||(this._instanceProperties=new Map),this._instanceProperties.set(e,t)}}))}_applyInstanceProperties(){this._instanceProperties.forEach(((t,e)=>this[e]=t)),this._instanceProperties=void 0}connectedCallback(){this.enableUpdating()}enableUpdating(){void 0!==this._enableUpdatingResolver&&(this._enableUpdatingResolver(),this._enableUpdatingResolver=void 0)}disconnectedCallback(){}attributeChangedCallback(t,e,i){e!==i&&this._attributeToProperty(t,i)}_propertyToAttribute(t,e,i=B){const s=this.constructor,n=s._attributeNameForProperty(t,i);if(void 0!==n){const t=s._propertyValueToAttribute(e,i);if(void 0===t)return;this._updateState=8|this._updateState,null==t?this.removeAttribute(n):this.setAttribute(n,t),this._updateState=-9&this._updateState}}_attributeToProperty(t,e){if(8&this._updateState)return;const i=this.constructor,s=i._attributeToPropertyMap.get(t);if(void 0!==s){const t=i.getPropertyOptions(s);this._updateState=16|this._updateState,this[s]=i._propertyValueFromAttribute(e,t),this._updateState=-17&this._updateState}}requestUpdateInternal(t,e,i){let s=!0;if(void 0!==t){const n=this.constructor;i=i||n.getPropertyOptions(t),n._valueHasChanged(this[t],e,i.hasChanged)?(this._changedProperties.has(t)||this._changedProperties.set(t,e),!0!==i.reflect||16&this._updateState||(void 0===this._reflectingProperties&&(this._reflectingProperties=new Map),this._reflectingProperties.set(t,i))):s=!1}!this._hasRequestedUpdate&&s&&(this._updatePromise=this._enqueueUpdate())}requestUpdate(t,e){return this.requestUpdateInternal(t,e),this.updateComplete}async _enqueueUpdate(){this._updateState=4|this._updateState;try{await this._updatePromise}catch(t){}const t=this.performUpdate();return null!=t&&await t,!this._hasRequestedUpdate}get _hasRequestedUpdate(){return 4&this._updateState}get hasUpdated(){return 1&this._updateState}performUpdate(){if(!this._hasRequestedUpdate)return;this._instanceProperties&&this._applyInstanceProperties();let t=!1;const e=this._changedProperties;try{t=this.shouldUpdate(e),t?this.update(e):this._markUpdated()}catch(e){throw t=!1,this._markUpdated(),e}t&&(1&this._updateState||(this._updateState=1|this._updateState,this.firstUpdated(e)),this.updated(e))}_markUpdated(){this._changedProperties=new Map,this._updateState=-5&this._updateState}get updateComplete(){return this._getUpdateComplete()}_getUpdateComplete(){return this._updatePromise}shouldUpdate(t){return!0}update(t){void 0!==this._reflectingProperties&&this._reflectingProperties.size>0&&(this._reflectingProperties.forEach(((t,e)=>this._propertyToAttribute(e,this[e],t))),this._reflectingProperties=void 0),this._markUpdated()}updated(t){}firstUpdated(t){}}H.finalized=!0;const J=(t,e)=>"method"===e.kind&&e.descriptor&&!("value"in e.descriptor)?Object.assign(Object.assign({},e),{finisher(i){i.createProperty(e.key,t)}}):{kind:"field",key:Symbol(),placement:"own",descriptor:{},initializer(){"function"==typeof e.initializer&&(this[e.key]=e.initializer.call(this))},finisher(i){i.createProperty(e.key,t)}};function K(t){return(e,i)=>void 0!==i?((t,e,i)=>{e.constructor.createProperty(i,t)})(t,e,i):J(t,e)}function Y(t){return K({attribute:!1,hasChanged:null==t?void 0:t.hasChanged})}const Q=(t,e,i)=>{Object.defineProperty(e,i,t)},X=(t,e)=>({kind:"method",placement:"prototype",key:e.key,descriptor:t}),Z=window.ShadowRoot&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,tt=Symbol();class et{constructor(t,e){if(e!==tt)throw new Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t}get styleSheet(){return void 0===this._styleSheet&&(Z?(this._styleSheet=new CSSStyleSheet,this._styleSheet.replaceSync(this.cssText)):this._styleSheet=null),this._styleSheet}toString(){return this.cssText}}const it=(t,...e)=>{const i=e.reduce(((e,i,s)=>e+(t=>{if(t instanceof et)return t.cssText;if("number"==typeof t)return t;throw new Error(`Value passed to 'css' function must be a 'css' function result: ${t}. Use 'unsafeCSS' to pass non-literal values, but\n take care to ensure page security.`)})(i)+t[s+1]),t[0]);return new et(i,tt)};(window.litElementVersions||(window.litElementVersions=[])).push("2.4.0");const st={};class nt extends H{static getStyles(){return this.styles}static _getUniqueStyles(){if(this.hasOwnProperty(JSCompiler_renameProperty("_styles",this)))return;const t=this.getStyles();if(Array.isArray(t)){const e=(t,i)=>t.reduceRight(((t,i)=>Array.isArray(i)?e(i,t):(t.add(i),t)),i),i=e(t,new Set),s=[];i.forEach((t=>s.unshift(t))),this._styles=s}else this._styles=void 0===t?[]:[t];this._styles=this._styles.map((t=>{if(t instanceof CSSStyleSheet&&!Z){const e=Array.prototype.slice.call(t.cssRules).reduce(((t,e)=>t+e.cssText),"");return new et(String(e),tt)}return t}))}initialize(){super.initialize(),this.constructor._getUniqueStyles(),this.renderRoot=this.createRenderRoot(),window.ShadowRoot&&this.renderRoot instanceof window.ShadowRoot&&this.adoptStyles()}createRenderRoot(){return this.attachShadow({mode:"open"})}adoptStyles(){const t=this.constructor._styles;0!==t.length&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow?Z?this.renderRoot.adoptedStyleSheets=t.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet)):this._needsShimAdoptedStyleSheets=!0:window.ShadyCSS.ScopingShim.prepareAdoptedCssText(t.map((t=>t.cssText)),this.localName))}connectedCallback(){super.connectedCallback(),this.hasUpdated&&void 0!==window.ShadyCSS&&window.ShadyCSS.styleElement(this)}update(t){const e=this.render();super.update(t),e!==st&&this.constructor.render(e,this.renderRoot,{scopeName:this.localName,eventContext:this}),this._needsShimAdoptedStyleSheets&&(this._needsShimAdoptedStyleSheets=!1,this.constructor._styles.forEach((t=>{const e=document.createElement("style");e.textContent=t.cssText,this.renderRoot.appendChild(e)})))}render(){return st}}function ot(){return document.querySelector("hc-main")?document.querySelector("hc-main").hass:document.querySelector("home-assistant")?document.querySelector("home-assistant").hass:void 0}nt.finalized=!0,nt.render=(t,e,s)=>{if(!s||"object"!=typeof s||!s.scopeName)throw new Error("The `scopeName` option is required.");const n=s.scopeName,o=U.has(e),r=R&&11===e.nodeType&&!!e.host,a=r&&!W.has(n),l=a?document.createDocumentFragment():e;if(((t,e,s)=>{let n=U.get(e);void 0===n&&(i(e,e.firstChild),U.set(e,n=new x(Object.assign({templateFactory:A},s))),n.appendInto(e)),n.setValue(t),n.commit()})(t,l,Object.assign({templateFactory:D(n)},s)),a){const t=U.get(l);U.delete(l);const s=t.value instanceof m?t.value.template:void 0;G(n,l,s),i(e,e.firstChild),e.appendChild(l),U.set(e,t)}!o&&r&&window.ShadyCSS.styleElement(e.host)};const rt="lovelace-player-device-id";function at(){if(!localStorage[rt]){const t=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);window.fully&&"function"==typeof fully.getDeviceId?localStorage[rt]=fully.getDeviceId():localStorage[rt]=`${t()}${t()}-${t()}${t()}`}return localStorage[rt]}let lt=at();const ct=new URLSearchParams(window.location.search);var dt;function ht(t){return!!String(t).includes("{%")||(!!String(t).includes("{{")||void 0)}ct.get("deviceID")&&null!==(dt=ct.get("deviceID"))&&("clear"===dt?localStorage.removeItem(rt):localStorage[rt]=dt,lt=at()),window.cardMod_template_cache=window.cardMod_template_cache||{};const ut=window.cardMod_template_cache;async function pt(t,e,i){const s=ot().connection,n=JSON.stringify([e,i]);let o=ut[n];o?(o.callbacks.has(t)||ft(t),t(o.value),o.callbacks.add(t)):(ft(t),t(""),i=Object.assign({user:ot().user.name,browser:lt,hash:location.hash.substr(1)||""},i),ut[n]=o={template:e,variables:i,value:"",callbacks:new Set([t]),unsubscribe:s.subscribeMessage((t=>function(t,e){const i=ut[t];i&&(i.value=e.result,i.callbacks.forEach((t=>t(e.result))))}(n,t)),{type:"render_template",template:e,variables:i})})}async function ft(t){let e;for(const[i,s]of Object.entries(ut))if(s.callbacks.has(t)){s.callbacks.delete(t),0==s.callbacks.size&&(e=s.unsubscribe,delete ut[i]);break}e&&await(await e)()}var gt;function _t(t,e){if("string"==typeof e&&"string"==typeof t&&(t.startsWith("/")&&t.endsWith("/")||-1!==t.indexOf("*"))){return t.startsWith("/")||(t=`/^${t=t.replace(/\./g,".").replace(/\*/g,".*")}$/`),new RegExp(t.slice(1,-1)).test(e)}if("string"==typeof t){if(t.startsWith("<="))return parseFloat(e)<=parseFloat(t.substr(2));if(t.startsWith(">="))return parseFloat(e)>=parseFloat(t.substr(2));if(t.startsWith("<"))return parseFloat(e)"))return parseFloat(e)>parseFloat(t.substr(1));if(t.startsWith("!"))return parseFloat(e)!=parseFloat(t.substr(1));if(t.startsWith("="))return parseFloat(e)==parseFloat(t.substr(1))}return t===e}window.autoEntities_cache=null!==(gt=window.autoEntities_cache)&&void 0!==gt?gt:{};const vt=window.autoEntities_cache;async function mt(t){var e;return vt.areas=null!==(e=vt.areas)&&void 0!==e?e:await t.callWS({type:"config/area_registry/list"}),vt.areas}async function yt(t){var e;return vt.devices=null!==(e=vt.devices)&&void 0!==e?e:await t.callWS({type:"config/device_registry/list"}),vt.devices}async function bt(t){var e;return vt.entities=null!==(e=vt.entities)&&void 0!==e?e:await t.callWS({type:"config/entity_registry/list"}),vt.entities}const wt={options:async()=>!0,sort:async()=>!0,domain:async(t,e,i)=>_t(e,i.entity_id.split(".")[0]),entity_id:async(t,e,i)=>_t(e,i.entity_id),state:async(t,e,i)=>_t(e,i.state),name:async(t,e,i)=>{var s;return _t(e,null===(s=i.attributes)||void 0===s?void 0:s.friendly_name)},group:async(t,e,i)=>{var s,n,o;return null===(o=null===(n=null===(s=t.states[e])||void 0===s?void 0:s.attributes)||void 0===n?void 0:n.entity_id)||void 0===o?void 0:o.includes(i.entity_id)},attributes:async(t,e,i)=>{for(const[t,s]of Object.entries(e)){let e=t.split(" ")[0],n=i.attributes;for(const t of e.split(":"))n=n?n[t]:void 0;if(void 0===n||!_t(s,n))return!1}return!0},not:async(t,e,i)=>!await St(t,e,i.entity_id),or:async(t,e,i)=>{for(const s of e)if(await St(t,s,i.entity_id))return!0;return!1},device:async(t,e,i)=>{const s=(await bt(t)).find((t=>t.entity_id===i.entity_id));if(!s)return!1;const n=(await yt(t)).find((t=>t.id===s.device_id));return!!n&&(_t(e,n.name_by_user)||_t(e,n.name))},area:async(t,e,i)=>{const s=(await bt(t)).find((t=>t.entity_id===i.entity_id));if(!s)return!1;let n=(await mt(t)).find((t=>t.area_id===s.area_id));if(n)return _t(e,n.name);const o=(await yt(t)).find((t=>t.id===s.device_id));return!!o&&(n=(await mt(t)).find((t=>t.area_id===o.area_id)),!!n&&_t(e,n.name))},last_changed:async(t,e,i)=>_t(e,((new Date).getTime()-new Date(i.last_changed).getTime())/6e4),last_updated:async(t,e,i)=>_t(e,((new Date).getTime()-new Date(i.last_updated).getTime())/6e4),last_triggered:async(t,e,i)=>{if(null==i.attributes.last_triggered)return!1;return _t(e,((new Date).getTime()-new Date(i.attributes.last_triggered).getTime())/6e4)}};async function St(t,e,i){var s;if(!t.states[i])return!1;for(let[n,o]of Object.entries(e))if(n=n.trim().split(" ")[0].trim(),!await(null===(s=wt[n])||void 0===s?void 0:s.call(wt,t,o,t.states[i])))return!1;return!0}function Ct(t,e,i){var s,n,o,r;const[a,l]=i.reverse?[-1,1]:[1,-1];return i.ignore_case&&(t=null!==(n=null===(s=null==t?void 0:t.toLowerCase)||void 0===s?void 0:s.call(t))&&void 0!==n?n:t,e=null!==(r=null===(o=null==e?void 0:e.toLowerCase)||void 0===o?void 0:o.call(e))&&void 0!==r?r:e),i.numeric&&(isNaN(parseFloat(t))&&isNaN(parseFloat(e))||(t=isNaN(parseFloat(t))?void 0:parseFloat(t),e=isNaN(parseFloat(e))?void 0:parseFloat(e))),void 0===t&&void 0===e?0:void 0===t?a:void 0===e?l:(i.reverse?-1:1)*String(t).localeCompare(String(e),void 0,i)}const Ot={none:()=>0,domain:(t,e,i)=>{var s,n;return Ct(null===(s=null==t?void 0:t.entity_id)||void 0===s?void 0:s.split(".")[0],null===(n=null==e?void 0:e.entity_id)||void 0===n?void 0:n.split(".")[0],i)},entity_id:(t,e,i)=>Ct(null==t?void 0:t.entity_id,null==e?void 0:e.entity_id,i),friendly_name:(t,e,i)=>{var s,n,o,r;return Ct((null===(s=null==t?void 0:t.attributes)||void 0===s?void 0:s.friendly_name)||(null===(n=null==t?void 0:t.entity_id)||void 0===n?void 0:n.split(".")[1]),(null===(o=null==e?void 0:e.attributes)||void 0===o?void 0:o.friendly_name)||(null===(r=null==e?void 0:e.entity_id)||void 0===r?void 0:r.split(".")[1]),i)},name:(t,e,i)=>{var s,n,o,r;return Ct((null===(s=null==t?void 0:t.attributes)||void 0===s?void 0:s.friendly_name)||(null===(n=null==t?void 0:t.entity_id)||void 0===n?void 0:n.split(".")[1]),(null===(o=null==e?void 0:e.attributes)||void 0===o?void 0:o.friendly_name)||(null===(r=null==e?void 0:e.entity_id)||void 0===r?void 0:r.split(".")[1]),i)},state:(t,e,i)=>Ct(null==t?void 0:t.state,null==e?void 0:e.state,i),attribute:(t,e,i)=>{var s;const[n,o]=(null==i?void 0:i.reverse)?[-1,1]:[1,-1];let r=null==t?void 0:t.attributes,a=null==e?void 0:e.attributes;for(const t of null===(s=null==i?void 0:i.attribute)||void 0===s?void 0:s.split(":")){if(void 0===r&&void 0===a)return 0;if(void 0===r)return n;if(void 0===a)return o;[r,a]=[r[t],a[t]]}return Ct(r,a,i)},last_changed:(t,e,i)=>{const[s,n]=(null==i?void 0:i.reverse)?[-1,1]:[1,-1];return null==(null==t?void 0:t.last_changed)&&null==(null==e?void 0:e.last_changed)?0:null==(null==t?void 0:t.last_changed)?s:null==(null==e?void 0:e.last_changed)?n:(i.numeric=!0,Ct(new Date(null==t?void 0:t.last_changed).getTime(),new Date(null==e?void 0:e.last_changed).getTime(),i))},last_updated:(t,e,i)=>{const[s,n]=(null==i?void 0:i.reverse)?[-1,1]:[1,-1];return null==(null==t?void 0:t.last_updated)&&null==(null==e?void 0:e.last_updated)?0:null==(null==t?void 0:t.last_updated)?s:null==(null==e?void 0:e.last_updated)?n:(i.numeric=!0,Ct(new Date(null==t?void 0:t.last_updated).getTime(),new Date(null==e?void 0:e.last_updated).getTime(),i))},last_triggered:(t,e,i)=>{var s,n,o,r,a,l;const[c,d]=(null==i?void 0:i.reverse)?[-1,1]:[1,-1];return null==(null===(s=null==t?void 0:t.attributes)||void 0===s?void 0:s.last_triggered)&&null==(null===(n=null==e?void 0:e.attributes)||void 0===n?void 0:n.last_triggered)?0:null==(null===(o=null==t?void 0:t.attributes)||void 0===o?void 0:o.last_triggered)?c:null==(null===(r=null==e?void 0:e.attributes)||void 0===r?void 0:r.last_triggered)?d:(i.numeric=!0,Ct(new Date(null===(a=null==t?void 0:t.attributes)||void 0===a?void 0:a.last_triggered).getTime(),new Date(null===(l=null==e?void 0:e.attributes)||void 0===l?void 0:l.last_triggered).getTime(),i))}};function Et(t,e){return function(i,s){var n,o;return null!==(o=null===(n=Ot[e.method])||void 0===n?void 0:n.call(Ot,t.states[i.entity],t.states[s.entity],e))&&void 0!==o?o:0}}var xt="1.9.1";const Pt=["domain","entity_id","state","name","group","device","area","last_changed","last_updated","last_triggered"],jt=["none","domain","entity_id","friendly_name","state","last_changed","last_updated","last_triggered"];class $t extends nt{constructor(){super(...arguments),this._selectedTab=0,this._cardGUIMode=!0,this._cardGUIModeAvailable=!0}setConfig(t){this._config=t}_handleSwitchTab(t){this._selectedTab=parseInt(t.detail.index,10)}_addFilterGroup(){var t;if(!this._config)return;const e=[...null===(t=this._config.filter)||void 0===t?void 0:t.include];e.push({domain:""});const i=Object.assign(Object.assign({},this._config.filter),{include:e});this._config=Object.assign(Object.assign({},this._config),{filter:i}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_deleteFilterGroup(t){var e;if(!this._config)return;const i=[...null===(e=this._config.filter)||void 0===e?void 0:e.include];i.splice(t,1);const s=Object.assign(Object.assign({},this._config.filter),{include:i});this._config=Object.assign(Object.assign({},this._config),{filter:s}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_moveFilterGroup(t,e){var i;if(!this._config)return;const s=[...null===(i=this._config.filter)||void 0===i?void 0:i.include];[s[t],s[t+e]]=[s[t+e],s[t]];const n=Object.assign(Object.assign({},this._config.filter),{include:s});this._config=Object.assign(Object.assign({},this._config),{filter:n}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_addSpecialEntry(){var t;if(!this._config)return;const e=[...null===(t=this._config.filter)||void 0===t?void 0:t.include];e.push({type:""});const i=Object.assign(Object.assign({},this._config.filter),{include:e});this._config=Object.assign(Object.assign({},this._config),{filter:i}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}async _changeSpecialEntry(t,e){var i;if(!this._config)return;const s=[...null===(i=this._config.filter)||void 0===i?void 0:i.include];s[t]=e.detail.value;const n=Object.assign(Object.assign({},this._config.filter),{include:s});this._config=Object.assign(Object.assign({},this._config),{filter:n}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}async _changeGroupOptions(t,e){var i;if(!this._config)return;const s=e.detail.value,n=[...null===(i=this._config.filter)||void 0===i?void 0:i.include];n[t]=Object.assign(Object.assign({},n[t]),{options:s});const o=Object.assign(Object.assign({},this._config.filter),{include:n});this._config=Object.assign(Object.assign({},this._config),{filter:o}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_addFilter(t){var e;if(!this._config)return;const i=Pt.find((e=>void 0===this._config.filter.include[t][e]));if(void 0===i)return;const s=[...null===(e=this._config.filter)||void 0===e?void 0:e.include];s[t]=Object.assign(Object.assign({},s[t]),{[i]:""});const n=Object.assign(Object.assign({},this._config.filter),{include:s});this._config=Object.assign(Object.assign({},this._config),{filter:n}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_removeFilter(t,e){var i;if(!this._config)return;const s=[...null===(i=this._config.filter)||void 0===i?void 0:i.include],n=Object.assign({},s[t]);if(delete n[e],0===Object.keys(n).length)return this._deleteFilterGroup(t);s[t]=n;const o=Object.assign(Object.assign({},this._config.filter),{include:s});this._config=Object.assign(Object.assign({},this._config),{filter:o}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_changeFilterKey(t,e,i){var s;if(!this._config)return;const n=Pt[i.target.selected];if(void 0===n||n===e)return;const o=[...null===(s=this._config.filter)||void 0===s?void 0:s.include],r=Object.assign({},o[t]);if(void 0===r[e])return;r[n]=r[e],delete r[e],o[t]=r;const a=Object.assign(Object.assign({},this._config.filter),{include:o});this._config=Object.assign(Object.assign({},this._config),{filter:a}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_changeFilterValue(t,e,i){var s;if(!this._config)return;const n=[...null===(s=this._config.filter)||void 0===s?void 0:s.include],o=Object.assign({},n[t]);o[e]=i.target.value,n[t]=o;const r=Object.assign(Object.assign({},this._config.filter),{include:n});this._config=Object.assign(Object.assign({},this._config),{filter:r}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_changeSortMethod(t){if(!this._config)return;const e=jt[t.target.selected],i=Object.assign(Object.assign({},this._config.sort),{method:e});this._config=Object.assign(Object.assign({},this._config),{sort:i}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_sortOptionToggle(t,e){if(!this._config)return;const i=Object.assign({},this._config.sort);i[t]=e.target.checked,this._config=Object.assign(Object.assign({},this._config),{sort:i}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_showEmptyToggle(){if(!this._config)return;const t=!1===this._config.show_empty;this._config=Object.assign(Object.assign({},this._config),{show_empty:t}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_changeCardParam(t){if(!this._config)return;const e=""===t.target.value||"entities"===t.target.value?void 0:t.target.value;this._config=Object.assign(Object.assign({},this._config),{card_param:e}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_getCardConfig(){const t=Object.assign({},this._config.card);return t[this._config.card_param||"entities"]=[],t}_handleCardPicked(t){if(t.stopPropagation(),!this._config)return;const e=Object.assign({},t.detail.config);delete e.entities,this._config=Object.assign(Object.assign({},this._config),{card:e}),this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_handleCardConfigChanged(t){if(t.stopPropagation(),!this._config)return;const e=Object.assign({},t.detail.config);delete e[this._config.card_param||"entities"],this._config=Object.assign(Object.assign({},this._config),{card:e}),this._cardGUIModeAvailable=t.detail.guiModeAvailable,this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}}))}_deleteCard(t){this._config&&(this._config=Object.assign({},this._config),delete this._config.card,this.dispatchEvent(new CustomEvent("config-changed",{detail:{config:this._config}})))}_toggleCardMode(t){var e;null===(e=this._cardEditorEl)||void 0===e||e.toggleMode()}_cardGUIModeChanged(t){t.stopPropagation(),this._cardGUIMode=t.detail.guiMode,this._cardGUIModeAvailable=t.detail.guiModeAvailable}render(){return this.hass&&this._config?V`
2 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | ${[this._renderFilterEditor,this._renderSortEditor,this._renderCardEditor][this._selectedTab].bind(this)()}
15 |
16 |
17 | `:V``}_renderFilterEditor(){var t;return(null===(t=this._config.filter)||void 0===t?void 0:t.template)||this._config.entities?V`
18 |
19 |
20 | Your filter method is not handled by the GUI editor.
21 |
22 |
Please switch to the CODE EDITOR to access all options.
23 |
24 | `:V`
25 | ${this._config.filter.include.map(((t,e)=>V`
26 |
27 |
28 | this._moveFilterGroup(e,-1)}
31 | >
32 |
33 |
34 | this._moveFilterGroup(e,1)}
37 | >
38 |
39 |
40 | this._deleteFilterGroup(e)}
42 | >
43 |
44 |
45 |
46 | ${void 0===t.type?V`
47 | ${Object.entries(t).map((([t,i],s)=>V`
48 | ${Pt.includes(t)?V`
49 |
50 |
51 | this._changeFilterKey(e,t,i)}
55 | >
56 | ${Pt.map((t=>V` ${t} `))}
57 |
58 |
59 |
this._changeFilterValue(e,t,i)}
62 | >
63 | this._removeFilter(e,t)}
66 | >
67 |
68 |
69 |
70 |
71 | `:"options"===t?V``:V`
Some filters are not shown
72 |
73 | Please switch to the CODE EDITOR to access all
74 | options.
75 |
`}
76 | `))}
77 |
this._addFilter(e)}>
78 | Add filter
79 |
80 |
this._changeGroupOptions(e,t)}
85 | >
86 | `:V`
this._changeSpecialEntry(e,t)}
90 | > `}
91 |
92 | `))}
93 |
94 | Add filter group
95 |
96 |
97 | Add non-filter entry
98 |
99 | `}_renderSortEditor(){var t,e,i,s,n;return V`
100 |
101 | ${(null===(t=this._config.sort)||void 0===t?void 0:t.method)&&!jt.includes(this._config.sort.method)?V`
102 | Your sort method is not handled by the GUI editor.
103 |
104 |
Please switch to the CODE EDITOR to access all options.
`:V`
105 | Method:
106 |
107 |
112 | ${jt.map((t=>V` ${t} `))}
113 |
114 |
115 |
116 |
117 | this._sortOptionToggle("reverse",t)}
120 | >
121 |
122 |
123 |
124 |
125 | this._sortOptionToggle("numeric",t)}
128 | >
129 |
130 |
131 | `}
132 |
133 | `}_renderCardEditor(){var t;return V`
134 |
135 |
136 |
140 |
141 |
146 |
147 | ${this._config.card?V`
148 |
149 |
154 | ${!this._cardEditorEl||this._cardGUIMode?"Show code editor":"Show Visual Editor"}
155 |
156 |
160 |
161 |
162 |
163 |
170 | `:V`
171 |
176 | `}
177 |
178 | `}static get styles(){return[it`
179 | mwc-tab-bar {
180 | border-bottom: 1px solid var(--divider-color);
181 | }
182 |
183 | .filter,
184 | .card {
185 | margin-top: 8px;
186 | border: 1px solid var(--divider-color);
187 | padding: 12px;
188 | }
189 | .filter .option {
190 | display: flex;
191 | align-items: flex-end;
192 | }
193 | .filter .option paper-dropdown-menu {
194 | margin-right: 16px;
195 | width: 150px;
196 | }
197 | .filter .option paper-input {
198 | flex-grow: 2;
199 | }
200 |
201 | .filter .toolbar,
202 | .card .card-options {
203 | display: flex;
204 | justify-content: flex-end;
205 | width: 100%;
206 | }
207 | .gui-mode-button {
208 | margin-right: auto;
209 | }
210 | `]}}function Nt(t,e){if(t===e)return!0;if(typeof t!=typeof e)return!1;if(!(t instanceof Object&&e instanceof Object))return!1;for(const i in t)if(t.hasOwnProperty(i)){if(!e.hasOwnProperty(i))return!1;if(t[i]!==e[i]){if("object"!=typeof t[i])return!1;if(!Nt(t[i],e[i]))return!1}}for(const i in e)if(e.hasOwnProperty(i)&&!t.hasOwnProperty(i))return!1;return!0}t([Y()],$t.prototype,"_config",void 0),t([K()],$t.prototype,"lovelace",void 0),t([K()],$t.prototype,"hass",void 0),t([Y()],$t.prototype,"_selectedTab",void 0),t([Y()],$t.prototype,"_cardGUIMode",void 0),t([Y()],$t.prototype,"_cardGUIModeAvailable",void 0),t([function(t,e){return(i,s)=>{const n={get(){return this.renderRoot.querySelector(t)},enumerable:!0,configurable:!0};if(e){const e="symbol"==typeof s?Symbol():`__${s}`;n.get=function(){return void 0===this[e]&&(this[e]=this.renderRoot.querySelector(t)),this[e]}}return void 0!==s?Q(n,i,s):X(n,i)}}("hui-card-element-editor")],$t.prototype,"_cardEditorEl",void 0),customElements.define("auto-entities-editor",$t),window.customCards=window.customCards||[],window.customCards.push({type:"auto-entities",name:"Auto Entities",preview:!1,description:"Entity Filter on Steroids. Auto Entities allows you to fill other cards with entities automatically, based on a number of attributes."}),window.queueMicrotask=window.queueMicrotask||(t=>window.setTimeout(t,1));class Tt extends nt{constructor(){super(...arguments),this._updateCooldown={timer:void 0,rerun:!1},this._renderer=t=>{this._template="string"==typeof t?t.split(/[\s,]+/):t}}static getConfigElement(){return document.createElement("auto-entities-editor")}static getStubConfig(){return{card:{type:"entities"},filter:{include:[],exclude:[]}}}setConfig(t){var e,i;if(!t)throw new Error("No configuration.");if(!(null===(e=t.card)||void 0===e?void 0:e.type))throw new Error("No card type specified.");if(!t.filter&&!t.entities)throw new Error("No filters specified.");t=JSON.parse(JSON.stringify(t)),this._config=t,(null===(i=this._config.filter)||void 0===i?void 0:i.template)&&ht(this._config.filter.template)&&pt(this._renderer,this._config.filter.template,{config:t}),this._cardBuilt=new Promise((t=>this._cardBuiltResolve=t)),queueMicrotask((()=>this.update_all()))}connectedCallback(){var t,e;super.connectedCallback(),(null===(e=null===(t=this._config)||void 0===t?void 0:t.filter)||void 0===e?void 0:e.template)&&ht(this._config.filter.template)&&pt(this._renderer,this._config.filter.template,{config:this._config})}disconnectedCallback(){super.disconnectedCallback(),ft(this._renderer)}async update_all(){if(this.card&&(this.card.hass=this.hass),this._updateCooldown.timer)return void(this._updateCooldown.rerun=!0);this._updateCooldown.rerun=!1,this._updateCooldown.timer=window.setTimeout((()=>{this._updateCooldown.timer=void 0,this._updateCooldown.rerun&&this.update_all()}),500);const t=await this.update_entities();this.update_card(t)}async update_card(t){var e,i,s;if(this._entities&&Nt(t,this._entities)&&Nt(this._cardConfig,this._config.card))return;const n=(null===(e=this._cardConfig)||void 0===e?void 0:e.type)!==this._config.card.type;this._entities=t,this._cardConfig=JSON.parse(JSON.stringify(this._config.card));const o=Object.assign({[this._config.card_param||"entities"]:t},this._config.card);if(!this.card||n){const t=await window.loadCardHelpers(),e=console.error;let s=!1;if(console.error=(...t)=>{var i,n,o,r,a,l;3===t.length&&t[2].message&&((null===(n=(i=t[2].message).startsWith)||void 0===n?void 0:n.call(i,"Entities"))||(null===(r=(o=t[2].message).startsWith)||void 0===r?void 0:r.call(o,"Either entities"))||(null===(l=(a=t[2].message).endsWith)||void 0===l?void 0:l.call(a,"entity")))?s=!0:e(...t)},this.card=await t.createCardElement(o),console.error=e,s)return this.card=void 0,this._entities=void 0,this._cardConfig=void 0,void(null===(i=this._cardBuiltResolve)||void 0===i||i.call(this))}else this.card.setConfig(o);null===(s=this._cardBuiltResolve)||void 0===s||s.call(this),this.card.hass=this.hass;const r=0===t.length&&!1===this._config.show_empty;this.style.display=r?"none":null,this.style.margin=r?"0":null,this.card.requestUpdate&&(await this.updateComplete,this.card.requestUpdate())}async update_entities(){var t,e,i,s,n,o;const r=t=>t?"string"==typeof t?{entity:t.trim()}:t:null;let a=[...(null===(e=null===(t=this._config)||void 0===t?void 0:t.entities)||void 0===e?void 0:e.map(r))||[]];if(!this.hass)return a;if(this._template&&(a=a.concat(this._template.map(r))),a=a.filter(Boolean),null===(i=this._config.filter)||void 0===i?void 0:i.include){const t=Object.keys(this.hass.states).map(r);for(const e of this._config.filter.include){if(e.type){a.push(e);continue}let i=[];for(const s of t)await St(this.hass,e,s.entity)&&i.push(JSON.parse(JSON.stringify(Object.assign(Object.assign({},s),e.options)).replace(/this.entity_id/g,s.entity)));if(e.sort&&(i=i.sort(Et(this.hass,e.sort)),e.sort.count)){const t=null!==(s=e.sort.first)&&void 0!==s?s:0;i=i.slice(t,t+e.sort.count)}a=a.concat(i)}}if(null===(n=this._config.filter)||void 0===n?void 0:n.exclude)for(const t of this._config.filter.exclude){const e=[];for(const i of a)void 0!==i.entity&&await St(this.hass,t,i.entity)||e.push(i);a=e}if(this._config.sort&&(a=a.sort(Et(this.hass,this._config.sort)),this._config.sort.count)){const t=null!==(o=this._config.sort.first)&&void 0!==o?o:0;a=a.slice(t,t+this._config.sort.count)}if(this._config.unique){let t=[];for(const e of a)"entity"===this._config.unique&&e.entity&&t.some((t=>t.entity===e.entity))||t.some((t=>Nt(t,e)))||t.push(e);a=t}return a}async updated(t){(t.has("_template")||t.has("hass")&&this.hass)&&queueMicrotask((()=>this.update_all()))}createRenderRoot(){return this}render(){return V`${this.card}`}async getCardSize(){var t,e;let i=0;return await this._cardBuilt,this.card&&this.card.getCardSize&&(i=await this.card.getCardSize()),1===i&&(null===(t=this._entities)||void 0===t?void 0:t.length)&&(i=this._entities.length),0===i&&(null===(e=this._config.filter)||void 0===e?void 0:e.include)&&(i=Object.keys(this._config.filter.include).length),i||5}}t([K()],Tt.prototype,"_config",void 0),t([K()],Tt.prototype,"hass",void 0),t([K()],Tt.prototype,"card",void 0),t([K()],Tt.prototype,"_template",void 0),customElements.get("auto-entities")||(customElements.define("auto-entities",Tt),console.info(`%cAUTO-ENTITIES ${xt} IS INSTALLED`,"color: green; font-weight: bold",""));
211 |
--------------------------------------------------------------------------------
/www/community/lovelace-auto-entities/auto-entities.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/lovelace-auto-entities/auto-entities.js.gz
--------------------------------------------------------------------------------
/www/community/lovelace-auto-entities/rollup.config.js:
--------------------------------------------------------------------------------
1 | import nodeResolve from "@rollup/plugin-node-resolve";
2 | import json from "@rollup/plugin-json";
3 | import typescript from "rollup-plugin-typescript2";
4 | import { terser } from "rollup-plugin-terser";
5 | import babel from "@rollup/plugin-babel";
6 |
7 | const dev = process.env.ROLLUP_WATCH;
8 |
9 | export default {
10 | input: "src/main.ts",
11 | output: {
12 | file: "auto-entities.js",
13 | format: "es",
14 | },
15 | plugins: [
16 | nodeResolve(),
17 | json(),
18 | typescript(),
19 | babel({
20 | exclude: "node_modules/**",
21 | }),
22 | !dev && terser({ format: { comments: false } }),
23 | ],
24 | };
25 |
--------------------------------------------------------------------------------
/www/community/lovelace-auto-entities/rollup.config.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/lovelace-auto-entities/rollup.config.js.gz
--------------------------------------------------------------------------------
/www/community/lovelace-card-mod/card-mod.js:
--------------------------------------------------------------------------------
1 | function e(){return document.querySelector("hc-main")?document.querySelector("hc-main").hass:document.querySelector("home-assistant")?document.querySelector("home-assistant").hass:void 0}function t(e,t,s=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},s)s.dispatchEvent(e);else{var n=function(){var e=document.querySelector("hc-main");return e?(e=(e=(e=e&&e.shadowRoot)&&e.querySelector("hc-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-view")||e.querySelector("hui-panel-view"):(e=(e=(e=(e=(e=(e=(e=(e=(e=(e=(e=(e=document.querySelector("home-assistant"))&&e.shadowRoot)&&e.querySelector("home-assistant-main"))&&e.shadowRoot)&&e.querySelector("app-drawer-layout partial-panel-resolver"))&&e.shadowRoot||e)&&e.querySelector("ha-panel-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-root"))&&e.shadowRoot)&&e.querySelector("ha-app-layout"))&&e.querySelector("#view"))&&e.firstElementChild}();n&&n.dispatchEvent(e)}}const s="undefined"!=typeof window&&null!=window.customElements&&void 0!==window.customElements.polyfillWrapFlushCallback,n=(e,t,s=null)=>{for(;t!==s;){const s=t.nextSibling;e.removeChild(t),t=s}},o=`{{lit-${String(Math.random()).slice(2)}}}`,i=`\x3c!--${o}--\x3e`,r=new RegExp(`${o}|${i}`);class a{constructor(e,t){this.parts=[],this.element=t;const s=[],n=[],i=document.createTreeWalker(t.content,133,null,!1);let a=0,l=-1,u=0;const{strings:p,values:{length:m}}=e;for(;u0;){const t=p[u],s=h.exec(t)[2],n=s.toLowerCase()+"$lit$",o=e.getAttribute(n);e.removeAttribute(n);const i=o.split(r);this.parts.push({type:"attribute",index:l,name:s,strings:i}),u+=i.length-1}}"TEMPLATE"===e.tagName&&(n.push(e),i.currentNode=e.content)}else if(3===e.nodeType){const t=e.data;if(t.indexOf(o)>=0){const n=e.parentNode,o=t.split(r),i=o.length-1;for(let t=0;t{const s=e.length-t.length;return s>=0&&e.slice(s)===t},l=e=>-1!==e.index,c=()=>document.createComment(""),h=/([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;function u(e,t){const{element:{content:s},parts:n}=e,o=document.createTreeWalker(s,133,null,!1);let i=m(n),r=n[i],a=-1,d=0;const l=[];let c=null;for(;o.nextNode();){a++;const e=o.currentNode;for(e.previousSibling===c&&(c=null),t.has(e)&&(l.push(e),null===c&&(c=e)),null!==c&&d++;void 0!==r&&r.index===a;)r.index=null!==c?-1:r.index-d,i=m(n,i),r=n[i]}l.forEach((e=>e.parentNode.removeChild(e)))}const p=e=>{let t=11===e.nodeType?0:1;const s=document.createTreeWalker(e,133,null,!1);for(;s.nextNode();)t++;return t},m=(e,t=-1)=>{for(let s=t+1;s"function"==typeof e&&f.has(e),_={},g={};class v{constructor(e,t,s){this.__parts=[],this.template=e,this.processor=t,this.options=s}update(e){let t=0;for(const s of this.__parts)void 0!==s&&s.setValue(e[t]),t++;for(const e of this.__parts)void 0!==e&&e.commit()}_clone(){const e=s?this.template.element.content.cloneNode(!0):document.importNode(this.template.element.content,!0),t=[],n=this.template.parts,o=document.createTreeWalker(e,133,null,!1);let i,r=0,a=0,d=o.nextNode();for(;re}),S=` ${o} `;class b{constructor(e,t,s,n){this.strings=e,this.values=t,this.type=s,this.processor=n}getHTML(){const e=this.strings.length-1;let t="",s=!1;for(let n=0;n-1||s)&&-1===e.indexOf("--\x3e",r+1);const a=h.exec(e);t+=null===a?e+(s?S:i):e.substr(0,a.index)+a[1]+a[2]+"$lit$"+a[3]+o}return t+=this.strings[e],t}getTemplateElement(){const e=document.createElement("template");let t=this.getHTML();return void 0!==w&&(t=w.createHTML(t)),e.innerHTML=t,e}}const E=e=>null===e||!("object"==typeof e||"function"==typeof e),C=e=>Array.isArray(e)||!(!e||!e[Symbol.iterator]);class N{constructor(e,t,s){this.dirty=!0,this.element=e,this.name=t,this.strings=s,this.parts=[];for(let e=0;e{try{const e={get capture(){return M=!0,!1}};window.addEventListener("test",e,e),window.removeEventListener("test",e,e)}catch(e){}})();class U{constructor(e,t,s){this.value=void 0,this.__pendingValue=void 0,this.element=e,this.eventName=t,this.eventContext=s,this.__boundHandleEvent=e=>this.handleEvent(e)}setValue(e){this.__pendingValue=e}commit(){for(;y(this.__pendingValue);){const e=this.__pendingValue;this.__pendingValue=_,e(this)}if(this.__pendingValue===_)return;const e=this.__pendingValue,t=this.value,s=null==e||null!=t&&(e.capture!==t.capture||e.once!==t.once||e.passive!==t.passive),n=null!=e&&(null==t||s);s&&this.element.removeEventListener(this.eventName,this.__boundHandleEvent,this.__options),n&&(this.__options=R(e),this.element.addEventListener(this.eventName,this.__boundHandleEvent,this.__options)),this.value=e,this.__pendingValue=_}handleEvent(e){"function"==typeof this.value?this.value.call(this.eventContext||this.element,e):this.value.handleEvent(e)}}const R=e=>e&&(M?{capture:e.capture,passive:e.passive,once:e.once}:e.capture);function k(e){let t=$.get(e.type);void 0===t&&(t={stringsArray:new WeakMap,keyString:new Map},$.set(e.type,t));let s=t.stringsArray.get(e.strings);if(void 0!==s)return s;const n=e.strings.join(o);return s=t.keyString.get(n),void 0===s&&(s=new a(e,e.getTemplateElement()),t.keyString.set(n,s)),t.stringsArray.set(e.strings,s),s}const $=new Map,D=new WeakMap;const V=new class{handleAttributeExpressions(e,t,s,n){const o=t[0];if("."===o){return new A(e,t.slice(1),s).parts}if("@"===o)return[new U(e,t.slice(1),n.eventContext)];if("?"===o)return[new T(e,t.slice(1),s)];return new N(e,t,s).parts}handleTextExpression(e){return new x(e)}};"undefined"!=typeof window&&(window.litHtmlVersions||(window.litHtmlVersions=[])).push("1.3.0");const q=(e,...t)=>new b(e,t,"html",V),L=(e,t)=>`${e}--${t}`;let I=!0;void 0===window.ShadyCSS?I=!1:void 0===window.ShadyCSS.prepareTemplateDom&&(console.warn("Incompatible ShadyCSS version detected. Please update to at least @webcomponents/webcomponentsjs@2.0.2 and @webcomponents/shadycss@1.3.1."),I=!1);const j=e=>t=>{const s=L(t.type,e);let n=$.get(s);void 0===n&&(n={stringsArray:new WeakMap,keyString:new Map},$.set(s,n));let i=n.stringsArray.get(t.strings);if(void 0!==i)return i;const r=t.strings.join(o);if(i=n.keyString.get(r),void 0===i){const s=t.getTemplateElement();I&&window.ShadyCSS.prepareTemplateDom(s,e),i=new a(t,s),n.keyString.set(r,i)}return n.stringsArray.set(t.strings,i),i},z=["html","svg"],H=new Set,J=(e,t,s)=>{H.add(e);const n=s?s.element:document.createElement("template"),o=t.querySelectorAll("style"),{length:i}=o;if(0===i)return void window.ShadyCSS.prepareTemplateStyles(n,e);const r=document.createElement("style");for(let e=0;e{z.forEach((t=>{const s=$.get(L(t,e));void 0!==s&&s.keyString.forEach((e=>{const{element:{content:t}}=e,s=new Set;Array.from(t.querySelectorAll("style")).forEach((e=>{s.add(e)})),u(e,s)}))}))})(e);const a=n.content;s?function(e,t,s=null){const{element:{content:n},parts:o}=e;if(null==s)return void n.appendChild(t);const i=document.createTreeWalker(n,133,null,!1);let r=m(o),a=0,d=-1;for(;i.nextNode();)for(d++,i.currentNode===s&&(a=p(t),s.parentNode.insertBefore(t,s));-1!==r&&o[r].index===d;){if(a>0){for(;-1!==r;)o[r].index+=a,r=m(o,r);return}r=m(o,r)}}(s,r,a.firstChild):a.insertBefore(r,a.firstChild),window.ShadyCSS.prepareTemplateStyles(n,e);const d=a.querySelector("style");if(window.ShadyCSS.nativeShadow&&null!==d)t.insertBefore(d.cloneNode(!0),t.firstChild);else if(s){a.insertBefore(r,a.firstChild);const e=new Set;e.add(r),u(s,e)}};window.JSCompiler_renameProperty=(e,t)=>e;const F={toAttribute(e,t){switch(t){case Boolean:return e?"":null;case Object:case Array:return null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){switch(t){case Boolean:return null!==e;case Number:return null===e?null:Number(e);case Object:case Array:return JSON.parse(e)}return e}},B=(e,t)=>t!==e&&(t==t||e==e),W={attribute:!0,type:String,converter:F,reflect:!1,hasChanged:B};class Y extends HTMLElement{constructor(){super(),this.initialize()}static get observedAttributes(){this.finalize();const e=[];return this._classProperties.forEach(((t,s)=>{const n=this._attributeNameForProperty(s,t);void 0!==n&&(this._attributeToPropertyMap.set(n,s),e.push(n))})),e}static _ensureClassProperties(){if(!this.hasOwnProperty(JSCompiler_renameProperty("_classProperties",this))){this._classProperties=new Map;const e=Object.getPrototypeOf(this)._classProperties;void 0!==e&&e.forEach(((e,t)=>this._classProperties.set(t,e)))}}static createProperty(e,t=W){if(this._ensureClassProperties(),this._classProperties.set(e,t),t.noAccessor||this.prototype.hasOwnProperty(e))return;const s="symbol"==typeof e?Symbol():`__${e}`,n=this.getPropertyDescriptor(e,s,t);void 0!==n&&Object.defineProperty(this.prototype,e,n)}static getPropertyDescriptor(e,t,s){return{get(){return this[t]},set(n){const o=this[e];this[t]=n,this.requestUpdateInternal(e,o,s)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this._classProperties&&this._classProperties.get(e)||W}static finalize(){const e=Object.getPrototypeOf(this);if(e.hasOwnProperty("finalized")||e.finalize(),this.finalized=!0,this._ensureClassProperties(),this._attributeToPropertyMap=new Map,this.hasOwnProperty(JSCompiler_renameProperty("properties",this))){const e=this.properties,t=[...Object.getOwnPropertyNames(e),..."function"==typeof Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e):[]];for(const s of t)this.createProperty(s,e[s])}}static _attributeNameForProperty(e,t){const s=t.attribute;return!1===s?void 0:"string"==typeof s?s:"string"==typeof e?e.toLowerCase():void 0}static _valueHasChanged(e,t,s=B){return s(e,t)}static _propertyValueFromAttribute(e,t){const s=t.type,n=t.converter||F,o="function"==typeof n?n:n.fromAttribute;return o?o(e,s):e}static _propertyValueToAttribute(e,t){if(void 0===t.reflect)return;const s=t.type,n=t.converter;return(n&&n.toAttribute||F.toAttribute)(e,s)}initialize(){this._updateState=0,this._updatePromise=new Promise((e=>this._enableUpdatingResolver=e)),this._changedProperties=new Map,this._saveInstanceProperties(),this.requestUpdateInternal()}_saveInstanceProperties(){this.constructor._classProperties.forEach(((e,t)=>{if(this.hasOwnProperty(t)){const e=this[t];delete this[t],this._instanceProperties||(this._instanceProperties=new Map),this._instanceProperties.set(t,e)}}))}_applyInstanceProperties(){this._instanceProperties.forEach(((e,t)=>this[t]=e)),this._instanceProperties=void 0}connectedCallback(){this.enableUpdating()}enableUpdating(){void 0!==this._enableUpdatingResolver&&(this._enableUpdatingResolver(),this._enableUpdatingResolver=void 0)}disconnectedCallback(){}attributeChangedCallback(e,t,s){t!==s&&this._attributeToProperty(e,s)}_propertyToAttribute(e,t,s=W){const n=this.constructor,o=n._attributeNameForProperty(e,s);if(void 0!==o){const e=n._propertyValueToAttribute(t,s);if(void 0===e)return;this._updateState=8|this._updateState,null==e?this.removeAttribute(o):this.setAttribute(o,e),this._updateState=-9&this._updateState}}_attributeToProperty(e,t){if(8&this._updateState)return;const s=this.constructor,n=s._attributeToPropertyMap.get(e);if(void 0!==n){const e=s.getPropertyOptions(n);this._updateState=16|this._updateState,this[n]=s._propertyValueFromAttribute(t,e),this._updateState=-17&this._updateState}}requestUpdateInternal(e,t,s){let n=!0;if(void 0!==e){const o=this.constructor;s=s||o.getPropertyOptions(e),o._valueHasChanged(this[e],t,s.hasChanged)?(this._changedProperties.has(e)||this._changedProperties.set(e,t),!0!==s.reflect||16&this._updateState||(void 0===this._reflectingProperties&&(this._reflectingProperties=new Map),this._reflectingProperties.set(e,s))):n=!1}!this._hasRequestedUpdate&&n&&(this._updatePromise=this._enqueueUpdate())}requestUpdate(e,t){return this.requestUpdateInternal(e,t),this.updateComplete}async _enqueueUpdate(){this._updateState=4|this._updateState;try{await this._updatePromise}catch(e){}const e=this.performUpdate();return null!=e&&await e,!this._hasRequestedUpdate}get _hasRequestedUpdate(){return 4&this._updateState}get hasUpdated(){return 1&this._updateState}performUpdate(){if(!this._hasRequestedUpdate)return;this._instanceProperties&&this._applyInstanceProperties();let e=!1;const t=this._changedProperties;try{e=this.shouldUpdate(t),e?this.update(t):this._markUpdated()}catch(t){throw e=!1,this._markUpdated(),t}e&&(1&this._updateState||(this._updateState=1|this._updateState,this.firstUpdated(t)),this.updated(t))}_markUpdated(){this._changedProperties=new Map,this._updateState=-5&this._updateState}get updateComplete(){return this._getUpdateComplete()}_getUpdateComplete(){return this._updatePromise}shouldUpdate(e){return!0}update(e){void 0!==this._reflectingProperties&&this._reflectingProperties.size>0&&(this._reflectingProperties.forEach(((e,t)=>this._propertyToAttribute(t,this[t],e))),this._reflectingProperties=void 0),this._markUpdated()}updated(e){}firstUpdated(e){}}Y.finalized=!0;const G=(e,t)=>"method"===t.kind&&t.descriptor&&!("value"in t.descriptor)?Object.assign(Object.assign({},t),{finisher(s){s.createProperty(t.key,e)}}):{kind:"field",key:Symbol(),placement:"own",descriptor:{},initializer(){"function"==typeof t.initializer&&(this[t.key]=t.initializer.call(this))},finisher(s){s.createProperty(t.key,e)}};const K=window.ShadowRoot&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,Q=Symbol();class X{constructor(e,t){if(t!==Q)throw new Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e}get styleSheet(){return void 0===this._styleSheet&&(K?(this._styleSheet=new CSSStyleSheet,this._styleSheet.replaceSync(this.cssText)):this._styleSheet=null),this._styleSheet}toString(){return this.cssText}}(window.litElementVersions||(window.litElementVersions=[])).push("2.4.0");const Z={};class ee extends Y{static getStyles(){return this.styles}static _getUniqueStyles(){if(this.hasOwnProperty(JSCompiler_renameProperty("_styles",this)))return;const e=this.getStyles();if(Array.isArray(e)){const t=(e,s)=>e.reduceRight(((e,s)=>Array.isArray(s)?t(s,e):(e.add(s),e)),s),s=t(e,new Set),n=[];s.forEach((e=>n.unshift(e))),this._styles=n}else this._styles=void 0===e?[]:[e];this._styles=this._styles.map((e=>{if(e instanceof CSSStyleSheet&&!K){const t=Array.prototype.slice.call(e.cssRules).reduce(((e,t)=>e+t.cssText),"");return new X(String(t),Q)}return e}))}initialize(){super.initialize(),this.constructor._getUniqueStyles(),this.renderRoot=this.createRenderRoot(),window.ShadowRoot&&this.renderRoot instanceof window.ShadowRoot&&this.adoptStyles()}createRenderRoot(){return this.attachShadow({mode:"open"})}adoptStyles(){const e=this.constructor._styles;0!==e.length&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow?K?this.renderRoot.adoptedStyleSheets=e.map((e=>e instanceof CSSStyleSheet?e:e.styleSheet)):this._needsShimAdoptedStyleSheets=!0:window.ShadyCSS.ScopingShim.prepareAdoptedCssText(e.map((e=>e.cssText)),this.localName))}connectedCallback(){super.connectedCallback(),this.hasUpdated&&void 0!==window.ShadyCSS&&window.ShadyCSS.styleElement(this)}update(e){const t=this.render();super.update(e),t!==Z&&this.constructor.render(t,this.renderRoot,{scopeName:this.localName,eventContext:this}),this._needsShimAdoptedStyleSheets&&(this._needsShimAdoptedStyleSheets=!1,this.constructor._styles.forEach((e=>{const t=document.createElement("style");t.textContent=e.cssText,this.renderRoot.appendChild(t)})))}render(){return Z}}ee.finalized=!0,ee.render=(e,t,s)=>{if(!s||"object"!=typeof s||!s.scopeName)throw new Error("The `scopeName` option is required.");const o=s.scopeName,i=D.has(t),r=I&&11===t.nodeType&&!!t.host,a=r&&!H.has(o),d=a?document.createDocumentFragment():t;if(((e,t,s)=>{let o=D.get(t);void 0===o&&(n(t,t.firstChild),D.set(t,o=new x(Object.assign({templateFactory:k},s))),o.appendInto(t)),o.setValue(e),o.commit()})(e,d,Object.assign({templateFactory:j(o)},s)),a){const e=D.get(d);D.delete(d);const s=e.value instanceof v?e.value.template:void 0;J(o,d,s),n(t,t.firstChild),t.appendChild(d),D.set(t,e)}!i&&r&&window.ShadyCSS.styleElement(t.host)};const te="lovelace-player-device-id";function se(){if(!localStorage[te]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);window.fully&&"function"==typeof fully.getDeviceId?localStorage[te]=fully.getDeviceId():localStorage[te]=`${e()}${e()}-${e()}${e()}`}return localStorage[te]}let ne=se();const oe=new URLSearchParams(window.location.search);var ie;oe.get("deviceID")&&null!==(ie=oe.get("deviceID"))&&("clear"===ie?localStorage.removeItem(te):localStorage[te]=ie,ne=se()),window.cardMod_template_cache=window.cardMod_template_cache||{};const re=window.cardMod_template_cache;async function ae(t,s,n){const o=e().connection,i=JSON.stringify([s,n]);let r=re[i];r?(r.callbacks.has(t)||de(t),t(r.value),r.callbacks.add(t)):(de(t),t(""),n=Object.assign({user:e().user.name,browser:ne,hash:location.hash.substr(1)||""},n),re[i]=r={template:s,variables:n,value:"",callbacks:new Set([t]),unsubscribe:o.subscribeMessage((e=>function(e,t){const s=re[e];s&&(s.value=t.result,s.callbacks.forEach((e=>e(t.result))))}(i,e)),{type:"render_template",template:s,variables:n})})}async function de(e){let t;for(const[s,n]of Object.entries(re))if(n.callbacks.has(e)){n.callbacks.delete(e),0==n.callbacks.size&&(t=n.unsubscribe,delete re[s]);break}t&&await(await t)()}var le="3.0.12";async function ce(e,t,s=!1){let n=e;"string"==typeof t&&(t=t.split(/(\$| )/)),""===t[t.length-1]&&t.pop();for(const[e,o]of t.entries())if(o.trim().length){if(!n)return null;n.localName&&n.localName.includes("-")&&await customElements.whenDefined(n.localName),n.updateComplete&&await n.updateComplete,n="$"===o?s&&e==t.length-1?[n.shadowRoot]:n.shadowRoot:s&&e==t.length-1?n.querySelectorAll(o):n.querySelector(o)}return n}async function he(e,t,s=!1,n=1e4){return Promise.race([ce(e,t,s),new Promise(((e,t)=>setTimeout((()=>t(new Error("timeout"))),n)))]).catch((e=>{if(!e.message||"timeout"!==e.message)throw e;return null}))}const ue=async e=>{await(async()=>{if(customElements.get("developer-tools-event"))return;await customElements.whenDefined("partial-panel-resolver");const e=document.createElement("partial-panel-resolver");e.hass={panels:[{url_path:"tmp",component_name:"developer-tools"}]},e._updateRoutes(),await e.routerOptions.routes.tmp.load(),await customElements.whenDefined("developer-tools-router");const t=document.createElement("developer-tools-router");await t.routerOptions.routes.event.load()})();return document.createElement("developer-tools-event")._computeParsedEventData(e)};async function pe(e,t,s="",n={},o=null,i=!0){var r;let a;(null===(r=e.localName)||void 0===r?void 0:r.includes("-"))&&await customElements.whenDefined(e.localName),e.updateComplete&&await e.updateComplete,void 0===e._cardMod&&(e._cardMod=[]);for(const s of e._cardMod)if(s.type===t){a=s;break}return a||(a=document.createElement("card-mod"),a.type=t,e._cardMod.push(a)),queueMicrotask((async()=>{(e.modElement?e.modElement:i&&e.shadowRoot||e).appendChild(a),a.variables=n,a.styles=s})),a}function me(e,t){const s=e=>e&&"object"==typeof e&&!Array.isArray(e);if(s(e)&&s(t))for(const n in t)s(t[n])?(e[n]||Object.assign(e,{[n]:{}}),"string"==typeof e[n]&&(e[n]={".":e[n]}),me(e[n],t[n])):e[n]?e[n]=t[n]+e[n]:e[n]=t[n];return e}function fe(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(!(e instanceof Object&&t instanceof Object))return!1;for(const s in e)if(e.hasOwnProperty(s)){if(!t.hasOwnProperty(s))return!1;if(e[s]!==t[s]){if("object"!=typeof e[s])return!1;if(!fe(e[s],t[s]))return!1}}for(const s in t)if(t.hasOwnProperty(s)&&!e.hasOwnProperty(s))return!1;return!0}function ye(e){return e.config?e.config:e._config?e._config:e.host?ye(e.host):e.parentElement?ye(e.parentElement):e.parentNode?ye(e.parentNode):null}function _e(e,t){for(const s of t)e.add(s)}async function ge(e,t=0){let s=new Set;if(10==t)return s;if(!e)return s;if(e._cardMod)for(const t of e._cardMod)t.styles&&s.add(t);return e.updateComplete&&await e.updateComplete,e.parentElement?_e(s,await ge(e.parentElement,t+1)):e.parentNode&&_e(s,await ge(e.parentNode,t+1)),e.host&&_e(s,await ge(e.host,t+1)),s}class ve extends ee{constructor(){super(),this._rendered_styles="",this._styleChildren=new Set,this._observer=new MutationObserver((e=>{for(const t of e){if("card-mod"===t.target.localName)return;let e=!0;if(t.addedNodes.length&&t.addedNodes.forEach((t=>{"card-mod"!==t.localName&&(e=!1)})),e)return;if(e=!0,t.removedNodes.length&&t.removedNodes.forEach((t=>{"card-mod"!==t.localName&&(e=!1)})),e)return}this.refresh()})),document.addEventListener("cm_update",(()=>{this.refresh()}))}static get applyToElement(){return pe}connectedCallback(){super.connectedCallback(),this._connect(),this.setAttribute("slot","none")}disconnectedCallback(){super.disconnectedCallback(),this._disconnect()}set styles(e){fe(e,this._input_styles)||(this._input_styles=e,this._connect())}get styles(){return this._styles}refresh(){this._connect()}async _connect(){const t=this._input_styles;let s=JSON.parse(JSON.stringify(t||{}));"string"==typeof s&&(s={".":s});me(s,await async function(t){if(!t.type)return null;const s=t.parentElement?t.parentElement:t,n=window.getComputedStyle(s).getPropertyValue("--card-mod-theme"),o=e().themes.themes;return o[n]?o[n][`card-mod-${t.type}-yaml`]?ue(o[n][`card-mod-${t.type}-yaml`]):o[n][`card-mod-${t.type}`]?{".":o[n][`card-mod-${t.type}`]}:{}:{}}(this));const n=new Set;let o;const i=this.parentElement||this.parentNode;s["."]||(o="");for(const[e,t]of Object.entries(s))if("."===e)o=t;else{const s=await he(i,e,!0);if(!s)continue;for(const e of s)if(e){const s=await pe(e,`${this.type}-child`,t,this.variables,null,!1);s.refresh(),n.add(s)}}for(const e of this._styleChildren)n.has(e)||e&&(e.styles="");var r;(this._styleChildren=n,this._styles!==o)&&(this._styles=o,this._styles&&(r=this._styles,String(r).includes("{%")||String(r).includes("{{"))?(this._renderer=this._renderer||this._style_rendered.bind(this),ae(this._renderer,this._styles,this.variables)):this._style_rendered(this._styles||""),this._observer.observe(function(e){if(!e)return;const t=e.parentElement||e.parentNode;return t?t.host?t.host:t:void 0}(this),{childList:!0}))}async _disconnect(){this._observer.disconnect(),this._styles="",await de(this._renderer)}_style_rendered(e){this._rendered_styles=e,this.dispatchEvent(new Event("card-mod-update"))}createRenderRoot(){return this}render(){return q`
2 |
5 | `}}var we;!function(e,t,s,n){var o,i=arguments.length,r=i<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,s):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,s,n);else for(var a=e.length-1;a>=0;a--)(o=e[a])&&(r=(i<3?o(r):i>3?o(t,s,r):o(t,s))||r);i>3&&r&&Object.defineProperty(t,s,r)}([(e,t)=>void 0!==t?((e,t,s)=>{t.constructor.createProperty(s,e)})(we,e,t):G(we,e)],ve.prototype,"_rendered_styles",void 0),customElements.get("card-mod")||(customElements.define("card-mod",ve),console.info(`%cCARD-MOD ${le} IS INSTALLED`,"color: green; font-weight: bold","")),customElements.whenDefined("ha-card").then((()=>{const e=customElements.get("ha-card");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.firstUpdated;e.prototype.firstUpdated=function(e){var s,n;null==t||t.bind(this)(e);const o=this.shadowRoot.querySelector(".card-header");o&&this.insertBefore(o,this.children[0]);const i=ye(this);(null===(s=null==i?void 0:i.card_mod)||void 0===s?void 0:s.class)&&this.classList.add(i.card_mod.class),(null==i?void 0:i.type)&&this.classList.add(`type-${i.type.replace(":","-")}`),pe(this,"card",(null===(n=null==i?void 0:i.card_mod)||void 0===n?void 0:n.style)||(null==i?void 0:i.style)||"",{config:i},null,!1).then((e=>{var t;const s=null===(t=this.parentNode)||void 0===t?void 0:t.host;if(s){if(s.setConfig&&!s.setConfig.cm_patched){const t=s.setConfig;s.setConfig=function(s){var n;t.bind(this)(s),e.variables={config:s},e.styles=(null===(n=s.card_mod)||void 0===n?void 0:n.style)||{}},s.setConfig.cm_patched=!0}if(s.update&&!s.update.cm_patched){const t=s.update;s.update=function(s){t.bind(this)(s),e.refresh(),this.updateComplete.then((()=>{e.refresh()}))},s.update.cm_patched=!0}window.setTimeout((()=>e.refresh()),100),window.setTimeout((()=>e.refresh()),500),window.setTimeout((()=>e.refresh()),1e3)}}))}})),customElements.whenDefined("hui-entities-card").then((()=>{const e=customElements.get("hui-entities-card");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.renderEntity;e.prototype.renderEntity=function(e){var s;const n=t.bind(this)(e);if(!n||!n.values)return n;const o=n.values[0];if(!o)return n;(null===(s=null==e?void 0:e.card_mod)||void 0===s?void 0:s.class)&&o.classList.add(e.card_mod.class),(null==e?void 0:e.type)&&o.classList.add(`type-${e.type.replace(":","-")}`);const i=()=>{var t;return pe(o,"row",(null===(t=null==e?void 0:e.card_mod)||void 0===t?void 0:t.style)||(null==e?void 0:e.style)||"",{config:e})};return this.updateComplete.then((()=>i())),n.values[0]&&n.values[0].addEventListener("ll-rebuild",i),n}}));customElements.whenDefined("hui-glance-card").then((()=>{const e=customElements.get("hui-glance-card");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.updated;e.prototype.updated=function(e){var s,n;null==t||t.bind(this)(e);for(const e of this.shadowRoot.querySelectorAll("ha-card div.entity")){if(!e.cardmod_patched){e.cardmod_patched=!0;const t=e.attachShadow({mode:"open"});for(;e.firstChild;)t.append(e.firstChild);const s=document.createElement("style");t.appendChild(s),s.innerHTML="\ndiv {\n width: 100%;\n text-align: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.name {\n min-height: var(--paper-font-body1_-_line-height, 20px);\n}\nstate-badge {\n margin: 8px 0;\n}\n"}const t=e.config||e.entityConf;(null===(s=null==t?void 0:t.card_mod)||void 0===s?void 0:s.class)&&e.classList.add(t.card_mod.class),pe(e,"glance",(null===(n=null==t?void 0:t.card_mod)||void 0===n?void 0:n.style)||(null==t?void 0:t.style)||"",{config:t})}}})),customElements.whenDefined("hui-state-label-badge").then((()=>{const e=customElements.get("hui-state-label-badge");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.firstUpdated;e.prototype.firstUpdated=function(e){var s,n;null==t||t.bind(this)(e);const o=this._config;(null===(s=null==o?void 0:o.card_mod)||void 0===s?void 0:s.class)&&this.classList.add(o.card_mod.class),pe(this,"badge",(null===(n=null==o?void 0:o.card_mod)||void 0===n?void 0:n.style)||(null==o?void 0:o.style)||"",{config:o})}})),customElements.whenDefined("hui-view").then((()=>{const e=customElements.get("hui-view");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.firstUpdated;e.prototype.firstUpdated=function(e){null==t||t.bind(this)(e),pe(this,"view")}})),customElements.whenDefined("hui-root").then((()=>{const e=customElements.get("hui-root");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.firstUpdated;e.prototype.firstUpdated=async function(e){null==t||t.bind(this)(e),pe(this,"root")},he(document,"home-assistant$home-assistant-main$app-drawer-layout partial-panel-resolver ha-panel-lovelace$hui-root",!1).then((e=>{null==e||e.firstUpdated()}))})),customElements.whenDefined("ha-more-info-dialog").then((()=>{const e=customElements.get("ha-more-info-dialog");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.showDialog;e.prototype.showDialog=function(e){null==t||t.bind(this)(e),this.requestUpdate().then((async()=>{pe(this.shadowRoot.querySelector("ha-dialog"),"more-info","",{config:e},null,!1)}))},he(document,"home-assistant$ha-more-info-dialog",!1).then((t=>{t&&(t.showDialog=e.prototype.showDialog.bind(t),t.showDialog({entityId:t.entityId}))}))})),customElements.whenDefined("ha-sidebar").then((()=>{const e=customElements.get("ha-sidebar");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.firstUpdated;e.prototype.firstUpdated=async function(e){null==t||t.bind(this)(e),pe(this,"sidebar")},he(document,"home-assistant$home-assistant-main$app-drawer-layout app-drawer ha-sidebar",!1).then((e=>null==e?void 0:e.firstUpdated()))})),customElements.whenDefined("hui-card-element-editor").then((()=>{const e=customElements.get("hui-card-element-editor");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.getConfigElement;e.prototype.getConfigElement=async function(){const e=await t.bind(this)();if(e){const t=e.setConfig;e.setConfig=function(e){var s,n;const o=JSON.parse(JSON.stringify(e));if(this._cardModData={card:o.card_mod,entities:[]},o.entities)for(const[e,t]of null===(s=o.entities)||void 0===s?void 0:s.entries())this._cardModData.entities[e]=t.card_mod,delete t.card_mod;if(delete o.card_mod,t.bind(this)(o),o.entities)for(const[e,t]of null===(n=o.entities)||void 0===n?void 0:n.entries())this._cardModData.entities[e]&&(t.card_mod=this._cardModData.entities[e])}}return e};const s=e.prototype._handleUIConfigChanged;e.prototype._handleUIConfigChanged=function(e){if(this._configElement&&this._configElement._cardModData){const t=this._configElement._cardModData;t.card&&(e.detail.config.card_mod=t.card)}s.bind(this)(e)}})),customElements.whenDefined("hui-dialog-edit-card").then((()=>{const e=customElements.get("hui-dialog-edit-card");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.updated;e.prototype.updated=function(e){null==t||t.bind(this)(e),this.updateComplete.then((async()=>{var e,t,s;this._cardModIcon||(this._cardModIcon=document.createElement("ha-icon"),this._cardModIcon.icon="mdi:brush");const n=this.shadowRoot.querySelector("mwc-button[slot=secondaryAction]");n&&(n.appendChild(this._cardModIcon),(null===(e=this._cardConfig)||void 0===e?void 0:e.card_mod)||(null===(s=null===(t=this._cardConfig)||void 0===t?void 0:t.entities)||void 0===s?void 0:s.some((e=>e.card_mod)))?this._cardModIcon.style.visibility="visible":this._cardModIcon.style.visibility="hidden")}))}})),customElements.whenDefined("hui-picture-elements-card").then((()=>{const e=customElements.get("hui-picture-elements-card");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.setConfig;e.prototype.setConfig=function(e){var s,n;null==t||t.bind(this)(e);for(const[e,t]of this._elements.entries()){const o=this._config.elements[e];(null===(s=null==o?void 0:o.card_mod)||void 0===s?void 0:s.class)&&t.classList.add(o.card_mod.class),(null==o?void 0:o.type)&&t.classList.add(`type-${o.type.replace(":","-")}`),pe(t,"element",null===(n=null==o?void 0:o.card_mod)||void 0===n?void 0:n.style,{config:o})}}})),customElements.whenDefined("ha-icon").then((()=>{const e=customElements.get("ha-icon");if(e.prototype.cardmod_patched)return;e.prototype.cardmod_patched=!0;const t=e.prototype.firstUpdated;e.prototype.firstUpdated=function(){null==t||t.bind(this)();const e=()=>{const e=window.getComputedStyle(this).getPropertyValue("--card-mod-icon");e&&(this.icon=e.trim());const t=window.getComputedStyle(this).getPropertyValue("--card-mod-icon-color");t&&(this.style.color=t)};(async()=>{const t=await ge(this);for(const s of t)s.addEventListener("card-mod-update",(async()=>{await s.updateComplete,e()}));e()})()}}));let Se=window.cardHelpers;const be=new Promise((async(t,s)=>{Se&&t();const n=async()=>{Se=await window.loadCardHelpers(),window.cardHelpers=Se,t()};window.loadCardHelpers?n():window.addEventListener("load",(async()=>{!async function(){if(customElements.get("hui-view"))return!0;await customElements.whenDefined("partial-panel-resolver");const t=document.createElement("partial-panel-resolver");if(t.hass={panels:[{url_path:"tmp",component_name:"lovelace"}]},t._updateRoutes(),await t.routerOptions.routes.tmp.load(),!customElements.get("ha-panel-lovelace"))return!1;const s=document.createElement("ha-panel-lovelace");s.hass=e(),void 0===s.hass&&(await new Promise((e=>{window.addEventListener("connection-status",(t=>{console.log(t),e()}),{once:!0})})),s.hass=e()),s.panel={config:{mode:null}},s._fetchConfig()}(),window.loadCardHelpers&&n()}))}));function Ee(e,s){const n={type:"error",error:e,origConfig:s},o=document.createElement("hui-error-card");return customElements.whenDefined("hui-error-card").then((()=>{const e=document.createElement("hui-error-card");e.setConfig(n),o.parentElement&&o.parentElement.replaceChild(e,o)})),be.then((()=>{t("ll-rebuild",{},o)})),o}function Ce(e,s){if(!s||"object"!=typeof s||!s.type)return Ee(`No ${e} type configured`,s);let n=s.type;if(n=n.startsWith("custom:")?n.substr("custom:".length):`hui-${n}-${e}`,customElements.get(n))return function(e,s){let n=document.createElement(e);try{n.setConfig(JSON.parse(JSON.stringify(s)))}catch(e){n=Ee(e,s)}return be.then((()=>{t("ll-rebuild",{},n)})),n}(n,s);const o=Ee(`Custom element doesn't exist: ${n}.`,s);o.style.display="None";const i=setTimeout((()=>{o.style.display=""}),2e3);return customElements.whenDefined(n).then((()=>{clearTimeout(i),t("ll-rebuild",{},o)})),o}const Ne="\nha-card {\n background: none;\n box-shadow: none;\n}";function Pe(){document.dispatchEvent(new Event("cm_update"))}customElements.define("mod-card",class extends ee{static get properties(){return{hass:{}}}setConfig(t){var s;this._config=JSON.parse(JSON.stringify(t));let n=(null===(s=this._config.card_mod)||void 0===s?void 0:s.style)||this._config.style;void 0===n?n=Ne:"string"==typeof n?n=Ne+n:n["."]?n["."]=Ne+n["."]:n["."]=Ne,this._config.card_mod={style:n},this.card=function(e){return Se?Se.createCardElement(e):Ce("card",e)}(t.card),this.card.hass=e()}firstUpdated(){window.setTimeout((()=>{var e,t;if(null===(t=null===(e=this.card)||void 0===e?void 0:e.shadowRoot)||void 0===t?void 0:t.querySelector("ha-card")){console.info("%cYou are doing it wrong!","color: red; font-weight: bold","");let e=this.card.localName.replace(/hui-(.*)-card/,"$1");console.info(`mod-card should NEVER be used with a card that already has a ha-card element, such as ${e}`)}}),3e3)}render(){return q` ${this.card} `}set hass(e){this.card&&(this.card.hass=e)}getCardSize(){if(this._config.report_size)return this._config.report_size;let e=this.shadowRoot;return e&&(e=e.querySelector("ha-card card-maker")),e&&(e=e.getCardSize),e&&(e=e()),e||1}});const xe=[customElements.whenDefined("home-assistant"),customElements.whenDefined("hc-main")];Promise.race(xe).then((()=>{window.setTimeout((()=>{var t,s;e().connection.subscribeEvents((()=>{window.setTimeout(Pe,500)}),"themes_updated"),null===(t=document.querySelector("home-assistant"))||void 0===t||t.addEventListener("settheme",Pe),null===(s=document.querySelector("hc-main"))||void 0===s||s.addEventListener("settheme",Pe)}),1e3)})),t("ll-rebuild",{});
6 |
--------------------------------------------------------------------------------
/www/community/lovelace-card-mod/card-mod.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/lovelace-card-mod/card-mod.js.gz
--------------------------------------------------------------------------------
/www/community/lovelace-card-mod/rollup.config.js:
--------------------------------------------------------------------------------
1 | import nodeResolve from "@rollup/plugin-node-resolve";
2 | import json from "@rollup/plugin-json";
3 | import typescript from "rollup-plugin-typescript2";
4 | import { terser } from "rollup-plugin-terser";
5 | import babel from "@rollup/plugin-babel";
6 |
7 | const dev = process.env.ROLLUP_WATCH;
8 |
9 | export default {
10 | input: "src/main.ts",
11 | output: {
12 | file: "card-mod.js",
13 | format: "es",
14 | },
15 | plugins: [
16 | nodeResolve(),
17 | json(),
18 | typescript(),
19 | babel({
20 | exclude: "node_modules/**",
21 | }),
22 | !dev && terser({ format: { comments: false } }),
23 | ],
24 | };
25 |
--------------------------------------------------------------------------------
/www/community/lovelace-card-mod/rollup.config.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/lovelace-card-mod/rollup.config.js.gz
--------------------------------------------------------------------------------
/www/community/lovelace-state-switch/state-switch.js:
--------------------------------------------------------------------------------
1 | !function(t){var e={};function i(s){if(e[s])return e[s].exports;var r=e[s]={i:s,l:!1,exports:{}};return t[s].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=t,i.c=e,i.d=function(t,e,s){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:s})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var s=Object.create(null);if(i.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)i.d(s,r,function(e){return t[e]}.bind(null,r));return s},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=0)}([function(t,e,i){"use strict";i.r(e);const s=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),r=s.prototype.html,o=s.prototype.css;function a(){return document.querySelector("hc-main")?document.querySelector("hc-main").hass:document.querySelector("home-assistant")?document.querySelector("home-assistant").hass:void 0}function n(t,e,i=null){if((t=new Event(t,{bubbles:!0,cancelable:!1,composed:!0})).detail=e||{},i)i.dispatchEvent(t);else{var s=function(){var t=document.querySelector("hc-main");return t=t?(t=(t=(t=t&&t.shadowRoot)&&t.querySelector("hc-lovelace"))&&t.shadowRoot)&&t.querySelector("hui-view")||t.querySelector("hui-panel-view"):(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=document.querySelector("home-assistant"))&&t.shadowRoot)&&t.querySelector("home-assistant-main"))&&t.shadowRoot)&&t.querySelector("app-drawer-layout partial-panel-resolver"))&&t.shadowRoot||t)&&t.querySelector("ha-panel-lovelace"))&&t.shadowRoot)&&t.querySelector("hui-root"))&&t.shadowRoot)&&t.querySelector("ha-app-layout #view"))&&t.firstElementChild}();s&&s.dispatchEvent(t)}}let l=window.cardHelpers;const c=new Promise(async(t,e)=>{l&&t();const i=async()=>{l=await window.loadCardHelpers(),window.cardHelpers=l,t()};window.loadCardHelpers?i():window.addEventListener("load",async()=>{!function(){if(customElements.get("hui-view"))return!0;const t=document.createElement("partial-panel-resolver");if(t.hass=a(),!t.hass||!t.hass.panels)return!1;t.route={path:"/lovelace/"},t._updateRoutes();try{document.querySelector("home-assistant").appendChild(t)}catch(t){}finally{document.querySelector("home-assistant").removeChild(t)}customElements.get("hui-view")}(),window.loadCardHelpers&&i()})});function d(t,e){const i={type:"error",error:t,origConfig:e},s=document.createElement("hui-error-card");return customElements.whenDefined("hui-error-card").then(()=>{const t=document.createElement("hui-error-card");t.setConfig(i),s.parentElement&&s.parentElement.replaceChild(t,s)}),c.then(()=>{n("ll-rebuild",{},s)}),s}function u(t,e){if(!e||"object"!=typeof e||!e.type)return d(`No ${t} type configured`,e);let i=e.type;if(i=i.startsWith("custom:")?i.substr("custom:".length):`hui-${i}-${t}`,customElements.get(i))return function(t,e){let i=document.createElement(t);try{i.setConfig(JSON.parse(JSON.stringify(e)))}catch(t){i=d(t,e)}return c.then(()=>{n("ll-rebuild",{},i)}),i}(i,e);const s=d(`Custom element doesn't exist: ${i}.`,e);s.style.display="None";const r=setTimeout(()=>{s.style.display=""},2e3);return customElements.whenDefined(i).then(()=>{clearTimeout(r),n("ll-rebuild",{},s)}),s}function h(t){return l?l.createCardElement(t):u("card",t)}let p=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const t=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${t()}${t()}-${t()}${t()}`}return localStorage["lovelace-player-device-id"]}();customElements.define("state-switch",class extends s{static get properties(){return{hass:{},state:{}}}setConfig(t){this._config=t,this.state=void 0,this.classList.add("no-match"),this.cards={};for(let e in t.states)this.cards[e]=h(t.states[e]),this.cards[e].hass=a();if("hash"===t.entity&&window.addEventListener("location-changed",()=>this.updated(new Map)),"mediaquery"===t.entity)for(const t in this.cards)window.matchMedia(t).addListener(this.update_state.bind(this));if("template"===t.entity){const e=t.template;String(e).includes("{%")||String(e).includes("{{")?function(t,e,i){t||(t=a().connection);let s={user:a().user.name,browser:p,hash:location.hash.substr(1)||" ",...i.variables},r=i.template,o=i.entity_ids;t.subscribeMessage(t=>{let i=t.result;i=i.replace(/_\([^)]*\)/g,t=>a().localize(t.substring(2,t.length-1))||t),e(i)},{type:"render_template",template:r,variables:s,entity_ids:o})}(null,t=>{this._tmpl=t,this.update_state()},{template:e,variables:{config:t},entity_ids:t.entity_ids}):this._tmpl=e}}update_state(){let t=void 0;switch(this._config.entity){case"template":t=this._tmpl;break;case"user":t=this.hass&&this.hass.user&&this.hass.user.name||void 0;break;case"group":t=this.hass&&this.hass.user&&this.hass.user.is_admin?"admin":"user";break;case"deviceID":case"browser":t=p;break;case"hash":t=location.hash.substr(1);break;case"mediaquery":for(const e in this.cards)if(window.matchMedia(e).matches){t=e;break}break;default:t=this.hass.states[this._config.entity],t=t?t.state:void 0}void 0!==t&&this.cards.hasOwnProperty(t)||(t=this._config.default),this.state=t}updated(t){if(t.has("hass"))for(let t in this.cards)this.cards[t].hass=this.hass;if(t.has("state")){const e=t.get("state");this.cards[e]&&(this.cards[e].classList.remove("visible"),this.cards[e].classList.add("out"),window.setTimeout(()=>{this.cards[e].classList.remove("out")},this._config.transition_time||500)),this.cards[this.state]?(this.cards[this.state].classList.add("visible"),this.classList.remove("no-match")):this.classList.add("no-match")}else this.update_state()}render(){return r`
2 |
10 | ${Object.keys(this.cards).map(t=>r`
11 | ${this.cards[t]}
12 | `)}
13 |
14 | `}getCardSize(){let t=1;for(let e in this.cards)this.cards[e]&&this.cards[e].getCardSize&&(t=Math.max(t,this.cards[e].getCardSize()));return t}static get styles(){return o`
15 | :host {
16 | perspective: 1000px;
17 | }
18 | :host(.no-match) {
19 | display: none;
20 | }
21 | #root * {
22 | display: none;
23 | }
24 | #root .visible {
25 | display: block;
26 | }
27 |
28 |
29 | #root.slide-right,
30 | #root.slide-left {
31 | display: grid;
32 | }
33 | #root.slide-right *,
34 | #root.slide-left * {
35 | grid-column: 1;
36 | grid-row: 1;
37 | display: block;
38 | opacity: 0;
39 | height: 0;
40 | transition-property: transform;
41 | transition-timing-function: linear;
42 | transition-duration: inherit;
43 | transform: translate(-110%);
44 | }
45 | #root.slide-left * {
46 | transform: translate(110%);
47 | }
48 | #root.slide-right .visible,
49 | #root.slide-left .visible {
50 | opacity: 1;
51 | height: auto;
52 | transform: translate(0%);
53 | }
54 | #root.slide-right .out,
55 | #root.slide-left .out {
56 | opacity: 1;
57 | height: auto;
58 | transform: translate(110%);
59 | }
60 | #root.slide-left .out {
61 | transform: translate(-110%);
62 | }
63 |
64 |
65 | #root.swap-right,
66 | #root.swap-left {
67 | display: grid;
68 | }
69 | #root.swap-right *,
70 | #root.swap-left * {
71 | grid-column: 1;
72 | grid-row: 1;
73 | display: block;
74 | opacity: 0;
75 | height: 0;
76 | transition-property: transform;
77 | transition-timing-function: linear;
78 | transition-duration: inherit;
79 | transform: translate(110%);
80 | }
81 | #root.swap-left *{
82 | transform: translate(-110%);
83 | }
84 | #root.swap-right .visible,
85 | #root.swap-left .visible {
86 | opacity: 1;
87 | height: auto;
88 | transition-delay: inherit;
89 | transform: translate(0%);
90 | }
91 | #root.swap-right .out,
92 | #root.swap-left .out {
93 | opacity: 1;
94 | height: auto;
95 | }
96 |
97 |
98 |
99 | #root.flip {
100 | display: grid;
101 | width: 100%;
102 | height: 100%;
103 | position: relative;
104 | }
105 | #root.flip * {
106 | grid-column: 1;
107 | grid-row: 1;
108 | display: block;
109 | opacity: 0;
110 | height: 0;
111 | transform: rotateY(-180deg);
112 | transition-property: transform;
113 | transition-timing-function: linear;
114 | transition-duration: inherit;
115 | transform-style: preserve-3d;
116 | backface-visibility: hidden;
117 | z-index: 100;
118 | }
119 | #root.flip .visible {
120 | opacity: 1;
121 | height: auto;
122 | backface-visibility: hidden;
123 | transform: rotateY(0deg);
124 | }
125 | #root.flip .out {
126 | opacity: 1;
127 | height: auto;
128 | transform: rotateY(180deg);
129 | }
130 | `}})}]);
--------------------------------------------------------------------------------
/www/community/lovelace-state-switch/state-switch.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/lovelace-state-switch/state-switch.js.gz
--------------------------------------------------------------------------------
/www/community/lovelace-state-switch/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | entry: './src/main.js',
5 | mode: 'production',
6 | output: {
7 | filename: 'state-switch.js',
8 | path: path.resolve(__dirname)
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/www/community/lovelace-state-switch/webpack.config.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/lovelace-state-switch/webpack.config.js.gz
--------------------------------------------------------------------------------
/www/community/mini-graph-card/mini-graph-card-bundle.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/mini-graph-card/mini-graph-card-bundle.js.gz
--------------------------------------------------------------------------------
/www/community/mini-media-player/mini-media-player-bundle.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/mini-media-player/mini-media-player-bundle.js.gz
--------------------------------------------------------------------------------
/www/community/swipe-card/swipe-card.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/swipe-card/swipe-card.js.gz
--------------------------------------------------------------------------------
/www/community/vertical-stack-in-card/vertical-stack-in-card.js:
--------------------------------------------------------------------------------
1 | console.log(`%cvertical-stack-in-card\n%cVersion: ${'0.4.1'}`, 'color: #1976d2; font-weight: bold;', '');
2 |
3 | class VerticalStackInCard extends HTMLElement {
4 | constructor() {
5 | super();
6 | }
7 |
8 | setConfig(config) {
9 | this._cardSize = {};
10 | this._cardSize.promise = new Promise((resolve) => (this._cardSize.resolve = resolve));
11 |
12 | if (!config || !config.cards || !Array.isArray(config.cards)) {
13 | throw new Error('Card config incorrect');
14 | }
15 | this._config = config;
16 | this._refCards = [];
17 | this.renderCard();
18 | }
19 |
20 | async renderCard() {
21 | const config = this._config;
22 | if (window.loadCardHelpers) {
23 | this.helpers = await window.loadCardHelpers();
24 | }
25 | const promises = config.cards.map((config) => this.createCardElement(config));
26 | this._refCards = await Promise.all(promises);
27 |
28 | // Style cards
29 | this._refCards.forEach((card) => {
30 | if (card.updateComplete) {
31 | card.updateComplete.then(() => this.styleCard(card));
32 | } else {
33 | this.styleCard(card);
34 | }
35 | });
36 |
37 | // Create the card
38 | const card = document.createElement('ha-card');
39 | const cardContent = document.createElement('div');
40 | card.header = config.title;
41 | card.style.overflow = 'hidden';
42 | this._refCards.forEach((card) => cardContent.appendChild(card));
43 | if (config.horizontal) {
44 | cardContent.style.display = 'flex';
45 | cardContent.childNodes.forEach((card) => {
46 | card.style.flex = '1 1 0';
47 | card.style.minWidth = 0;
48 | });
49 | }
50 | card.appendChild(cardContent);
51 | while (this.hasChildNodes()) {
52 | this.removeChild(this.lastChild);
53 | }
54 | this.appendChild(card);
55 |
56 | // Calculate card size
57 | this._cardSize.resolve();
58 | }
59 |
60 | async createCardElement(cardConfig) {
61 | const createError = (error, origConfig) => {
62 | return createThing('hui-error-card', {
63 | type: 'error',
64 | error,
65 | origConfig
66 | });
67 | };
68 |
69 | const createThing = (tag, config) => {
70 | if (this.helpers) {
71 | if (config.type === 'divider') {
72 | return this.helpers.createRowElement(config);
73 | } else {
74 | return this.helpers.createCardElement(config);
75 | }
76 | }
77 |
78 | const element = document.createElement(tag);
79 | try {
80 | element.setConfig(config);
81 | } catch (err) {
82 | console.error(tag, err);
83 | return createError(err.message, config);
84 | }
85 | return element;
86 | };
87 |
88 | let tag = cardConfig.type;
89 | if (tag.startsWith('divider')) {
90 | tag = `hui-divider-row`;
91 | } else if (tag.startsWith('custom:')) {
92 | tag = tag.substr('custom:'.length);
93 | } else {
94 | tag = `hui-${tag}-card`;
95 | }
96 |
97 | const element = createThing(tag, cardConfig);
98 | element.hass = this._hass;
99 | element.addEventListener(
100 | 'll-rebuild',
101 | (ev) => {
102 | ev.stopPropagation();
103 | this.createCardElement(cardConfig).then(() => {
104 | this.renderCard();
105 | });
106 | },
107 | { once: true }
108 | );
109 | return element;
110 | }
111 |
112 | set hass(hass) {
113 | this._hass = hass;
114 | if (this._refCards) {
115 | this._refCards.forEach((card) => {
116 | card.hass = hass;
117 | });
118 | }
119 | }
120 |
121 | styleCard(element) {
122 | const config = this._config;
123 | if (element.shadowRoot) {
124 | if (element.shadowRoot.querySelector('ha-card')) {
125 | let ele = element.shadowRoot.querySelector('ha-card');
126 | ele.style.boxShadow = 'none';
127 | ele.style.borderRadius = '0';
128 | if ('styles' in config) {
129 | Object.entries(config.styles).forEach(([key, value]) => ele.style.setProperty(key, value));
130 | }
131 | } else {
132 | let searchEles = element.shadowRoot.getElementById('root');
133 | if (!searchEles) {
134 | searchEles = element.shadowRoot.getElementById('card');
135 | }
136 | if (!searchEles) return;
137 | searchEles = searchEles.childNodes;
138 | for (let i = 0; i < searchEles.length; i++) {
139 | if (searchEles[i].style) {
140 | searchEles[i].style.margin = '0px';
141 | }
142 | this.styleCard(searchEles[i]);
143 | }
144 | }
145 | } else {
146 | if (typeof element.querySelector === 'function' && element.querySelector('ha-card')) {
147 | let ele = element.querySelector('ha-card');
148 | ele.style.boxShadow = 'none';
149 | ele.style.borderRadius = '0';
150 | if ('styles' in config) {
151 | Object.entries(config.styles).forEach(([key, value]) => ele.style.setProperty(key, value));
152 | }
153 | }
154 | let searchEles = element.childNodes;
155 | for (let i = 0; i < searchEles.length; i++) {
156 | if (searchEles[i] && searchEles[i].style) {
157 | searchEles[i].style.margin = '0px';
158 | }
159 | this.styleCard(searchEles[i]);
160 | }
161 | }
162 | }
163 |
164 | _computeCardSize(card) {
165 | if (typeof card.getCardSize === 'function') {
166 | return card.getCardSize();
167 | }
168 | return customElements
169 | .whenDefined(card.localName)
170 | .then(() => this._computeCardSize(card))
171 | .catch(() => 1);
172 | }
173 |
174 | async getCardSize() {
175 | await this._cardSize.promise;
176 | const sizes = await Promise.all(this._refCards.map(this._computeCardSize));
177 | return sizes.reduce((a, b) => a + b);
178 | }
179 | }
180 |
181 | customElements.define('vertical-stack-in-card', VerticalStackInCard);
182 |
--------------------------------------------------------------------------------
/www/community/vertical-stack-in-card/vertical-stack-in-card.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TBens/lovelace-ui-minimalist/db4b250248c4c6a1666061d358844ee529c4cd99/www/community/vertical-stack-in-card/vertical-stack-in-card.js.gz
--------------------------------------------------------------------------------