├── automations.yaml
├── configuration.yaml
├── custom_components
└── customizer
│ ├── __init__.py
│ └── services.yaml
├── groups.yaml
├── helm.yaml
├── packages
├── loc_zane.yaml
├── obd.yaml
├── speedify.yaml
└── verizon.yaml
├── scripts.yaml
├── themes
├── google-home.yaml
└── light-navy-blue.yaml
├── update.sh
└── www
├── card-mod.js
├── custom_ui
├── scripts-es5.js.LICENSE
├── scripts-es5.js.map
├── scripts.js.LICENSE
├── scripts.js.map
├── state-card-custom-ui-es5.html
├── state-card-custom-ui-es5.html.gz
├── state-card-custom-ui.html
└── state-card-custom-ui.html.gz
├── kiosk.css
├── kiosk.js
├── mini-graph-card-bundle.js
├── monster-card.js
└── photos
├── van-overhead.jpg
└── van-side.jpg
/automations.yaml:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/configuration.yaml:
--------------------------------------------------------------------------------
1 | homeassistant:
2 | packages: !include_dir_named packages
3 | customize_glob:
4 | "sensor.speedify_status_*":
5 | templates:
6 | friendly_name: >-
7 | if (state === 'disconnected') return 'disconnected';
8 | else if (attributes.type == 'Wi-Fi') return attributes.connectedNetworkName;
9 | else return attributes.type;
10 | icon: >-
11 | if (state === 'disconnected') {
12 | if (attributes.type == 'Wi-Fi') return 'mdi:wifi-strength-off-outline';
13 | else return 'mdi:signal-off';
14 | }
15 | else if (attributes.type == 'Wi-Fi') return 'mdi:wifi-strength-4';
16 | else return 'mdi:signal-4g';
17 | auth_providers:
18 | - type: homeassistant
19 | # - type: trusted_networks
20 | # allow_bypass_login: true
21 | # trusted_networks:
22 | # - !secret ip_self
23 | # trusted_users:
24 | # !secret ip_local_network_all: !secret guest_user
25 |
26 | http:
27 | server_port: 8123
28 | base_url: !secret base_url
29 | use_x_forwarded_for: true
30 | trusted_proxies:
31 | - 127.0.0.1
32 | - !secret gateway
33 | cors_allowed_origins:
34 | - https://google.com
35 | - https://www.home-assistant.io
36 | # - http://house.local
37 | ip_ban_enabled: false
38 |
39 | # custom_updater:
40 | # show_installable: false
41 | # hide_sensor: false
42 | # track:
43 | # - components
44 | # - cards
45 | # - python_scripts
46 | # component_urls:
47 | # - https://raw.githubusercontent.com/keatontaylor/custom_components/master/custom_components.json
48 | # card_urls:
49 | # - https://raw.githubusercontent.com/kalkih/mini-media-player/master/tracker.json
50 | # - https://raw.githubusercontent.com/kalkih/mini-graph-card/master/tracker.json
51 |
52 | frontend:
53 | javascript_version: latest
54 | themes: !include_dir_merge_named themes
55 | extra_html_url:
56 | - /local/custom_ui/state-card-custom-ui.html
57 | extra_html_url_es5:
58 | - /local/custom_ui/state-card-custom-ui-es5.html
59 |
60 | # Configure a default setup of Home Assistant (frontend, api, etc)
61 | default_config:
62 |
63 | # Text to speech
64 | tts:
65 | - platform: google_translate
66 |
67 | group: !include groups.yaml
68 | automation: !include automations.yaml
69 | script: !include scripts.yaml
70 |
71 | mqtt:
72 | broker: !secret ip_self
73 |
--------------------------------------------------------------------------------
/custom_components/customizer/__init__.py:
--------------------------------------------------------------------------------
1 | """Customizer component. Bring extra customize features to home-assistant."""
2 |
3 | import asyncio
4 | import logging
5 | import os
6 |
7 | import homeassistant.components.frontend as frontend
8 | import homeassistant.helpers.config_validation as cv
9 | from homeassistant.config import load_yaml_config_file, DATA_CUSTOMIZE
10 | from homeassistant.core import callback
11 |
12 | from homeassistant.helpers.entity import Entity
13 | from homeassistant.helpers.entity_component import EntityComponent
14 | from homeassistant.const import CONF_ENTITY_ID, MINOR_VERSION
15 |
16 | import voluptuous as vol
17 |
18 | _LOGGER = logging.getLogger(__name__)
19 |
20 | DOMAIN = 'customizer'
21 | DEPENDENCIES = ['frontend']
22 |
23 | CONF_CUSTOM_UI = 'custom_ui'
24 |
25 | LOCAL = 'local'
26 | HOSTED = 'hosted'
27 | DEBUG = 'debug'
28 |
29 | CONF_HIDE_ATTRIBUTES = 'hide_attributes'
30 |
31 | CONF_ATTRIBUTE = 'attribute'
32 | CONF_VALUE = 'value'
33 | CONF_COLUMNS = 'columns'
34 |
35 | SERVICE_SET_ATTRIBUTE = 'set_attribute'
36 | SERVICE_SET_ATTRIBUTE_SCHEMA = vol.Schema({
37 | vol.Required(CONF_ENTITY_ID): cv.entity_id,
38 | vol.Required(CONF_ATTRIBUTE): cv.string,
39 | vol.Optional(CONF_VALUE): cv.match_all,
40 | })
41 |
42 | CONFIG_SCHEMA = vol.Schema({
43 | DOMAIN: vol.Schema({
44 | vol.Optional(CONF_CUSTOM_UI): cv.string,
45 | vol.Optional(CONF_COLUMNS): [int],
46 | vol.Optional(CONF_HIDE_ATTRIBUTES):
47 | vol.All(cv.ensure_list, [cv.string]),
48 | })
49 | }, extra=vol.ALLOW_EXTRA)
50 |
51 |
52 | @asyncio.coroutine
53 | def async_setup(hass, config):
54 | """Set up customizer."""
55 | custom_ui = config[DOMAIN].get(CONF_CUSTOM_UI)
56 | if MINOR_VERSION < 53 and custom_ui is not None:
57 | _LOGGER.warning('%s is only supported from Home Assistant 0.53',
58 | CONF_CUSTOM_UI)
59 | elif custom_ui is not None:
60 | def add_extra_html_url(base_url):
61 | """Add extra url using version-dependent function."""
62 | if MINOR_VERSION >= 59:
63 | frontend.add_extra_html_url(
64 | hass, '{}.html'.format(base_url), False)
65 | frontend.add_extra_html_url(
66 | hass, '{}-es5.html'.format(base_url), True)
67 | else:
68 | frontend.add_extra_html_url(hass, '{}.html'.format(base_url))
69 |
70 | if custom_ui == LOCAL:
71 | add_extra_html_url('/local/custom_ui/state-card-custom-ui')
72 | elif custom_ui == HOSTED:
73 | add_extra_html_url(
74 | 'https://raw.githubusercontent.com/andrey-git/'
75 | 'home-assistant-custom-ui/master/state-card-custom-ui')
76 | elif custom_ui == DEBUG:
77 | add_extra_html_url(
78 | 'https://raw.githubusercontent.com/andrey-git/'
79 | 'home-assistant-custom-ui/master/'
80 | 'state-card-custom-ui-dbg')
81 | else:
82 | add_extra_html_url(
83 | 'https://github.com/andrey-git/home-assistant-custom-ui/'
84 | 'releases/download/{}/state-card-custom-ui'
85 | .format(custom_ui))
86 |
87 | component = EntityComponent(_LOGGER, DOMAIN, hass)
88 | yield from component.async_add_entities([CustomizerEntity(config[DOMAIN])])
89 |
90 | @callback
91 | def set_attribute(call):
92 | """Set attribute override."""
93 | data = call.data
94 | entity_id = data[CONF_ENTITY_ID]
95 | attribute = data[CONF_ATTRIBUTE]
96 | value = data.get(CONF_VALUE)
97 | overrides = hass.data[DATA_CUSTOMIZE].get(entity_id)
98 | state = hass.states.get(entity_id)
99 | state_attributes = dict(state.attributes)
100 | if value is None:
101 | if attribute in overrides:
102 | overrides.pop(attribute)
103 | if attribute in state_attributes:
104 | state_attributes.pop(attribute)
105 | else:
106 | overrides[attribute] = value
107 | state_attributes[attribute] = value
108 | hass.states.async_set(entity_id, state.state, state_attributes)
109 |
110 | if MINOR_VERSION >= 61:
111 | hass.services.async_register(DOMAIN, SERVICE_SET_ATTRIBUTE,
112 | set_attribute,
113 | SERVICE_SET_ATTRIBUTE_SCHEMA)
114 | else:
115 | descriptions = yield from hass.async_add_job(
116 | load_yaml_config_file, os.path.join(
117 | os.path.dirname(__file__), 'services.yaml'))
118 | hass.services.async_register(DOMAIN, SERVICE_SET_ATTRIBUTE,
119 | set_attribute,
120 | descriptions[SERVICE_SET_ATTRIBUTE],
121 | SERVICE_SET_ATTRIBUTE_SCHEMA)
122 |
123 | return True
124 |
125 |
126 | class CustomizerEntity(Entity):
127 | """Customizer entity class."""
128 |
129 | def __init__(self, config):
130 | """Constructor that parses the config."""
131 | self.hide_attributes = config.get(CONF_HIDE_ATTRIBUTES)
132 | self.columns = config.get(CONF_COLUMNS)
133 |
134 | @property
135 | def hidden(self):
136 | """Don't show the entity."""
137 | return True
138 |
139 | @property
140 | def name(self):
141 | """Singleton name."""
142 | return DOMAIN
143 |
144 | @property
145 | def state_attributes(self):
146 | """Return the state attributes."""
147 | result = {}
148 | if self.hide_attributes:
149 | result[CONF_HIDE_ATTRIBUTES] = self.hide_attributes
150 | if self.columns:
151 | result[CONF_COLUMNS] = self.columns
152 | return result
153 |
--------------------------------------------------------------------------------
/custom_components/customizer/services.yaml:
--------------------------------------------------------------------------------
1 | set_attribute:
2 | description: >
3 | Set or clear persistent attribute of an entity overriding any value set in code.
4 | Note that calling homeassistant.reload_core_config will reset overrides to their yaml state.
5 | fields:
6 | entity_id:
7 | description: Entity ID to set the attribute on.
8 | example: light.patio
9 | attribute:
10 | description: Name of the attribute to set.
11 | example: friendly_name
12 | value:
13 | description: >
14 | (Optional) Value to set. Leave unspecified in order to clear set value.
15 | Note that when clearing attribute it will be empty (and not set-by-code) until next entity update.
16 | example: 'My light'
17 |
--------------------------------------------------------------------------------
/groups.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zaneclaes/van-home-assistant-config/907196e279a1f9bccc25649bf42c1c99773e50c1/groups.yaml
--------------------------------------------------------------------------------
/helm.yaml:
--------------------------------------------------------------------------------
1 | hostNetwork: true
2 |
3 | image:
4 | tag: 0.100.3
5 |
6 | persistence:
7 | hostPath: /home/pi/home-assistant
8 |
9 | # hostMounts:
10 | # - name: zha
11 | # hostPath: /dev/serial/by-id/usb-Silicon_Labs_HubZ_Smart_Home_Controller_6120245D-if01-port0
12 | # - name: zwave
13 | # hostPath: /dev/serial/by-id/usb-Silicon_Labs_HubZ_Smart_Home_Controller_6120245D-if00-port0
14 |
--------------------------------------------------------------------------------
/packages/loc_zane.yaml:
--------------------------------------------------------------------------------
1 | sensor:
2 | - name: 'ZanePhone'
3 | platform: mqtt
4 | state_topic: 'owntracks/zane/D1B72C3A-923A-437D-9ABE-8E4416216C6F'
5 | json_attributes_topic: 'owntracks/zane/D1B72C3A-923A-437D-9ABE-8E4416216C6F'
6 | value_template: '{{value_json.batt}}'
7 |
8 | # "batt":98,"lon":-97.997737509999951,"acc":9785,"p":95.547836303710938,"bs":1,"vac":45,"lat":40.875564669999989,"t":"t","conn":"w","tst":1573599940,"alt":534,"_type":"location","tid":"6F"
--------------------------------------------------------------------------------
/packages/obd.yaml:
--------------------------------------------------------------------------------
1 | sensor:
2 | - name: 'Car Speed'
3 | platform: mqtt
4 | state_topic: '/obd/speed'
5 | value_template: '{{value | int}}'
6 | force_update: true
7 | unit_of_measurement: 'Mph'
8 | icon: 'mdi:speedometer'
9 |
10 | - name: 'Car RPM'
11 | platform: mqtt
12 | state_topic: '/obd/rpm'
13 | value_template: '{{value | float | round(2)}}'
14 | force_update: true
15 | unit_of_measurement: 'rpm'
16 | icon: 'mdi:engine'
17 |
18 | - name: 'Car Control Module Voltage'
19 | platform: mqtt
20 | state_topic: '/obd/control_module_voltage'
21 | value_template: '{{value | float | round(2)}}'
22 | force_update: true
23 | unit_of_measurement: 'v'
24 | icon: 'mdi:flash'
25 |
26 | - name: 'Car ELM Voltage'
27 | platform: mqtt
28 | state_topic: '/obd/elm_voltage'
29 | value_template: '{{value | float | round(2)}}'
30 | force_update: true
31 | unit_of_measurement: 'v'
32 | icon: 'mdi:flash'
33 |
34 | - name: 'Car Fuel Level'
35 | platform: mqtt
36 | state_topic: '/obd/fuel_level'
37 | value_template: '{{value | float | round(2)}}'
38 | force_update: true
39 | unit_of_measurement: '%'
40 | icon: 'mdi:gas-station'
41 |
42 | - name: 'Car Ambient Air Temp'
43 | platform: mqtt
44 | state_topic: '/obd/ambiant_air_temp'
45 | value_template: '{{value | float | round(2)}}'
46 | force_update: true
47 | unit_of_measurement: 'F'
48 | icon: 'mdi:thermometer-lines'
49 |
50 | - name: 'Car Barometric Pressure'
51 | platform: mqtt
52 | state_topic: '/obd/barometric_pressure'
53 | value_template: '{{value | float | round(2)}}'
54 | force_update: true
55 | unit_of_measurement: 'kPa'
56 | icon: 'mdi:weight'
57 |
58 | - name: 'Car Run Time'
59 | platform: mqtt
60 | state_topic: '/obd/run_time'
61 | value_template: '{{value | float | round(2)}}'
62 | force_update: true
63 | unit_of_measurement: 's'
64 | icon: 'mdi:timer'
65 |
66 | - name: 'Car Accelerator Position (D)'
67 | platform: mqtt
68 | state_topic: '/obd/accelerator_pos_d'
69 | value_template: '{{value | float | round(2)}}'
70 | force_update: true
71 | unit_of_measurement: '%'
72 | icon: 'mdi:van-utility'
73 |
74 | - name: 'Car Accelerator Position (E)'
75 | platform: mqtt
76 | state_topic: '/obd/accelerator_pos_e'
77 | value_template: '{{value | float | round(2)}}'
78 | force_update: true
79 | unit_of_measurement: '%'
80 | icon: 'mdi:van-utility'
81 |
82 | - name: 'Car Throttle Position'
83 | platform: mqtt
84 | state_topic: '/obd/throttle_pos'
85 | value_template: '{{value | float | round(2)}}'
86 | force_update: true
87 | unit_of_measurement: '%'
88 | icon: 'mdi:van-utility'
89 |
90 | - name: 'Car Throttle Position (B)'
91 | platform: mqtt
92 | state_topic: '/obd/throttle_pos_b'
93 | value_template: '{{value | float | round(2)}}'
94 | force_update: true
95 | unit_of_measurement: '%'
96 | icon: 'mdi:van-utility'
97 |
98 | - name: 'Car Throttle Actuator'
99 | platform: mqtt
100 | state_topic: '/obd/throttle_actuator'
101 | value_template: '{{value | float | round(2)}}'
102 | force_update: true
103 | unit_of_measurement: '%'
104 | icon: 'mdi:van-utility'
105 |
106 | - name: 'Car Relative Throttle Position'
107 | platform: mqtt
108 | state_topic: '/obd/relative_throttle_pos'
109 | value_template: '{{value | float | round(2)}}'
110 | force_update: true
111 | unit_of_measurement: '%'
112 | icon: 'mdi:van-utility'
113 |
114 | - name: 'Car Coolant Temp'
115 | platform: mqtt
116 | state_topic: '/obd/coolant_temp'
117 | value_template: '{{value | float | round(2)}}'
118 | force_update: true
119 | unit_of_measurement: 'F'
120 | icon: 'mdi:thermometer-lines'
121 |
122 | - name: 'Car Intake Temp'
123 | platform: mqtt
124 | state_topic: '/obd/intake_temp'
125 | value_template: '{{value | float | round(2)}}'
126 | force_update: true
127 | unit_of_measurement: 'F'
128 | icon: 'mdi:thermometer-lines'
129 |
130 | - name: 'Car Engine Load'
131 | platform: mqtt
132 | state_topic: '/obd/engine_load'
133 | value_template: '{{value | float | round(2)}}'
134 | force_update: true
135 | unit_of_measurement: '%'
136 | icon: 'mdi:van-utility'
137 |
138 | - name: 'Car Absolute Load'
139 | platform: mqtt
140 | state_topic: '/obd/absolute_load'
141 | value_template: '{{value | float | round(2)}}'
142 | force_update: true
143 | unit_of_measurement: '%'
144 | icon: 'mdi:van-utility'
145 |
--------------------------------------------------------------------------------
/packages/speedify.yaml:
--------------------------------------------------------------------------------
1 | sensor:
2 | - name: 'Speedify Status Verizon Jetpack'
3 | platform: mqtt
4 | state_topic: '/speedify/eth1'
5 | json_attributes_topic: '/speedify/eth1'
6 | value_template: '{{value_json.state}}'
7 |
8 | - name: 'Speedify Status WiFi'
9 | platform: mqtt
10 | state_topic: '/speedify/wlan1'
11 | json_attributes_topic: '/speedify/wlan1'
12 | value_template: '{{value_json.state}}'
13 |
14 | - name: 'Speedify Speed - Ping'
15 | platform: mqtt
16 | state_topic: '/speedify/speedtest/speedify'
17 | json_attributes_topic: '/speedify/speedtest/speedify'
18 | value_template: '{{value_json.rttMs | int}}'
19 | icon: 'mdi:speedometer'
20 | unit_of_measurement: 'ms'
21 |
22 | - platform: template
23 | sensors:
24 | speedify_speed_download:
25 | friendly_name_template: "Speedify Speed - Down"
26 | unit_of_measurement: 'Mbps'
27 | value_template: >-
28 | {{ ((states.sensor.speedify_speed_ping.attributes.downloadBps | float) / 1000000) | round(2) }}
29 | icon_template: 'mdi:download-network-outline'
30 |
31 | speedify_speed_upload:
32 | friendly_name_template: "Speedify Speed - Up"
33 | unit_of_measurement: 'Mbps'
34 | value_template: >-
35 | {{ ((states.sensor.speedify_speed_ping.attributes.uploadBps | float) / 1000000) | round(2) }}
36 | icon_template: 'mdi:upload-network-outline'
37 |
--------------------------------------------------------------------------------
/packages/verizon.yaml:
--------------------------------------------------------------------------------
1 | sensor:
2 | - name: 'Verizon Usage Info'
3 | platform: mqtt
4 | state_topic: '/verizon/usage_info'
5 | json_attributes_topic: '/verizon/usage_info'
6 | value_template: '{{value_json.totalShrUsage | float | round(2)}}' # {{ value_json.unit }}
7 | force_update: true
8 | icon: 'mdi:access-point-network'
9 | unit_of_measurement: 'Gb'
10 |
11 | - name: 'Verizon Status Data'
12 | platform: mqtt
13 | state_topic: '/verizon/status_data'
14 | json_attributes_topic: '/verizon/status_data'
15 | value_template: '{{ ((value_json.statusBarBytesTotal | int) / 1000000000) | round(2) }}'
16 | unit_of_measurement: 'Gb'
17 | icon: 'mdi:wan'
18 | force_update: true
19 |
20 | - platform: template
21 | sensors:
22 | verizon_device:
23 | friendly_name_template: "{{ states.sensor.verizon_usage_info.attributes.gProductName }}"
24 | value_template: >-
25 | {{ states.sensor.verizon_status_data.attributes.statusBarNetwork }}
26 | icon_template: 'mdi:cellphone-wireless'
27 |
28 | # Icon = cell strength,
29 | verizon:
30 | friendly_name_template: "Verizon ({{ states.sensor.verizon_usage_info.attributes.daysLeft }} days left)"
31 | unit_of_measurement: 'Gb'
32 | value_template: >-
33 | {{ states.sensor.verizon_usage_info.state }}
34 | icon_template: >
35 | {% if states.sensor.verizon_status_data.attributes.statusBarConnectionState == 'Connected' %}
36 | {% if states.sensor.verizon_status_data.attributes.statusBarSignalBars | int <= 0 %}
37 | mdi:network-strength-outline
38 | {% elif states.sensor.verizon_status_data.attributes.statusBarSignalBars | int == 1 %}
39 | mdi:network-strength-1
40 | {% elif states.sensor.verizon_status_data.attributes.statusBarSignalBars | int == 2 %}
41 | mdi:network-strength-2
42 | {% elif states.sensor.verizon_status_data.attributes.statusBarSignalBars | int == 3 %}
43 | mdi:network-strength-3
44 | {% elif states.sensor.verizon_status_data.attributes.statusBarSignalBars | int >= 4 %}
45 | mdi:network-strength-4
46 | {% endif %}
47 | {% else %}
48 | mdi:network-strength-off-outline
49 | {% endif %}
50 |
51 |
--------------------------------------------------------------------------------
/scripts.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zaneclaes/van-home-assistant-config/907196e279a1f9bccc25649bf42c1c99773e50c1/scripts.yaml
--------------------------------------------------------------------------------
/themes/google-home.yaml:
--------------------------------------------------------------------------------
1 | Google - Light:
2 | # accent: "#FF4081"
3 | # sidebar-selected-text-color: "var(--accent)"
4 |
5 | ### Fonts ###
6 | primary-font-family: "'Open Sans','Rubik',Roboto,sans-serif"
7 | paper-font-common-base_-_font-family: "var(--primary-font-family)"
8 | paper-font-common-code_-_font-family: "var(--primary-font-family)"
9 | paper-font-body_-_font-family: "var(--primary-font-family)"
10 | paper-font-subhead_-_font-family: "var(--primary-font-family)"
11 | paper-font-headline_-_font-family: "var(--primary-font-family)"
12 | paper-font-caption_-_font-family: "var(--primary-font-family)"
13 | paper-font-title_-_font-family: "var(--primary-font-family)"
14 |
15 | ha-card-border-radius: "5px"
16 | ha-card-header-color: "#757575"
17 | ha-card-header-background-color: "#eeeeee"
18 | ha-card-header-padding: "8px 16px 6px"
19 | ha-card-box-shadow: "0px 0px 1px #eeeeee"
20 |
21 | ### Main Interface Colors ###
22 | primary-color: "#ffffff"
23 | light-primary-color: "#c1c1c1"
24 | primary-background-color: "#eeeeee" # "#F7F9FB"
25 | secondary-background-color: "#ffffff"
26 | divider-color: "#e7e7e7"
27 | paper-icon-button-active-color: "#061014"
28 | paper-icon-button-inactive-color: "#a1a1a1"
29 | ### Text ###
30 | primary-text-color: "#000000"
31 | secondary-text-color: "#757575"
32 | text-primary-color: "#061014"
33 | disabled-text-color: "#a1a1a1"
34 | ### Sidebar Menu ###
35 | sidebar-background-color: "#ffffff"
36 | sidebar-icon-color: "#757575"
37 | sidebar-text-color: "#212121"
38 | sidebar-selected-background-color: var(--primary-background-color)
39 | sidebar-selected-icon-color: "#4284F4"
40 | sidebar-selected-text-color: var(--sidebar-selected-icon-color)
41 | ### States and Badges ###
42 | state-icon-color: "#606367"
43 | state-icon-active-color: "#ffb750"
44 | state-icon-unavailable-color: var(--disabled-text-color)
45 | ### Sliders ###
46 | paper-slider-knob-color: "#4284F4"
47 | paper-slider-knob-start-color: "#8eb8ff"
48 | paper-slider-pin-color: "#8eb8ff"
49 | paper-slider-active-color: "#8eb8ff"
50 | paper-slider-secondary-color: var(--light-primary-color)
51 | paper-slider-container-color: "#e7e7e7"
52 | ### Labels ###
53 | label-badge-background-color: "#252B36"
54 | label-badge-text-color: "#F1F1F1"
55 | label-badge-red: "#6C7B9B"
56 | ### Cards ###
57 | paper-card-background-color: "#ffffff"
58 | paper-listbox-background-color: "#ffffff"
59 | ### Toggles ###
60 | paper-toggle-button-checked-button-color: "#4284F4"
61 | paper-toggle-button-checked-bar-color: "#4284F4"
62 | paper-toggle-button-unchecked-button-color: "#4284F4"
63 | paper-toggle-button-unchecked-bar-color: "#c1c1c1"
64 |
65 | ### Dialog ###
66 | paper-dialog-background-color: "#ffffff"
67 |
68 | ### Table row ###
69 | table-row-background-color: var(--primary-background-color)
70 | table-row-alternative-background-color: var(--secondary-background-color)
71 |
72 | iron-overlay-backdrop-background-color: "#ffffff"
73 | mdc-theme-primary: "#4284F4"
74 |
75 | Google - Dark:
76 | ### Fonts ###
77 | primary-font-family: "'Open Sans','Rubik',Roboto,sans-serif"
78 | paper-font-common-base_-_font-family: "var(--primary-font-family)"
79 | paper-font-common-code_-_font-family: "var(--primary-font-family)"
80 | paper-font-body_-_font-family: "var(--primary-font-family)"
81 | paper-font-subhead_-_font-family: "var(--primary-font-family)"
82 | paper-font-headline_-_font-family: "var(--primary-font-family)"
83 | paper-font-caption_-_font-family: "var(--primary-font-family)"
84 | paper-font-title_-_font-family: "var(--primary-font-family)"
85 |
86 | ha-card-border-radius: "0px"
87 | ha-card-header-color: "#d7d7d7"
88 | ha-card-box-shadow: "0px 0px 1px #000000"
89 |
90 | ### Main Interface Colors ###
91 | primary-color: "#000000"
92 | light-primary-color: "#2b2b2b"
93 | primary-background-color: "#000000"
94 | secondary-background-color: "#2b2b2b"
95 | divider-color: "#2b2b2b"
96 | paper-icon-button-active-color: "#ffffff"
97 | paper-icon-button-inactive-color: "#a1a1a1"
98 | ### Text ###
99 | primary-text-color: "#ffffff"
100 | secondary-text-color: "#d7d7d7"
101 | text-primary-color: "#ffffff"
102 | disabled-text-color: "#a1a1a1"
103 | ### Sidebar Menu ###
104 | sidebar-background-color: "#000000"
105 | sidebar-icon-color: "#ffffff"
106 | sidebar-text-color: "#ffffff"
107 | sidebar-selected-background-color: var(--primary-background-color)
108 | sidebar-selected-icon-color: "#4284F4"
109 | sidebar-selected-text-color: var(--sidebar-selected-icon-color)
110 | ### States and Badges ###
111 | state-icon-color: "#ffffff"
112 | state-icon-active-color: "#ffb750"
113 | state-icon-unavailable-color: var(--disabled-text-color)
114 | ### Sliders ###
115 | paper-slider-knob-color: "#4284F4"
116 | paper-slider-knob-start-color: "#8eb8ff"
117 | paper-slider-pin-color: "#8eb8ff"
118 | paper-slider-active-color: "#8eb8ff"
119 | paper-slider-secondary-color: var(--light-primary-color)
120 | paper-slider-container-color: "#a1a1a1"
121 | ### Labels ###
122 | label-badge-background-color: "#252B36"
123 | label-badge-text-color: "#F1F1F1"
124 | label-badge-red: "#6C7B9B"
125 | ### Cards ###
126 | paper-card-background-color: "#2b2b2b"
127 | paper-listbox-background-color: "#000000"
128 | ### Toggles ###
129 | paper-toggle-button-checked-button-color: "#4284F4"
130 | paper-toggle-button-checked-bar-color: "#4284F4"
131 | paper-toggle-button-unchecked-button-color: "#4284F4"
132 | paper-toggle-button-unchecked-bar-color: "#c1c1c1"
133 |
134 | ### Dialog ###
135 | paper-dialog-background-color: "#2b2b2b"
136 |
137 | ### Table row ###
138 | table-row-background-color: var(--primary-background-color)
139 | table-row-alternative-background-color: var(--secondary-background-color)
140 |
141 | iron-overlay-backdrop-background-color: "#000000"
142 | mdc-theme-primary: "#4284F4"
143 |
144 | Smart - Dark:
145 | ### Fonts ###
146 | primary-font-family: "'Open Sans','Rubik',Roboto,sans-serif"
147 | paper-font-common-base_-_font-family: "var(--primary-font-family)"
148 | paper-font-common-code_-_font-family: "var(--primary-font-family)"
149 | paper-font-body_-_font-family: "var(--primary-font-family)"
150 | paper-font-subhead_-_font-family: "var(--primary-font-family)"
151 | paper-font-headline_-_font-family: "var(--primary-font-family)"
152 | paper-font-caption_-_font-family: "var(--primary-font-family)"
153 | paper-font-title_-_font-family: "var(--primary-font-family)"
154 |
155 | ha-card-border-radius: "5px"
156 |
157 | ### Main Interface Colors ###
158 | primary-color: "#000000"
159 | light-primary-color: "#B5B5B5"
160 | primary-background-color: "#000000"
161 | secondary-background-color: var(--primary-background-color)
162 | divider-color: "#2a2a2a"
163 | ### Text ###
164 | primary-text-color: "#ffffff"
165 | secondary-text-color: "#ffffff"
166 | text-primary-color: "#ffffff"
167 | disabled-text-color: "#a1a1a1"
168 | ### Sidebar Menu ###
169 | sidebar-background-color: "#000000"
170 | sidebar-icon-color: "#B5B5B5"
171 | sidebar-text-color: "#ffffff"
172 | sidebar-selected-background-color: var(--primary-background-color)
173 | sidebar-selected-icon-color: "#4197FE"
174 | sidebar-selected-text-color: "#ffffff"
175 | ### States and Badges ###
176 | state-icon-color: "#B5B5B5"
177 | state-icon-active-color: "#ffb750"
178 | state-icon-unavailable-color: var(--disabled-text-color)
179 | ### Sliders ###
180 | paper-slider-knob-color: "#E59D37"
181 | paper-slider-knob-start-color: "#ffd89f"
182 | paper-slider-pin-color: "#ffd89f"
183 | paper-slider-active-color: "#ffd89f"
184 | paper-slider-secondary-color: var(--light-primary-color)
185 | paper-slider-container-color: "#4e4e4e"
186 | ### Labels ###
187 | label-badge-background-color: "#0057f5"
188 | label-badge-text-color: "#F1F1F1"
189 | label-badge-red: "#6C7B9B"
190 | ### Cards ###
191 | paper-card-background-color: "#2c2c2c"
192 | paper-listbox-background-color: var(--primary-background-color)
193 | ### Toggles ###
194 | paper-toggle-button-checked-button-color: "#ffb750"
195 | paper-toggle-button-checked-bar-color: "#ffb750"
196 | paper-toggle-button-unchecked-button-color: "#6da3ff"
197 | paper-toggle-button-unchecked-bar-color: "#c1c1c1"
198 | ### Table row ###
199 | table-row-background-color: var(--primary-background-color)
200 | table-row-alternative-background-color: var(--secondary-background-color)
201 |
202 | iron-overlay-backdrop-background-color: "#B5B5B5"
203 | mdc-theme-primary: "#4197FE"
204 |
205 | Smart - Light:
206 | ### Fonts ###
207 | primary-font-family: "'Open Sans','Rubik',Roboto,sans-serif"
208 | paper-font-common-base_-_font-family: "var(--primary-font-family)"
209 | paper-font-common-code_-_font-family: "var(--primary-font-family)"
210 | paper-font-body_-_font-family: "var(--primary-font-family)"
211 | paper-font-subhead_-_font-family: "var(--primary-font-family)"
212 | paper-font-headline_-_font-family: "var(--primary-font-family)"
213 | paper-font-caption_-_font-family: "var(--primary-font-family)"
214 | paper-font-title_-_font-family: "var(--primary-font-family)"
215 |
216 | ha-card-border-radius: "5px"
217 |
218 | ### Main Interface Colors ###
219 | primary-color: "#ffffff"
220 | light-primary-color: "#c1c1c1"
221 | primary-background-color: "#ffffff"
222 | secondary-background-color: var(--primary-background-color)
223 | divider-color: "#e7e7e7"
224 | ### Text ###
225 | primary-text-color: "#757575"
226 | secondary-text-color: "#757575"
227 | text-primary-color: "#757575"
228 | disabled-text-color: "#a1a1a1"
229 | ### Sidebar Menu ###
230 | sidebar-background-color: "#ffffff"
231 | sidebar-icon-color: "#757575"
232 | sidebar-text-color: "#212121"
233 | sidebar-selected-background-color: var(--primary-background-color)
234 | sidebar-selected-icon-color: "#4284F4"
235 | sidebar-selected-text-color: var(--sidebar-selected-icon-color)
236 | ### States and Badges ###
237 | state-icon-color: "#606367"
238 | state-icon-active-color: "#ffb750"
239 | state-icon-unavailable-color: var(--disabled-text-color)
240 | ### Sliders ###
241 | paper-slider-knob-color: "#E59D37"
242 | paper-slider-knob-start-color: "#ffd89f"
243 | paper-slider-pin-color: "#ffd89f"
244 | paper-slider-active-color: "#ffd89f"
245 | paper-slider-secondary-color: var(--light-primary-color)
246 | paper-slider-container-color: "#e7e7e7"
247 | ### Labels ###
248 | label-badge-background-color: "#252B36"
249 | label-badge-text-color: "#F1F1F1"
250 | label-badge-red: "#6C7B9B"
251 | ### Cards ###
252 | paper-card-background-color: "#ffffff"
253 | paper-listbox-background-color: var(--primary-background-color)
254 | ### Toggles ###
255 | paper-toggle-button-checked-button-color: "#ffb750"
256 | paper-toggle-button-checked-bar-color: "#ffb750"
257 | paper-toggle-button-unchecked-button-color: "#4284F4"
258 | paper-toggle-button-unchecked-bar-color: "#c1c1c1"
259 | ### Table row ###
260 | table-row-background-color: var(--primary-background-color)
261 | table-row-alternative-background-color: var(--secondary-background-color)
262 |
263 | iron-overlay-backdrop-background-color: "#ffffff"
264 | mdc-theme-primary: "#4284F4"
--------------------------------------------------------------------------------
/themes/light-navy-blue.yaml:
--------------------------------------------------------------------------------
1 | Light - Navy Blue:
2 | ### Main Interface Colors ###
3 | primary-color: "#395274"
4 | light-primary-color: "#5F81B0"
5 | primary-background-color: "#F6F7F9"
6 | secondary-background-color: var(--primary-background-color)
7 | divider-color: "#D6DFEB"
8 | ### Text ###
9 | primary-text-color: "#395274"
10 | secondary-text-color: "#FF6262"
11 | text-primary-color: "#FFFFFF"
12 | disabled-text-color: "#88A1C4"
13 | ### Sidebar Menu ###
14 | sidebar-icon-color: "#395274"
15 | sidebar-text-color: var(--sidebar-icon-color)
16 | sidebar-selected-background-color: var(--primary-background-color)
17 | sidebar-selected-icon-color: "#FF6262"
18 | sidebar-selected-text-color: var(--sidebar-selected-icon-color)
19 | ### States and Badges ###
20 | state-icon-color: "#FF6262"
21 | state-icon-active-color: "#FBCD41"
22 | state-icon-unavailable-color: var(--disabled-text-color)
23 | ### Sliders ###
24 | paper-slider-knob-color: "#FF6262"
25 | paper-slider-knob-start-color: var(--paper-slider-knob-color)
26 | paper-slider-pin-color: var(--paper-slider-knob-color)
27 | paper-slider-active-color: var(--paper-slider-knob-color)
28 | paper-slider-secondary-color: var(--light-primary-color)
29 | ### Labels ###
30 | label-badge-background-color: "#FFFFFF"
31 | label-badge-text-color: "#395274"
32 | label-badge-red: "#FF8888"
33 | ### Cards ###
34 | paper-card-background-color: "#FFFFFF"
35 | paper-listbox-background-color: var(--primary-background-color)
36 | ### Toggles ###
37 | paper-toggle-button-checked-button-color: "#FF6262"
38 | paper-toggle-button-checked-bar-color: "#FFA3A3"
39 | paper-toggle-button-unchecked-button-color: "#FF6262"
40 | paper-toggle-button-unchecked-bar-color: "#9CB2CE"
41 | ### Table row ###
42 | table-row-background-color: var(--primary-background-color)
43 | table-row-alternative-background-color: var(--secondary-background-color)
--------------------------------------------------------------------------------
/update.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function get_file {
4 | DOWNLOAD_PATH=${2}?raw=true
5 | FILE_NAME=$1
6 | if [ "${FILE_NAME:0:1}" = "/" ]; then
7 | SAVE_PATH=$FILE_NAME
8 | else
9 | SAVE_PATH=$3$FILE_NAME
10 | fi
11 | TMP_NAME=${1}.tmp
12 | echo "Getting $1"
13 | # wget $DOWNLOAD_PATH -q -O $TMP_NAME
14 | curl -s -q -L -o $TMP_NAME $DOWNLOAD_PATH
15 | rv=$?
16 | if [ $rv != 0 ]; then
17 | rm $TMP_NAME
18 | echo "Download failed with error $rv"
19 | exit
20 | fi
21 | diff ${SAVE_PATH} $TMP_NAME &>/dev/null
22 | if [ $? == 0 ]; then
23 | echo "File up to date."
24 | rm $TMP_NAME
25 | return 0
26 | else
27 | mv $TMP_NAME ${SAVE_PATH}
28 | if [ $1 == $0 ]; then
29 | chmod u+x $0
30 | echo "Restarting"
31 | $0
32 | exit $?
33 | else
34 | return 1
35 | fi
36 | fi
37 | }
38 |
39 | function get_file_and_gz {
40 | get_file $1 $2 $3
41 | r1=$?
42 | get_file ${1}.gz ${2}.gz $3
43 | r2=$?
44 | if (( $r1 != 0 || $r2 != 0 )); then
45 | return 1
46 | fi
47 | return 0
48 | }
49 |
50 | function check_dir {
51 | if [ ! -d $1 ]; then
52 | read -p "$1 dir not found. Create? (y/n): [n] " r
53 | r=${r:-n}
54 | if [[ $r == 'y' || $r == 'Y' ]]; then
55 | mkdir -p $1
56 | else
57 | exit
58 | fi
59 | fi
60 | }
61 |
62 | if [ ! -f configuration.yaml ]; then
63 | echo "There is no configuration.yaml in current dir. 'update.sh' should run from Homeassistant config dir"
64 | read -p "Are you sure you want to continue? (y/n): [n] " r
65 | r=${r:-n}
66 | if [[ $r == 'n' || $r == 'N' ]]; then
67 | exit
68 | fi
69 | fi
70 |
71 | get_file $0 https://github.com/andrey-git/home-assistant-custom-ui/blob/master/update.sh ./
72 |
73 |
74 | check_dir "www/custom_ui"
75 |
76 |
77 | get_file scripts.js.map https://github.com/andrey-git/home-assistant-custom-ui/blob/master/scripts.js.map www/custom_ui/
78 | get_file scripts.js.LICENSE https://github.com/andrey-git/home-assistant-custom-ui/blob/master/scripts.js.LICENSE www/custom_ui/
79 | get_file scripts-es5.js.map https://github.com/andrey-git/home-assistant-custom-ui/blob/master/scripts-es5.js.map www/custom_ui/
80 | get_file scripts-es5.js.LICENSE https://github.com/andrey-git/home-assistant-custom-ui/blob/master/scripts-es5.js.LICENSE www/custom_ui/
81 | get_file_and_gz state-card-custom-ui-es5.html https://github.com/andrey-git/home-assistant-custom-ui/blob/master/state-card-custom-ui-es5.html www/custom_ui/
82 | get_file_and_gz state-card-custom-ui.html https://github.com/andrey-git/home-assistant-custom-ui/blob/master/state-card-custom-ui.html www/custom_ui/
83 |
84 |
85 | if [ $? != 0 ]; then
86 | echo "Updated to Custom UI `grep -o -e '"[0-9][0-9][0-9]*"' www/custom_ui/state-card-custom-ui.html`"
87 | fi
88 |
89 |
90 | check_dir "custom_components/customizer"
91 |
92 | get_file __init__.py https://github.com/andrey-git/home-assistant-customizer/blob/master/customizer/__init__.py custom_components/customizer/
93 | get_file services.yaml https://github.com/andrey-git/home-assistant-customizer/blob/master/customizer/services.yaml custom_components/customizer/
94 |
--------------------------------------------------------------------------------
/www/card-mod.js:
--------------------------------------------------------------------------------
1 | !function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";function i(){return document.querySelector("home-assistant").hass}n.r(t);let o=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${e()}${e()}-${e()}${e()}`}return localStorage["lovelace-player-device-id"]}();function a(e,t,n=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},n)n.dispatchEvent(e);else{var i=document.querySelector("home-assistant");(i=(i=(i=(i=(i=(i=(i=(i=(i=(i=(i=i&&i.shadowRoot)&&i.querySelector("home-assistant-main"))&&i.shadowRoot)&&i.querySelector("app-drawer-layout partial-panel-resolver"))&&i.shadowRoot||i)&&i.querySelector("ha-panel-lovelace"))&&i.shadowRoot)&&i.querySelector("hui-root"))&&i.shadowRoot)&&i.querySelector("ha-app-layout #view"))&&i.firstElementChild)&&i.dispatchEvent(e)}}customElements.define("card-mod",class extends HTMLElement{disconnectedCallback(){this._disconnect()}connectedCallback(){this._connect()}_has_template(e){return!!e.template.includes("{%")||!!e.template.includes("{{")}set template(e){this._data=e,this._has_template(e)&&!this._data.entity_ids&&this._data.template.includes("config.entity")&&this._data.variables.config&&this._data.variables.config.entity&&(this._data.entity_ids=[this._data.variables.config.entity])}update(){this._disconnect().then(()=>this._connect())}async _connect(){this._data&&(this._has_template(this._data)||(this.innerHTML=``),this._unsubRenderTemplate||(this._unsubRenderTemplate=function(e,t,n){e||(e=i().connection);let a={user:i().user.name,browser:o,hash:location.hash.substr(1)||" ",...n.variables},s=n.template,r=n.entity_ids;return e.subscribeMessage(e=>t(e.result),{type:"render_template",template:s,variables:a,entity_ids:r})}(null,e=>this.innerHTML=``,this._data),this._unsubRenderTemplate.catch(()=>{this.innerHTML=``,this._unsubRenderTemplate=void 0})))}async _disconnect(){if(this._unsubRenderTemplate)try{const e=await this._unsubRenderTemplate;this._unsubRenderTemplate=void 0,await e()}catch(e){if("not_found"!==e.code)throw e}}});const s=async function(e,t,n,i){const o=function(e){i&&("string"==typeof e?console.log(" ".repeat(2*(i-1))+e):console.log(e))};if(e&&t)if(e.updateComplete&&await e.updateComplete,"string"==typeof t){const i=e.querySelector("card-mod");if(i)return void i.update();const a=document.createElement("card-mod");a.template={template:t,variables:n.variables,entity_ids:n.entity_ids},e.appendChild(a),o("Applied styles to:"),o(e)}else Object.keys(t).forEach(a=>"."===a?(o(`Stepping into root of ${e.tagName}`),s(e,t[a],n,i?i+1:0)):"$"===a?(o(`Stepping into ShadowRoot of ${e.tagName}`),s(e.shadowRoot,t[a],n,i?i+1:0)):(o(`Searching for: "${a}". ${e.querySelectorAll(a).length} matches.`),void e.querySelectorAll(`${a}`).forEach(e=>{o(`Stepping into ${e.tagName}`),s(e,t[a],n,i?i+1:0)})))};customElements.whenDefined("ha-card").then(()=>{const e=customElements.get("ha-card"),t=function(e){return e.config?e.config:e._config?e._config:e.host?t(e.host):e.parentElement?t(e.parentElement):e.parentNode?t(e.parentNode):null};e.prototype.firstUpdated=function(){const e=this.shadowRoot.querySelector(".card-header");e&&this.insertBefore(e,this.children[0]);const n=t(this);if(!n||!n.style)return;let i=n.entity_ids;const o=()=>{s(this,n.style,{variables:{config:n},entity_ids:i},!!n.debug_cardmod)};o(),window.addEventListener("location-changed",()=>o())},a("ll-rebuild",{})}),customElements.whenDefined("hui-entities-card").then(()=>{const e=customElements.get("hui-entities-card"),t=e.prototype.renderEntity;e.prototype.renderEntity=function(e){const n=t.bind(this)(e);if(!e||!e.style)return n;if(!n||!n.values)return n;const i=n.values[0];if(!i||!i.updateComplete)return n;let o=e.entity_ids;const a=()=>{s(i.shadowRoot,e.style,{variables:{config:e},entity_ids:o},!!e.debug_cardmod)};return i.updateComplete.then(a),window.addEventListener("location-changed",a),n},e.prototype._handleClick=function(e){switch(e.tap_action&&e.tap_action.action?e.tap_action.action:"more-info"){case"more-info":a("hass-more-info",{entityId:e.entity},this);break;case"navigate":history.pushState(null,"",e.tap_action.navigation_path),a("location-changed",{},this);break;case"url":e.tap_action.url_path&&window.open(e.tap_action.url_path);break;case"toggle":if(e.entity){const t=e.entity.split(".",1)[0],n=["closed","locked","off"].includes(this._hass.states[e.entity].state),i=({lock:["unlock","lock"],cover:["open_cover","close_cover"]}[t]||["turn_on","turn_off"])[n?0:1];this._hass.callService(t,i,{entity_id:e.entity})}break;case"call-service":{if(!e.tap_action.service)break;const[t,n]=e.tap_action.service.split(".",2);this._hass.callService(t,n,e.tap_action.service_data);break}}},a("ll-rebuild",{})}),customElements.whenDefined("hui-glance-card").then(()=>{customElements.get("hui-glance-card").prototype.firstUpdated=function(){this.shadowRoot.querySelectorAll("ha-card div.entity").forEach(e=>{const t=e.attachShadow({mode:"open"});[...e.children].forEach(e=>t.appendChild(e));const n=document.createElement("style");t.appendChild(n),n.innerHTML="\n :host {\n box-sizing: border-box;\n padding: 0 4px;\n display: flex;\n flex-direction: column;\n align-items: center;\n cursor: pointer;\n margin-bottom: 12px;\n width: var(--glance-column-width, 20%);\n }\n div {\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 }\n state-badge {\n margin: 8px 0;\n }\n ";const i=e.config||e.entityConf;if(!i||!i.style)return;let o=i.entity_ids;const a=()=>{s(t,i.style,{variables:{config:i},entity_ids:o},!!i.debug_cardmod)};a(),window.addEventListener("location-changed",a)})},a("ll-rebuild",{})})}]);
--------------------------------------------------------------------------------
/www/custom_ui/scripts-es5.js.LICENSE:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
4 | * This code may only be used under the BSD style license found at
5 | * http://polymer.github.io/LICENSE.txt
6 | * The complete set of authors may be found at
7 | * http://polymer.github.io/AUTHORS.txt
8 | * The complete set of contributors may be found at
9 | * http://polymer.github.io/CONTRIBUTORS.txt
10 | * Code distributed by Google as part of the polymer project is also
11 | * subject to an additional IP rights grant found at
12 | * http://polymer.github.io/PATENTS.txt
13 | */
14 |
15 | /**
16 | * @license
17 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
18 | * This code may only be used under the BSD style license found at
19 | * http://polymer.github.io/LICENSE.txt
20 | * The complete set of authors may be found at
21 | * http://polymer.github.io/AUTHORS.txt
22 | * The complete set of contributors may be found at
23 | * http://polymer.github.io/CONTRIBUTORS.txt
24 | * Code distributed by Google as part of the polymer project is also
25 | * subject to an additional IP rights grant found at
26 | * http://polymer.github.io/PATENTS.txt
27 | */
28 |
29 | /**
30 | * @license
31 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
32 | * This code may only be used under the BSD style license found at
33 | * http://polymer.github.io/LICENSE.txt
34 | * The complete set of authors may be found at
35 | * http://polymer.github.io/AUTHORS.txt
36 | * The complete set of contributors may be found at
37 | * http://polymer.github.io/CONTRIBUTORS.txt
38 | * Code distributed by Google as part of the polymer project is also
39 | * subject to an additional IP rights grant found at
40 | * http://polymer.github.io/PATENTS.txt
41 | */
42 |
43 | /**
44 | * @license
45 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
46 | * This code may only be used under the BSD style license found at
47 | * http://polymer.github.io/LICENSE.txt
48 | * The complete set of authors may be found at
49 | * http://polymer.github.io/AUTHORS.txt
50 | * The complete set of contributors may be found at
51 | * http://polymer.github.io/CONTRIBUTORS.txt
52 | * Code distributed by Google as part of the polymer project is also
53 | * subject to an additional IP rights grant found at
54 | * http://polymer.github.io/PATENTS.txt
55 | */
56 |
57 | /**
58 | * @license
59 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
60 | * This code may only be used under the BSD style license found at
61 | * http://polymer.github.io/LICENSE.txt
62 | * The complete set of authors may be found at
63 | * http://polymer.github.io/AUTHORS.txt
64 | * The complete set of contributors may be found at
65 | * http://polymer.github.io/CONTRIBUTORS.txt
66 | * Code distributed by Google as part of the polymer project is also
67 | * subject to an additional IP rights grant found at
68 | * http://polymer.github.io/PATENTS.txt
69 | */
70 |
71 | /**
72 | * @license
73 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
74 | * This code may only be used under the BSD style license found at
75 | * http://polymer.github.io/LICENSE.txt
76 | * The complete set of authors may be found at
77 | * http://polymer.github.io/AUTHORS.txt
78 | * The complete set of contributors may be found at
79 | * http://polymer.github.io/CONTRIBUTORS.txt
80 | * Code distributed by Google as part of the polymer project is also
81 | * subject to an additional IP rights grant found at
82 | * http://polymer.github.io/PATENTS.txt
83 | */
84 |
85 | /**
86 | * @license
87 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
88 | * This code may only be used under the BSD style license found at
89 | * http://polymer.github.io/LICENSE.txt
90 | * The complete set of authors may be found at
91 | * http://polymer.github.io/AUTHORS.txt
92 | * The complete set of contributors may be found at
93 | * http://polymer.github.io/CONTRIBUTORS.txt
94 | * Code distributed by Google as part of the polymer project is also
95 | * subject to an additional IP rights grant found at
96 | * http://polymer.github.io/PATENTS.txt
97 | */
98 |
99 | /**
100 | * @license
101 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
102 | * This code may only be used under the BSD style license found at
103 | * http://polymer.github.io/LICENSE.txt
104 | * The complete set of authors may be found at
105 | * http://polymer.github.io/AUTHORS.txt
106 | * The complete set of contributors may be found at
107 | * http://polymer.github.io/CONTRIBUTORS.txt
108 | * Code distributed by Google as part of the polymer project is also
109 | * subject to an additional IP rights grant found at
110 | * http://polymer.github.io/PATENTS.txt
111 | */
112 |
113 | /**
114 | * @license
115 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
116 | * This code may only be used under the BSD style license found at
117 | * http://polymer.github.io/LICENSE.txt
118 | * The complete set of authors may be found at
119 | * http://polymer.github.io/AUTHORS.txt
120 | * The complete set of contributors may be found at
121 | * http://polymer.github.io/CONTRIBUTORS.txt
122 | * Code distributed by Google as part of the polymer project is also
123 | * subject to an additional IP rights grant found at
124 | * http://polymer.github.io/PATENTS.txt
125 | */
126 |
127 | /**
128 | * @license
129 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
130 | * This code may only be used under the BSD style license found at
131 | * http://polymer.github.io/LICENSE.txt
132 | * The complete set of authors may be found at
133 | * http://polymer.github.io/AUTHORS.txt
134 | * The complete set of contributors may be found at
135 | * http://polymer.github.io/CONTRIBUTORS.txt
136 | * Code distributed by Google as part of the polymer project is also
137 | * subject to an additional IP rights grant found at
138 | * http://polymer.github.io/PATENTS.txt
139 | */
140 |
141 | /**
142 | * @license
143 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
144 | * This code may only be used under the BSD style license found at
145 | * http://polymer.github.io/LICENSE.txt
146 | * The complete set of authors may be found at
147 | * http://polymer.github.io/AUTHORS.txt
148 | * The complete set of contributors may be found at
149 | * http://polymer.github.io/CONTRIBUTORS.txt
150 | * Code distributed by Google as part of the polymer project is also
151 | * subject to an additional IP rights grant found at
152 | * http://polymer.github.io/PATENTS.txt
153 | */
154 |
155 | /**
156 | @license
157 | Copyright (c) 2019 The Polymer Project Authors. All rights reserved.
158 | This code may only be used under the BSD style license found at
159 | http://polymer.github.io/LICENSE.txt The complete set of authors may be found at
160 | http://polymer.github.io/AUTHORS.txt The complete set of contributors may be
161 | found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as
162 | part of the polymer project is also subject to an additional IP rights grant
163 | found at http://polymer.github.io/PATENTS.txt
164 | */
165 |
166 | /**
167 | * @license
168 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
169 | * This code may only be used under the BSD style license found at
170 | * http://polymer.github.io/LICENSE.txt
171 | * The complete set of authors may be found at
172 | * http://polymer.github.io/AUTHORS.txt
173 | * The complete set of contributors may be found at
174 | * http://polymer.github.io/CONTRIBUTORS.txt
175 | * Code distributed by Google as part of the polymer project is also
176 | * subject to an additional IP rights grant found at
177 | * http://polymer.github.io/PATENTS.txt
178 | */
179 |
180 | /**
181 | * @license
182 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
183 | * This code may only be used under the BSD style license found at
184 | * http://polymer.github.io/LICENSE.txt
185 | * The complete set of authors may be found at
186 | * http://polymer.github.io/AUTHORS.txt
187 | * The complete set of contributors may be found at
188 | * http://polymer.github.io/CONTRIBUTORS.txt
189 | * Code distributed by Google as part of the polymer project is also
190 | * subject to an additional IP rights grant found at
191 | * http://polymer.github.io/PATENTS.txt
192 | */
193 |
194 | /**
195 | @license
196 | Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
197 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
198 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
199 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
200 | Code distributed by Google as part of the polymer project is also
201 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
202 | */
203 |
204 | /**
205 | @license
206 | Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
207 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
208 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
209 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
210 | Code distributed by Google as part of the polymer project is also
211 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
212 | */
213 |
--------------------------------------------------------------------------------
/www/custom_ui/scripts.js.LICENSE:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
4 | * This code may only be used under the BSD style license found at
5 | * http://polymer.github.io/LICENSE.txt
6 | * The complete set of authors may be found at
7 | * http://polymer.github.io/AUTHORS.txt
8 | * The complete set of contributors may be found at
9 | * http://polymer.github.io/CONTRIBUTORS.txt
10 | * Code distributed by Google as part of the polymer project is also
11 | * subject to an additional IP rights grant found at
12 | * http://polymer.github.io/PATENTS.txt
13 | */
14 |
15 | /**
16 | * @license
17 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
18 | * This code may only be used under the BSD style license found at
19 | * http://polymer.github.io/LICENSE.txt
20 | * The complete set of authors may be found at
21 | * http://polymer.github.io/AUTHORS.txt
22 | * The complete set of contributors may be found at
23 | * http://polymer.github.io/CONTRIBUTORS.txt
24 | * Code distributed by Google as part of the polymer project is also
25 | * subject to an additional IP rights grant found at
26 | * http://polymer.github.io/PATENTS.txt
27 | */
28 |
29 | /**
30 | * @license
31 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
32 | * This code may only be used under the BSD style license found at
33 | * http://polymer.github.io/LICENSE.txt
34 | * The complete set of authors may be found at
35 | * http://polymer.github.io/AUTHORS.txt
36 | * The complete set of contributors may be found at
37 | * http://polymer.github.io/CONTRIBUTORS.txt
38 | * Code distributed by Google as part of the polymer project is also
39 | * subject to an additional IP rights grant found at
40 | * http://polymer.github.io/PATENTS.txt
41 | */
42 |
43 | /**
44 | * @license
45 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
46 | * This code may only be used under the BSD style license found at
47 | * http://polymer.github.io/LICENSE.txt
48 | * The complete set of authors may be found at
49 | * http://polymer.github.io/AUTHORS.txt
50 | * The complete set of contributors may be found at
51 | * http://polymer.github.io/CONTRIBUTORS.txt
52 | * Code distributed by Google as part of the polymer project is also
53 | * subject to an additional IP rights grant found at
54 | * http://polymer.github.io/PATENTS.txt
55 | */
56 |
57 | /**
58 | * @license
59 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
60 | * This code may only be used under the BSD style license found at
61 | * http://polymer.github.io/LICENSE.txt
62 | * The complete set of authors may be found at
63 | * http://polymer.github.io/AUTHORS.txt
64 | * The complete set of contributors may be found at
65 | * http://polymer.github.io/CONTRIBUTORS.txt
66 | * Code distributed by Google as part of the polymer project is also
67 | * subject to an additional IP rights grant found at
68 | * http://polymer.github.io/PATENTS.txt
69 | */
70 |
71 | /**
72 | * @license
73 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
74 | * This code may only be used under the BSD style license found at
75 | * http://polymer.github.io/LICENSE.txt
76 | * The complete set of authors may be found at
77 | * http://polymer.github.io/AUTHORS.txt
78 | * The complete set of contributors may be found at
79 | * http://polymer.github.io/CONTRIBUTORS.txt
80 | * Code distributed by Google as part of the polymer project is also
81 | * subject to an additional IP rights grant found at
82 | * http://polymer.github.io/PATENTS.txt
83 | */
84 |
85 | /**
86 | * @license
87 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
88 | * This code may only be used under the BSD style license found at
89 | * http://polymer.github.io/LICENSE.txt
90 | * The complete set of authors may be found at
91 | * http://polymer.github.io/AUTHORS.txt
92 | * The complete set of contributors may be found at
93 | * http://polymer.github.io/CONTRIBUTORS.txt
94 | * Code distributed by Google as part of the polymer project is also
95 | * subject to an additional IP rights grant found at
96 | * http://polymer.github.io/PATENTS.txt
97 | */
98 |
99 | /**
100 | * @license
101 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
102 | * This code may only be used under the BSD style license found at
103 | * http://polymer.github.io/LICENSE.txt
104 | * The complete set of authors may be found at
105 | * http://polymer.github.io/AUTHORS.txt
106 | * The complete set of contributors may be found at
107 | * http://polymer.github.io/CONTRIBUTORS.txt
108 | * Code distributed by Google as part of the polymer project is also
109 | * subject to an additional IP rights grant found at
110 | * http://polymer.github.io/PATENTS.txt
111 | */
112 |
113 | /**
114 | * @license
115 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
116 | * This code may only be used under the BSD style license found at
117 | * http://polymer.github.io/LICENSE.txt
118 | * The complete set of authors may be found at
119 | * http://polymer.github.io/AUTHORS.txt
120 | * The complete set of contributors may be found at
121 | * http://polymer.github.io/CONTRIBUTORS.txt
122 | * Code distributed by Google as part of the polymer project is also
123 | * subject to an additional IP rights grant found at
124 | * http://polymer.github.io/PATENTS.txt
125 | */
126 |
127 | /**
128 | * @license
129 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
130 | * This code may only be used under the BSD style license found at
131 | * http://polymer.github.io/LICENSE.txt
132 | * The complete set of authors may be found at
133 | * http://polymer.github.io/AUTHORS.txt
134 | * The complete set of contributors may be found at
135 | * http://polymer.github.io/CONTRIBUTORS.txt
136 | * Code distributed by Google as part of the polymer project is also
137 | * subject to an additional IP rights grant found at
138 | * http://polymer.github.io/PATENTS.txt
139 | */
140 |
141 | /**
142 | @license
143 | Copyright (c) 2019 The Polymer Project Authors. All rights reserved.
144 | This code may only be used under the BSD style license found at
145 | http://polymer.github.io/LICENSE.txt The complete set of authors may be found at
146 | http://polymer.github.io/AUTHORS.txt The complete set of contributors may be
147 | found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as
148 | part of the polymer project is also subject to an additional IP rights grant
149 | found at http://polymer.github.io/PATENTS.txt
150 | */
151 |
152 | /**
153 | * @license
154 | * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
155 | * This code may only be used under the BSD style license found at
156 | * http://polymer.github.io/LICENSE.txt
157 | * The complete set of authors may be found at
158 | * http://polymer.github.io/AUTHORS.txt
159 | * The complete set of contributors may be found at
160 | * http://polymer.github.io/CONTRIBUTORS.txt
161 | * Code distributed by Google as part of the polymer project is also
162 | * subject to an additional IP rights grant found at
163 | * http://polymer.github.io/PATENTS.txt
164 | */
165 |
166 | /**
167 | @license
168 | Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
169 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
170 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
171 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
172 | Code distributed by Google as part of the polymer project is also
173 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
174 | */
175 |
176 | /**
177 | @license
178 | Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
179 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
180 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
181 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
182 | Code distributed by Google as part of the polymer project is also
183 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
184 | */
185 |
--------------------------------------------------------------------------------
/www/custom_ui/state-card-custom-ui-es5.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/www/custom_ui/state-card-custom-ui-es5.html.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zaneclaes/van-home-assistant-config/907196e279a1f9bccc25649bf42c1c99773e50c1/www/custom_ui/state-card-custom-ui-es5.html.gz
--------------------------------------------------------------------------------
/www/custom_ui/state-card-custom-ui.html:
--------------------------------------------------------------------------------
1 |
242 |
--------------------------------------------------------------------------------
/www/custom_ui/state-card-custom-ui.html.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zaneclaes/van-home-assistant-config/907196e279a1f9bccc25649bf42c1c99773e50c1/www/custom_ui/state-card-custom-ui.html.gz
--------------------------------------------------------------------------------
/www/kiosk.css:
--------------------------------------------------------------------------------
1 | #view {
2 | min-height: 110vh !important;
3 | }
--------------------------------------------------------------------------------
/www/kiosk.js:
--------------------------------------------------------------------------------
1 | // Adapted from https://gist.github.com/ciotlosm/1f09b330aa5bd5ea87b59f33609cc931
2 | if (window.location.href.indexOf('kiosk') > 0) {
3 | setTimeout(function () {
4 | try {
5 | const home_assistant_main = document
6 | .querySelector("body > home-assistant").shadowRoot
7 | .querySelector("home-assistant-main");
8 |
9 | var header = home_assistant_main.shadowRoot
10 | .querySelector("app-drawer-layout > partial-panel-resolver > ha-panel-lovelace").shadowRoot
11 | .querySelector("hui-root").shadowRoot
12 | .querySelector('#layout > app-header')
13 | if (window.location.href.indexOf('show_tabs') > 0) {
14 | header = header.querySelector('app-toolbar')
15 | }
16 |
17 | const drawer = home_assistant_main.shadowRoot.querySelector("#drawer");
18 |
19 | header.style.display = "none";
20 | drawer.style.display = 'none';
21 |
22 | home_assistant_main.style.setProperty("--app-drawer-width", 0);
23 | home_assistant_main.shadowRoot
24 | .querySelector("#drawer > ha-sidebar").shadowRoot
25 | .querySelector("div.menu > paper-icon-button")
26 | .click();
27 |
28 | window.dispatchEvent(new Event('resize'));
29 | }
30 | catch (e) {
31 | console.log(e);
32 | }
33 | }, 200);
34 | }
--------------------------------------------------------------------------------
/www/monster-card.js:
--------------------------------------------------------------------------------
1 | class MonsterCard extends HTMLElement {
2 |
3 | _getEntities(hass, filters) {
4 | function _filterEntityId(stateObj, pattern) {
5 | if (pattern.indexOf('*') === -1) {
6 | return stateObj.entity_id === pattern;
7 | }
8 | const regEx = new RegExp(`^${pattern.replace(/\*/g, '.*')}$`, 'i');
9 | return stateObj.entity_id.search(regEx) === 0;
10 | }
11 | function _filterName(stateObj, pattern) {
12 | let compareEntity = stateObj.attributes.title ? stateObj.attributes.title : stateObj.attributes.friendly_name;
13 | if (!compareEntity) compareEntity = stateObj.entity_id;
14 | if (pattern.indexOf('*') === -1) {
15 | return compareEntity === pattern;
16 | }
17 | const regEx = new RegExp(`^${pattern.replace(/\*/g, '.*')}$`, 'i');
18 | return compareEntity.search(regEx) === 0;
19 | }
20 | // Allows '< 300' in b
21 | function _complexCompare(a, b) {
22 | const _compare = {
23 | '>': (x, y) => x > y,
24 | '<': (x, y) => x < y,
25 | '<=': (x, y) => x <= y,
26 | '>=': (x, y) => x >= y,
27 | '=': (x, y) => x === y,
28 | };
29 | let operator = '=';
30 | let y = b;
31 | let x = a;
32 | if (!isNaN(a) && typeof (b) == 'string'
33 | && b.split(" ").length > 1) {
34 | [operator, y] = b.split(' ', 2);
35 | x = parseFloat(a);
36 | }
37 | return _compare[operator](x, y);
38 | }
39 | const entities = new Map();
40 | filters.forEach((filter) => {
41 | const filters = [];
42 | if (filter.domain) {
43 | filters.push(stateObj => stateObj.entity_id.split('.', 1)[0] === filter.domain);
44 | }
45 | if (filter.attributes) {
46 | Object.keys(filter.attributes).forEach(key => {
47 | filters.push(stateObj => _complexCompare(stateObj.attributes[key], filter.attributes[key]));
48 | });
49 | }
50 | if (filter.entity_id) {
51 | filters.push(stateObj => _filterEntityId(stateObj, filter.entity_id));
52 | }
53 | if (filter.name) {
54 | filters.push(stateObj => _filterName(stateObj, filter.name));
55 | }
56 | if (filter.state) {
57 | filters.push(stateObj => _complexCompare(stateObj.state, filter.state));
58 | }
59 |
60 | const options = filter.options ? filter.options : {}
61 |
62 | Object.keys(hass.states).sort().forEach(key => {
63 | if (filters.every(filterFunc => filterFunc(hass.states[key]))) {
64 | const dynOptions = JSON.parse(JSON.stringify(options).replace(/this.entity_id/g,hass.states[key].entity_id));
65 | entities.set(hass.states[key].entity_id, Object.assign({ "entity": hass.states[key].entity_id }, dynOptions));
66 | }
67 | });
68 | });
69 | return Array.from(entities.values());
70 | }
71 |
72 | setConfig(config) {
73 | if (!config.filter.include || !Array.isArray(config.filter.include)) {
74 | throw new Error('Please define filters');
75 | }
76 |
77 | if (this.lastChild) this.removeChild(this.lastChild);
78 |
79 | const cardConfig = Object.assign({}, config);
80 | if (!cardConfig.card) cardConfig.card = {};
81 | if (config.card.entities) delete config.card.entities;
82 | if (!cardConfig.card.type) cardConfig.card.type = 'entities';
83 |
84 | const element = document.createElement(`hui-${cardConfig.card.type}-card`);
85 | this.appendChild(element);
86 |
87 | this._config = cardConfig;
88 | }
89 |
90 | set hass(hass) {
91 | const config = this._config;
92 | let entities = this._getEntities(hass, config.filter.include);
93 | if (config.filter.exclude) {
94 | const excludeEntities = this._getEntities(hass, config.filter.exclude).map(entity => entity.entity);
95 | entities = entities.filter(entity => !excludeEntities.includes(entity.entity));
96 | }
97 |
98 |
99 |
100 | if (entities.length === 0 && config.show_empty === false) {
101 | this.style.display = 'none';
102 | } else {
103 | if (config.when && (hass.states[config.when.entity].state == config.when.state) || !config.when) {
104 | this.style.display = 'block';
105 | } else {
106 | this.style.display = 'none';
107 | }
108 | }
109 |
110 | if (!config.card.entities || config.card.entities.length !== entities.length ||
111 | !config.card.entities.every((value, index) => value.entity === entities[index].entity)) {
112 | config.card.entities = entities;
113 | this.lastChild.setConfig(config.card);
114 | }
115 | this.lastChild.hass = hass;
116 | }
117 |
118 | getCardSize() {
119 | return 'getCardSize' in this.lastChild ? this.lastChild.getCardSize() : 1;
120 | }
121 | }
122 |
123 | customElements.define('monster-card', MonsterCard);
124 |
--------------------------------------------------------------------------------
/www/photos/van-overhead.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zaneclaes/van-home-assistant-config/907196e279a1f9bccc25649bf42c1c99773e50c1/www/photos/van-overhead.jpg
--------------------------------------------------------------------------------
/www/photos/van-side.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zaneclaes/van-home-assistant-config/907196e279a1f9bccc25649bf42c1c99773e50c1/www/photos/van-side.jpg
--------------------------------------------------------------------------------