├── .github
└── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── changelog.md
├── home-card-editor.js
├── home-card.js
├── images
├── card-editor.png
├── demo.gif
├── ranch_home.png
└── structure.png
├── themes.js
└── themes
├── ranch_with_three_stall_garage
├── car.png
├── door-close.png
├── door-open.png
├── garage-close.png
├── garage-open.png
├── house.png
├── outside-light-off.png
├── outside-light-on.png
├── sprinkler-off.png
├── sprinkler-on.png
├── utility-electricity.png
├── utility-water.png
├── weather-cloudy.png
├── weather-exceptional.png
├── weather-fog.png
├── weather-hail.png
├── weather-lightning-rainy.png
├── weather-lightning.png
├── weather-partlycloudy.png
├── weather-pouring.png
├── weather-rainy.png
├── weather-snowy-rainy.png
├── weather-snowy.png
├── weather-sun.png
├── weather-sunny.png
├── weather-windy-variant.png
├── weather-windy.png
├── window-dark.png
└── window-light.png
└── two_story_with_garage
├── car.png
├── door-close.png
├── door-open.png
├── garage-close.png
├── garage-open.png
├── house.png
├── outside-light-off.png
├── outside-light-on.png
├── sprinkler-off.png
├── sprinkler-on.png
├── utility-electricity.png
├── utility-water.png
├── weather-cloudy.png
├── weather-exceptional.png
├── weather-fog.png
├── weather-hail.png
├── weather-lightning-rainy.png
├── weather-lightning.png
├── weather-partlycloudy.png
├── weather-pouring.png
├── weather-rainy.png
├── weather-snowy-rainy.png
├── weather-snowy.png
├── weather-sun.png
├── weather-sunny.png
├── weather-windy-variant.png
├── weather-windy.png
├── window-dark.png
└── window-light.png
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [postlund]
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Pierre Ståhl
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Home Card
2 |
3 | A quick glance of the state of your home in [Home Assistant](https://github.com/home-assistant/home-assistant) Lovelace UI.
4 |
5 | 
6 |
7 | Initial work on UI editor (only some options can be edited):
8 |
9 | 
10 |
11 | *Note: This card is still in early development (preview/proof-of-concept), beware of bugs and lacking features!*
12 |
13 | ## Features
14 |
15 | * Graphical representation of your home with different themes
16 | * Displays things such as weather, state of lights and garage door as well as arbitrary sensors
17 | * Lovelace UI editor for some options (still early work)
18 | * Flexible tap and hold actions (same as for entity-button)
19 | * Create your own custom themes!
20 | * Transparent or regular paper card background
21 |
22 | ## Roadmap
23 |
24 | Some things I want to add in upcoming releases:
25 |
26 | * More house types and better graphics
27 | * Extend with additional overlays for things like alarm, people and doors
28 | * More ways to customize how the card looks and feel
29 | * Extend or override existing themes using `custom_themes`
30 | * More improved Lovelace UI editor
31 | * Support for custom_updater
32 | * Better development environment with linting, etc.
33 |
34 | ## Install
35 |
36 | ### Simple Install
37 |
38 | 1. Download `home-card.js`, `themes.js` and `themes` and copy them into `config/www/home-card` (create the `home-card` directory)
39 |
40 | 2. Add a reference to `home-card/home-card.js` inside your `ui-lovelace.yaml`
41 |
42 | ```yaml
43 | resources:
44 | - url: /local/home-card/home-card.js?v=0
45 | type: module
46 | ```
47 |
48 | ### Git Install
49 |
50 | 1. Clone this repository into your `www`-directory: `git clone https://github.com/postlund/home-card.git`
51 |
52 | 2. Add a reference to `home-card/home-card.js` inside your `ui-lovelace.yaml`
53 |
54 | ```yaml
55 | resources:
56 | - url: /local/home-card/home-card.js?v=0
57 | type: module
58 | ```
59 |
60 | ### Custom updater
61 |
62 | Not using this yet...
63 |
64 | ## Updating
65 |
66 | If you...
67 |
68 | * manually copied the files, just download the latest files and overwrite what you already have
69 | * cloned the repository from Github, just do `git pull` to update
70 |
71 | ... and increase `?v=X` to `?vX+1`.
72 |
73 | ## Using the card
74 |
75 | ### Card layout
76 |
77 | The card is split into three different areas:
78 |
79 | 
80 |
81 | Explanation of each area:
82 |
83 | * Weather area (Red): Displays current weather with an icon (e.g. sun or cloud) and temperature. Name of location is displayed as well. Controlled by the `weather` option.
84 | * House area (Green): Main visualization of the house. Consists of `overlay` images that can be shown or hidden depending on an entity state. A car overlay (image) can for instance be shown if `device_tracker.car` has the state `home`. Controlled by the `entities` option.
85 | * Resources (Blue): Simplistic view of sensors. Controlled by the `resources` option.
86 |
87 | Both the weather and resources areas are optional and will not displayed if omitted from the configuration. The house area are however mandatory.
88 |
89 | ### Options
90 |
91 | | Name | Type | Default | Description |
92 | |------|------|---------|-------------|
93 | | type | string | **required** | `custom:home-card`
94 | | theme | string | **required** | Name of a theme, see [supported themes](#supported-themes)
95 | | background | string | transparent | Supported values: empty, `transparent`, `paper-card`
96 | | weather | string | optional | `weather` entity used for displaying location and temperature
97 | | entities | object | optional | List of [entity objects](#entity-object)
98 | | resources | object | optional | List of [resource objects](#resource-object)
99 | | custom_themes | object | optional | List of [theme objects](#theme-object)
100 |
101 | #### Supported themes
102 |
103 | The following themes and overlays are currently supported:
104 |
105 | | Theme | Overlays |
106 | |------|----------|
107 | | two_story_with_garage | door, garage, outside_light, upstairs_light, downstairs_light, car, sprinkler
108 |
109 | These states are supported by the overlays:
110 |
111 | | Overlay | States | Component examples |
112 | |---------|--------|-----------------------|
113 | | car | home, not_home | device_tracker
114 | | door | on, off | E.g. binary_sensor, switch
115 | | downstairs_lights | on, off | E.g. light, binary_sensor
116 | | garage | open, closed | cover
117 | | outside_light | on, off | E.g. light, binary_sensor
118 | | upstairs_lights | on, off | E.g. light, binary_sensor
119 | | sprinkler | on, off | E.g. binary_sensor, switch
120 |
121 | You may add additional state mappings using a `state_map` to support other component types, see [Entity object](#entity-object).
122 |
123 | #### Entity object
124 |
125 | An `entity object` maps an entity in Home Assistant to an overlay in the card, e.g. which `device_tracker` entity that shows/hides the car or which `light` that corresponds to "upstairs".
126 |
127 | | Name | Type | Default | Description |
128 | |------|------|---------|-------------|
129 | | type | string | **required** | Overlay type, see [overlay tabe](#supported-themes)
130 | | entity | string | **required** | Entity id from Home Assistant, e.g. `light.downstairs`
131 | | state_map | map | optional | Key-value map of state (in Home Assistant) to overlay state
132 |
133 | A simple example of an entity object in yaml looks like this:
134 |
135 | ```yaml
136 | - type: car
137 | entity: binary_sensor_.car
138 | state_map:
139 | on: home
140 | off: not_home
141 | ```
142 |
143 | This object supports custom [tap and hold actions](#tap-and-hold-actions).
144 |
145 | #### Resource object
146 |
147 | A `resource` is a simple sensor that is displayed beneath the house, e.g. a temperature sensor or water usage. You can use any entity but you might have to manually specify an `icon` and/or `unit_of_measurement`.
148 |
149 | | Name | Type | Default | Description |
150 | |------|------|---------|-------------|
151 | | entity | string | **required** | An entity from Home Assistant, e.g, `sensor.water_usage`
152 | | icon | string | optional | Override icon to use, e.g. `mdi:car`
153 | | unit_of_measurement | string | optional | Override unit of measurement, e.g. `lux`
154 |
155 | A simple example of a resource object in yaml looks like this:
156 |
157 | ```yaml
158 | - entity: sensor.water_usage
159 | icon: mdi:water
160 | unit_of_measurement: liter
161 | ```
162 |
163 | This object supports custom [tap and hold actions](#tap-and-hold-actions).
164 |
165 | #### Theme object
166 |
167 | **THIS IS EXPERIMENTAL AND MAY BREAK LATER - BEWARE!**
168 |
169 | You can define your own themes and use your own images if you like. Some things to consider:
170 |
171 | * Keep images small (in size) to keep everything snappy
172 | * Re-use overlays and names as much as possible to keep themes consistent
173 | * If you make a cool looking theme, feel free to send a PR (make sure to clarify where images come from to cope with licenses) and remember to include a screenshot
174 | * It is currently not possible to alter/extend existing themes, only define additional themes
175 |
176 | The format of this object will be described in more detail once the format has been set, but have a look at the [example](#creating-custom-themes) to see how you configure your theme in current state.
177 |
178 | ### Tap and hold actions
179 |
180 | This card supports custom `tap` and `hold` actions for most things available in the card. Each theme defines the default behavior for how `tap` and `hold` works, but you may freely override this behavior. The exact same format as used by the `entity button` in lovelace is used here.
181 |
182 | The following options are valid for `tap_action` and `hold_action`:
183 |
184 | | Name | Type | Default | Description |
185 | |------|------|---------|-------------|
186 | | action | string | **required** | Action to perform, one of: `more-info`, `toggle`, `call-service`, `navigate`, `none`
187 | | navigation_path | string | optional | Where to navigate (e.g. `/lovelace/1`) when `action` is `navigate`
188 | | service | string | optional | Service to call (e.g. `switch.turn_on`) when `action` is `call-service`
189 | | service_data | string | optional | Service data to include when calling a service (e.g. `entity_id: switch.bedroom`).
190 |
191 | To see an example, click [here](#using-custom-tap-and-hold-actions).
192 |
193 | ### Example usage
194 |
195 | #### Defining a home
196 |
197 | Simple example using basic features:
198 |
199 | ```yaml
200 | - type: 'custom:home-card'
201 | theme: two_story_with_garage
202 | weather: weather.home
203 | entities:
204 | - type: garage
205 | entity: cover.garage_door
206 | - type: upstairs_light
207 | entity: light.demo_upstairs_light
208 | - type: downstairs_light
209 | entity: light_downstairs_light
210 | - type: car
211 | entity: device_tracker.car
212 | resources:
213 | - entity: utility meter.water
214 | - entity: utility meter.electricity
215 | - entity: binary_sensor.movement_backyard
216 | icon: 'mdi:alarm-light'
217 | - entity: sensor.outside_temperature
218 | icon: 'mdi:thermometer'
219 | ```
220 |
221 | #### Using custom tap and hold actions
222 |
223 | Simple example using various `tap` and `hold` actions:
224 |
225 | ```yaml
226 | - type: 'custom:home-card'
227 | theme: two_story_with_garage
228 | entities:
229 | - type: car
230 | entity: device_tracker.car
231 | tap_action:
232 | action: navigate
233 | navigation_path: /lovelace/2
234 | hold_action:
235 | action: more-info
236 | resources:
237 | - entity: sensor.outside_temperature
238 | tap_action:
239 | action: call-service
240 | service: switch.turn_on
241 | service_data:
242 | entity_id: switch.fan
243 | hold_action:
244 | action: none
245 | ```
246 |
247 | #### Re-mapping states
248 |
249 | Here, the `car` type is used as an example. It requires the specified entity to be a `device_tracker` as it maps states like `home` and `not_home` to different overlays. But you can add additional mappings to support for instance a `binary_sensor` as well using `state_map`, like below:
250 |
251 | ```yaml
252 | - type: 'custom:home-card'
253 | theme: two_story_with_garage
254 | entities:
255 | - type: car
256 | entity: binary_sensor.car
257 | state_map:
258 | on: home
259 | off: not_home
260 | ```
261 |
262 | #### Creating custom themes
263 |
264 | You can define you own themes quite simply using `custom_themes`. The basic structure looks like below (`car` is used to illustrate, you may add as many overlays as you like):
265 |
266 | ```yaml
267 | - type: 'custom:home-card'
268 | theme: my_home
269 | entities:
270 | - type: car
271 | entity: device_tracker.car
272 | custom_themes:
273 | my_home:
274 | house: house.png
275 | overlay_actions:
276 | '*':
277 | tap_action:
278 | action: toggle
279 | car:
280 | tap_action:
281 | action: more-info
282 | overlays:
283 | car:
284 | home:
285 | - image: car_home.png
286 | style:
287 | left: 10%
288 | top: 10%
289 | not_home:
290 | - image: car_away.png
291 | style:
292 | left: 40%
293 | top: 40%
294 | ```
295 |
296 | Some notes here:
297 |
298 | * You can defined multiple images for each state if you like (as a list is used)
299 | * `style` translates to CSS style attributes, so you may use any CSS attributes here
300 | * The theme is called `my_home`, so a directory with the same name must be created in the `themes` directory and all images placed there
301 | * The `house` option is the main backdrop image and must be defined
302 | * Overlay name (e.g. `car`) corresponds to `type` you specify under `entities` and may be anything you like (but try to be consistent with other themes to simply for other users in case you share your theme)
303 | * If an entity in Home Assistant has a state that is not defined by its corresponding overlay, no overlay will be shown
304 | * Different `tap_action` and `hold_action` configurations can be defined for specific overlay taps (like for 'car' in the example) or for all overlays using `*`.
305 |
306 | ## Issues and imitations
307 |
308 | * Very limited lovelace editor support
309 | * Only one theme built-in
310 |
311 | ## Getting errors?
312 |
313 | Clear the browser cache, restart Home Assistant and make sure the configuration is correct.
314 |
315 | If you believe you have found an error, please write an issue.
316 |
317 | ## External resources
318 |
319 |
320 | ### Images
321 |
322 | This card uses some great free resources from Freepik, namely these:
323 |
324 | * [Weather Icons](https://www.freepik.com/free-vector/weather-icons-collection_972339.htm)
325 | * [House](https://www.freepik.com/free-vector/residential-houses-collection-flat-style_2065378.htm)
326 | * [Car](https://www.freepik.com/free-vector/flat-car-different-views_1504979.htm)
327 |
328 | ### Other resources
329 |
330 | The excellent `clear` theme is used in demo graphics, you can find it here:
331 |
332 | https://community.home-assistant.io/t/clear-theme/100464
333 |
334 | Background image is linked from the same page as well.
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | ## v0.1
2 |
3 | - Initial version
4 |
--------------------------------------------------------------------------------
/home-card-editor.js:
--------------------------------------------------------------------------------
1 | import { THEMES } from './themes.js';
2 |
3 | // Not sure this is really needed, should be available through the frontend?
4 | const deps = ['paper-input', 'paper-dropdown-menu', 'paper-item', 'paper-listbox'];
5 | deps.map(dep => {
6 | if (!customElements.get(dep)) {
7 | console.log("imported", dep);
8 | import(`https://unpkg.com/@polymer/${dep}/${dep}.js?module`);
9 | }
10 | });
11 |
12 | const fireEvent = (node, type, detail, options) => {
13 | options = options || {};
14 | detail = detail === null || detail === undefined ? {} : detail;
15 | const event = new Event(type, {
16 | bubbles: options.bubbles === undefined ? true : options.bubbles,
17 | cancelable: Boolean(options.cancelable),
18 | composed: options.composed === undefined ? true : options.composed
19 | });
20 | event.detail = detail;
21 | node.dispatchEvent(event);
22 | return event;
23 | };
24 |
25 | const LitElement = Object.getPrototypeOf(
26 | customElements.get("ha-panel-lovelace")
27 | );
28 | const html = LitElement.prototype.html;
29 |
30 | export class HomeCardEditor extends LitElement {
31 | setConfig(config) {
32 | this.config = config;
33 | }
34 |
35 | static get properties() {
36 | return {
37 | hass: {},
38 | config: {}
39 | };
40 | }
41 |
42 | get _weather() {
43 | return this.config.weather || "";
44 | }
45 |
46 | render() {
47 | if (!this.hass) {
48 | return html``;
49 | }
50 | return html`
51 |
52 | ${this.make_dropdown("Theme", "theme", Object.keys(Object.assign({}, THEMES, this.config.custom_themes)))}
53 | ${this.make_dropdown("Background", "background", ["transparent", "paper-card"])}
54 |
60 |
61 | `;
62 | }
63 |
64 | make_dropdown(label, configValue, items) {
65 | var selected = Math.max(0, items.indexOf(this.config[configValue]));
66 | return html`
67 |
68 |
72 |
73 | ${items.map(
74 | (name) => html`
75 | ${name}
76 | `
77 | )}
78 |
79 |
80 |
81 | `;
82 | }
83 |
84 | _valueChanged(ev) {
85 | if (!this.config || !this.hass) {
86 | return;
87 | }
88 | const target = ev.target;
89 | if (this[`_${target.configValue}`] === target.value) {
90 | return;
91 | }
92 | if (target.configValue) {
93 | if (target.value === "") {
94 | delete this.config[target.configValue];
95 | } else {
96 | this.config = {
97 | ...this.config,
98 | [target.configValue]: target.value
99 | };
100 | }
101 | }
102 | fireEvent(this, "config-changed", { config: this.config });
103 | }
104 | }
105 |
106 | customElements.define("home-card-editor", HomeCardEditor);
--------------------------------------------------------------------------------
/home-card.js:
--------------------------------------------------------------------------------
1 | import { THEMES } from './themes.js';
2 |
3 | import {
4 | LitElement,
5 | html,
6 | css,
7 | } from 'https://unpkg.com/lit-element@2.0.1/lit-element.js?module';
8 |
9 | const VERSION = 4;
10 |
11 | // From weather-card
12 | const fireEvent = (node, type, detail, options) => {
13 | options = options || {};
14 | detail = detail === null || detail === undefined ? {} : detail;
15 | const event = new Event(type, {
16 | bubbles: options.bubbles === undefined ? true : options.bubbles,
17 | cancelable: Boolean(options.cancelable),
18 | composed: options.composed === undefined ? true : options.composed
19 | });
20 | event.detail = detail;
21 | node.dispatchEvent(event);
22 | return event;
23 | };
24 |
25 | class HomeCard extends LitElement {
26 |
27 | static get properties() {
28 | return {
29 | config: {},
30 | hass: {},
31 | held: false,
32 | timer: {},
33 | };
34 | }
35 |
36 | static async getConfigElement() {
37 | await import("./home-card-editor.js");
38 | return document.createElement("home-card-editor");
39 | }
40 |
41 | static getStubConfig() {
42 | return {
43 | tap_action: { action: "more-info" },
44 | hold_action: { action: "none" },
45 | };
46 | }
47 |
48 | setConfig(config) {
49 | if (!config.theme) {
50 | throw new Error('No house type defined');
51 | }
52 |
53 | if (THEMES[config.theme]) {
54 | this.theme = THEMES[config.theme];
55 | } else if (config.custom_themes[config.theme]) {
56 | this.theme = config.custom_themes[config.theme];
57 | } else {
58 | throw new Error('Unsupported house type: ' + config.theme);
59 | }
60 |
61 | this.config = config;
62 | }
63 |
64 | getCardSize() {
65 | return 4;
66 | }
67 |
68 | render() {
69 | try {
70 | if (this.config.background == 'paper-card') {
71 | return html `${this.make_content()}`;
72 | }
73 |
74 | return this.make_content();
75 | } catch (error) {
76 | return html `
77 |
78 |
79 | ${error}
80 |
81 |
82 | `;
83 | }
84 | }
85 |
86 | make_content() {
87 | var weather = "";
88 | var resources = "";
89 |
90 | if (this.config.weather) {
91 | var weatherObj = this.stateObject('weather', this.config.weather);
92 | weather = html `
93 |
94 |

95 |
96 | ${weatherObj.attributes.friendly_name}
97 | ${weatherObj.attributes.temperature}${this.hass.config.unit_system.temperature}
98 |
99 |
`;
100 | }
101 |
102 | if (this.config.resources) {
103 | resources = html `
104 |
105 | ${this.config.resources.map(resource => this.make_resource(resource))}
106 |
`;
107 | }
108 |
109 | return html `
110 |
111 | ${weather}
112 |
113 |
})
114 | ${this.make_entities()}
115 |
116 | ${resources}
117 |
118 | `;
119 | }
120 |
121 | make_resource(resource) {
122 | var stateObj = this.stateObject('resources', resource.entity);
123 | return html `
124 | this._down(resource)}"
125 | @touchstart="${ev => this._down(resource)}"
126 | @mouseup="${ev => this._up(resource, false)}">
127 |
128 |
129 |
130 | ${Math.round(stateObj.state) || stateObj.state}
131 | ${resource.unit_of_measurement || this.get_attribute(stateObj, 'unit_of_measurement', '')}
132 |
133 |
134 | `;
135 | }
136 |
137 | get_attribute(stateObj, name, _default) {
138 | if (!stateObj['attributes'] || !stateObj.attributes[name]) {
139 | return _default;
140 | }
141 |
142 | return stateObj.attributes[name];
143 | }
144 |
145 | more_info(entity_id) {
146 | fireEvent(this, "hass-more-info", { entityId: entity_id });
147 | }
148 |
149 | make_entities() {
150 | var to_add = []
151 | Object.keys(this.config.entities).map(index => {
152 | var entity = this.config.entities[index];
153 |
154 | if (!this.theme.overlays[entity.type]) {
155 | throw Error('Unsupported entity type: ' + entity.type);
156 | }
157 |
158 | var stateObj = this.stateObject('entities', entity.entity);
159 |
160 | var state = stateObj.state;
161 | if (entity.state_map && stateObj.state in entity.state_map) {
162 | state = entity.state_map[stateObj.state];
163 | }
164 |
165 | var overlay = this.theme.overlays[entity.type][state];
166 | if (overlay) {
167 | for (var i = 0; i < overlay.length; ++i) {
168 | var imageName = entity.type + '_' + stateObj.state + '_' + i;
169 | to_add.push(this.create_overlay(
170 | imageName, overlay[i].image, overlay[i].style, entity));
171 | }
172 | }
173 | });
174 | return to_add;
175 | }
176 |
177 | create_overlay(imageName, imageFile, style, entity) {
178 | var styleString = Object.keys(style).map(prop => prop + ": " + style[prop] + ";");
179 | return html `
180 |
this._down(entity)}"
185 | @touchstart="${ev => this._down(entity)}"
186 | @mouseup="${ev => this._up(entity, true)}" />
187 | `
188 | }
189 |
190 | imgPath(filename) {
191 | return `/local/home-card/themes/${this.config.theme}/${filename}?v=${VERSION}`;
192 | }
193 |
194 | stateObject(source, entity_id) {
195 | if (!entity_id) {
196 | throw Error(`Empty entity id specified in ${source}`);
197 | }
198 |
199 | var stateObj = this.hass.states[entity_id];
200 | if (!stateObj) {
201 | throw Error(`The entity "${entity_id}" does not exist (${source})`)
202 | }
203 |
204 | return stateObj;
205 | }
206 |
207 | // The function contains so much magic...
208 | get_entity_action(config, action) {
209 | // If action is specified for this entity, use that
210 | if (config[action]) {
211 | return config[action];
212 | }
213 |
214 | // If no action is specified, use theme defined action
215 | if (this.theme.overlay_actions) {
216 | var overlayActions = this.theme.overlay_actions;
217 |
218 | // First check for specific overlay in theme
219 | if (overlayActions[config.type] && overlayActions[config.type][action]) {
220 | return overlayActions[config.type][action];
221 | }
222 |
223 | // Next check default for all overlays in theme
224 | if (overlayActions['*'] && overlayActions['*'][action]) {
225 | return overlayActions['*'][action];
226 | }
227 | }
228 |
229 | // If no theme action, fallback to default action
230 | return { action: 'more-info', };
231 | }
232 |
233 | // Tap/hold for resources are hardcoded to more-info for now (maybe configurable in the future)
234 | get_resource_action(action) {
235 | return { 'action': 'more-info'};
236 | }
237 |
238 | handleClick(config, actionConfig) {
239 | switch (actionConfig.action) {
240 | case "more-info":
241 | if (config.entity || config.camera_image) {
242 | fireEvent(this, "hass-more-info", {
243 | entityId: config.entity ? config.entity : config.camera_image,
244 | });
245 | }
246 | break;
247 | case "navigate":
248 | if (actionConfig.navigation_path) {
249 | history.pushState(null, "", actionConfig.navigation_path);
250 | fireEvent(window, "location-changed");
251 | }
252 | break;
253 | case "toggle":
254 | if (!config.entity) {
255 | return;
256 | }
257 |
258 | if (config.entity.startsWith("cover.")) {
259 | var coverState = this.hass.states[config.entity].state;
260 | this.hass.callService('cover',
261 | coverState == 'open' ? 'close_cover' : 'open_cover',
262 | {'entity_id': config.entity});
263 | } else {
264 | this.hass.callService('homeassistant', 'toggle', {'entity_id': config.entity});
265 | }
266 | break;
267 | case "call-service": {
268 | if (actionConfig.service) {
269 | const [domain, service] = actionConfig.service.split(".", 2);
270 | this.hass.callService(domain, service, actionConfig.service_data);
271 | }
272 | }
273 | }
274 | }
275 |
276 | _down(config) {
277 | if (!this.timer) {
278 | this.timer = window.setTimeout(() => { this.held = true; }, 500);
279 | this.held = false;
280 | }
281 | }
282 |
283 | _up(config, is_overlay) {
284 | if (this.timer) {
285 | clearTimeout(this.timer);
286 | this.timer = undefined;
287 |
288 | let actionConfig = undefined;
289 | if (is_overlay) {
290 | actionConfig = this.get_entity_action(config, this.held ? 'hold_action' : 'tap_action');
291 | } else {
292 | actionConfig = this.get_resource_action(this.held ? 'hold_action' : 'tap_action')
293 | }
294 | this.handleClick(config, actionConfig);
295 | }
296 | }
297 |
298 | static get styles() {
299 | return css `
300 | #root {
301 | width: 100%;
302 | height: auto;
303 | padding-top: 5%;
304 | padding-bottom: 5%;
305 | }
306 | #weather {
307 | position: relative;
308 | overflow: visible;
309 | height: 100%;
310 | width: 90%;
311 | left: 5%;
312 | margin-bottom: 25px;
313 | }
314 | #weather-icon {
315 | width: 15%;
316 | }
317 | #weather-info {
318 | position: absolute;
319 | top: 25%;
320 | margin-left: 20px;
321 | color: var(--primary-text-color);
322 | font-weight: 300;
323 | font-size: 2em;
324 | }
325 | #house {
326 | position: relative;
327 | overflow: visible;
328 | height: 100%;
329 | width: 90%;
330 | left: 5%;
331 | z-index: 1;
332 | }
333 | #house-image {
334 | top: 50%;
335 | width: 100%;
336 | }
337 | #resource-usage {
338 | width: 90%;
339 | left: 5%;
340 | height: 100%;
341 | position: relative;
342 | margin-top: 25px;
343 | display: grid;
344 | grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
345 | grid-auto-rows: 20px;
346 | grid-gap: 5px;
347 | }
348 | .element {
349 | position: absolute;
350 | transform: translate(-50%, -50%);
351 | }
352 | .icon {
353 | color: var(--paper-item-icon-color, #44739e);
354 | display: inline-block;
355 | flex: 0 0 40px;
356 | line-height: 40px;
357 | position: relative;
358 | text-align: center;
359 | width: 40px;
360 | }
361 | .error-message {
362 | flex: 1;
363 | background-color: yellow;
364 | padding: 1em;
365 | }
366 | `;
367 | }
368 | }
369 |
370 | customElements.define('home-card', HomeCard);
371 |
--------------------------------------------------------------------------------
/images/card-editor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/images/card-editor.png
--------------------------------------------------------------------------------
/images/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/images/demo.gif
--------------------------------------------------------------------------------
/images/ranch_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/images/ranch_home.png
--------------------------------------------------------------------------------
/images/structure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/images/structure.png
--------------------------------------------------------------------------------
/themes.js:
--------------------------------------------------------------------------------
1 | export const THEMES = {
2 | 'two_story_with_garage': {
3 | 'house': 'house.png',
4 | 'overlay_actions': {
5 | '*': {
6 | 'tap_action': {
7 | 'action': 'toggle',
8 | },
9 | 'hold_action': {
10 | 'action': 'more-info',
11 | },
12 | },
13 | 'car': {
14 | 'tap_action': {
15 | 'action': 'more-info',
16 | },
17 | },
18 | 'sprinkler': {
19 | 'tap_action': {
20 | 'action': 'more-info',
21 | },
22 | },
23 | },
24 | 'overlays': {
25 | 'door': {
26 | 'on': [
27 | {
28 | 'image': 'door-close.png',
29 | 'style': { 'width': '8%', 'left': '40%', 'top': '68.5%', 'z-index': '10'},
30 | }
31 | ],
32 | 'off': [
33 | {
34 | 'image': 'door-open.png',
35 | 'style': { 'width': '8%', 'left': '40%', 'top': '68.5%', 'z-index': '10'},
36 | },
37 | ],
38 | },
39 | 'garage': {
40 | 'open': [
41 | {
42 | 'image': 'garage-open.png',
43 | 'style': { 'width': '21%', 'left': '73.5%', 'top': '67.5%', 'z-index': '10' },
44 | },
45 | ],
46 | 'closed': [
47 | {
48 | 'image': 'garage-close.png',
49 | 'style': { 'width': '21%', 'left': '73.5%', 'top': '67.5%', 'z-index': '10' },
50 | },
51 | ],
52 | },
53 | 'outside_light': {
54 | 'on': [
55 | {
56 | 'image': 'outside-light-on.png',
57 | 'style': { 'width': '8%', 'left': '10%', 'top': '77%', 'z-index': '10' },
58 | },
59 | {
60 | 'image': 'outside-light-on.png',
61 | 'style': { 'width': '8%', 'left': '56%', 'top': '77%', 'z-index': '10' },
62 | },
63 | {
64 | 'image': 'outside-light-on.png',
65 | 'style': { 'width': '8%', 'left': '91%', 'top': '77%', 'z-index': '10' },
66 | },
67 | ],
68 | 'off': [
69 | {
70 | 'image': 'outside-light-off.png',
71 | 'style': { 'width': '8%', 'left': '10%', 'top': '77%', 'z-index': '10' },
72 | },
73 | {
74 | 'image': 'outside-light-off.png',
75 | 'style': { 'width': '8%', 'left': '56%', 'top': '77%', 'z-index': '10' },
76 | },
77 | {
78 | 'image': 'outside-light-off.png',
79 | 'style': { 'width': '8%', 'left': '91%', 'top': '77%', 'z-index': '10' },
80 | },
81 | ],
82 | },
83 | 'downstairs_light': {
84 | 'on': [
85 | {
86 | 'image': 'window-light.png',
87 | 'style': { 'width': '6%', 'left': '56%', 'top': '61%', 'z-index': '10' },
88 | },
89 | {
90 | 'image': 'window-light.png',
91 | 'style': { 'width': '6%', 'left': '17%', 'top': '61%', 'z-index': '10' },
92 | },
93 | {
94 | 'image': 'window-light.png',
95 | 'style': { 'width': '6%', 'left': '25%', 'top': '61%', 'z-index': '10' },
96 | },
97 | ],
98 | 'off': [
99 | {
100 | 'image': 'window-dark.png',
101 | 'style': { 'width': '6%', 'left': '56%', 'top': '61%', 'z-index': '10' },
102 | },
103 | {
104 | 'image': 'window-dark.png',
105 | 'style': { 'width': '6%', 'left': '17%', 'top': '61%', 'z-index': '10' },
106 | },
107 | {
108 | 'image': 'window-dark.png',
109 | 'style': { 'width': '6%', 'left': '25%', 'top': '61%', 'z-index': '10' },
110 | },
111 | ]
112 | },
113 | 'upstairs_light': {
114 | 'on': [
115 | {
116 | 'image': 'window-light.png',
117 | 'style': { 'width': '6%', 'left': '33%', 'top': '25%', 'z-index': '10' },
118 | },
119 | ],
120 | 'off': [
121 | {
122 | 'image': 'window-dark.png',
123 | 'style': { 'width': '6%', 'left': '33%', 'top': '25%', 'z-index': '10' },
124 | },
125 | ]
126 | },
127 | 'car': {
128 | 'home': [
129 | {
130 | 'image': 'car.png',
131 | 'style': { 'width': '18%', 'left': '73.5%', 'top': '85%', 'z-index': '10' },
132 | },
133 | ],
134 | },
135 | 'sprinkler': {
136 | 'on': [
137 | {
138 | 'image': 'sprinkler-on.png',
139 | 'style': { 'left': '23%', 'top': '86%', 'z-index': '10' },
140 | },
141 | {
142 | 'image': 'sprinkler-on.png',
143 | 'style': { 'left': '50%', 'top': '89%', 'z-index': '10' },
144 | },
145 | ],
146 | 'off': [
147 | {
148 | 'image': 'sprinkler-off.png',
149 | 'style': { 'left': '23%', 'top': '86%', 'z-index': '10' },
150 | },
151 | {
152 | 'image': 'sprinkler-off.png',
153 | 'style': { 'left': '50%', 'top': '89%', 'z-index': '10' },
154 | },
155 | ],
156 | },
157 | },
158 | },
159 | 'ranch_with_three_stall_garage': {
160 | 'house': 'house.png',
161 | 'overlay_actions': {
162 | '*': {
163 | 'tap_action': {
164 | 'action': 'toggle',
165 | },
166 | 'hold_action': {
167 | 'action': 'more-info',
168 | },
169 | },
170 | 'car': {
171 | 'tap_action': {
172 | 'action': 'more-info',
173 | },
174 | },
175 | 'car2': {
176 | 'tap_action': {
177 | 'action': 'more-info',
178 | },
179 | },
180 | 'car3': {
181 | 'tap_action': {
182 | 'action': 'more-info',
183 | },
184 | },
185 | 'sprinkler': {
186 | 'tap_action': {
187 | 'action': 'more-info',
188 | },
189 | },
190 | },
191 | 'overlays': {
192 | 'door': {
193 | 'on': [
194 | {
195 | 'image': 'door-close.png',
196 | 'style': { 'width': '5.8%', 'left': '32.11%', 'top': '61%', 'z-index': '10'},
197 | }
198 | ],
199 | 'off': [
200 | {
201 | 'image': 'door-open.png',
202 | 'style': { 'width': '5.8%', 'left': '32.11%', 'top': '61%', 'z-index': '10'},
203 | },
204 | ],
205 | },
206 | 'garage': {
207 | 'open': [
208 | {
209 | 'image': 'garage-open.png',
210 | 'style': { 'width': '23%', 'height': '34%', 'left': '61.2%', 'top': '57.5%', 'z-index': '10' },
211 | },
212 | ],
213 | 'closed': [
214 | {
215 | 'image': 'garage-close.png',
216 | 'style': { 'width': '23%', 'height': '34%', 'left': '61.2%', 'top': '57.5%', 'z-index': '10' },
217 | },
218 | ],
219 | },
220 | 'garage2': {
221 | 'open': [
222 | {
223 | 'image': 'garage-open.png',
224 | 'style': { 'width': '13%', 'height': '34%', 'left': '83.7%', 'top': '57.5%', 'z-index': '10', 'filter': 'contrast(80%)' },
225 | }
226 | ],
227 | 'closed': [
228 | {
229 | 'image': 'garage-close.png',
230 | 'style': { 'width': '13%', 'height': '34%', 'left': '83.7%', 'top': '57.5%', 'z-index': '10', 'filter': 'contrast(80%)' },
231 | }
232 | ],
233 | },
234 | 'outside_light': {
235 | 'on': [
236 | {
237 | 'image': 'outside-light-on.png',
238 | 'style': { 'width': '6%', 'left': '12.3%', 'top': '70.5%', 'z-index': '10' },
239 | },
240 | {
241 | 'image': 'outside-light-on.png',
242 | 'style': { 'width': '6%', 'left': '21.2%', 'top': '70.5%', 'z-index': '10' },
243 | },
244 | {
245 | 'image': 'outside-light-on.png',
246 | 'style': { 'width': '6%', 'left': '42.8%', 'top': '70.5%', 'z-index': '10' },
247 | },
248 | ],
249 | 'off': [
250 | {
251 | 'image': 'outside-light-off.png',
252 | 'style': { 'width': '6%', 'left': '12.3%', 'top': '70.5%', 'z-index': '10' },
253 | },
254 | {
255 | 'image': 'outside-light-off.png',
256 | 'style': { 'width': '6%', 'left': '21.2%', 'top': '70.5%', 'z-index': '10' },
257 | },
258 | {
259 | 'image': 'outside-light-off.png',
260 | 'style': { 'width': '6%', 'left': '42.8%', 'top': '70.5%', 'z-index': '10' },
261 | },
262 | ],
263 | },
264 | 'downstairs_light': {
265 | 'on': [
266 | ],
267 | 'off': [
268 | ]
269 | },
270 | 'upstairs_light': {
271 | 'on': [
272 | {
273 | 'image': 'window-light.png',
274 | 'style': { 'width': '4.5%', 'left': '15.5%', 'top': '53.6%', 'z-index': '10' },
275 | },
276 | {
277 | 'image': 'window-light.png',
278 | 'style': { 'width': '4.5%', 'left': '19.5%', 'top': '53.6%', 'z-index': '10' },
279 | },
280 | {
281 | 'image': 'window-light.png',
282 | 'style': { 'width': '4.5%', 'left': '42.3%', 'top': '53.6%', 'z-index': '10' },
283 | },
284 | ],
285 | 'off': [
286 | {
287 | 'image': 'window-dark.png',
288 | 'style': { 'width': '4.5%', 'left': '15.5%', 'top': '53.6%', 'z-index': '10' },
289 | },
290 | {
291 | 'image': 'window-dark.png',
292 | 'style': { 'width': '4.5%', 'left': '19.5%', 'top': '53.6%', 'z-index': '10' },
293 | },
294 | {
295 | 'image': 'window-dark.png',
296 | 'style': { 'width': '4.5%', 'left': '42.3%', 'top': '53.6%', 'z-index': '10' },
297 | },
298 | ]
299 | },
300 | 'car': {
301 | 'home': [
302 | {
303 | 'image': 'car.png',
304 | 'style': { 'width': '11%', 'left': '55.2%', 'top': '72%', 'z-index': '10' },
305 | },
306 | ],
307 | },
308 | 'car2': {
309 | 'home': [
310 | {
311 | 'image': 'car.png',
312 | 'style': { 'width': '11%', 'left': '67.2%', 'top': '72%', 'z-index': '10' },
313 | },
314 | ],
315 | },
316 | 'car3': {
317 | 'home': [
318 | {
319 | 'image': 'car.png',
320 | 'style': { 'width': '11%', 'left': '84%', 'top': '72%', 'z-index': '10' },
321 | },
322 | ],
323 | },
324 | 'sprinkler': {
325 | 'on': [
326 | {
327 | 'image': 'sprinkler-on.png',
328 | 'style': { 'width': '6%', 'left': '18%', 'top': '74%', 'z-index': '10' },
329 | },
330 | {
331 | 'image': 'sprinkler-on.png',
332 | 'style': { 'width': '6%', 'left': '40%', 'top': '78%', 'z-index': '10' },
333 | },
334 | ],
335 | 'off': [
336 | {
337 | 'image': 'sprinkler-off.png',
338 | 'style': { 'width': '6%', 'left': '18%', 'top': '74%', 'z-index': '10' },
339 | },
340 | {
341 | 'image': 'sprinkler-off.png',
342 | 'style': { 'width': '6%', 'left': '40%', 'top': '78%', 'z-index': '10' },
343 | },
344 | ],
345 | },
346 | },
347 | },
348 | };
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/car.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/door-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/door-close.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/door-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/door-open.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/garage-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/garage-close.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/garage-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/garage-open.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/house.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/house.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/outside-light-off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/outside-light-off.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/outside-light-on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/outside-light-on.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/sprinkler-off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/sprinkler-off.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/sprinkler-on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/sprinkler-on.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/utility-electricity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/utility-electricity.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/utility-water.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/utility-water.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-cloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-cloudy.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-exceptional.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-exceptional.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-fog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-fog.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-hail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-hail.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-lightning-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-lightning-rainy.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-lightning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-lightning.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-partlycloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-partlycloudy.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-pouring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-pouring.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-rainy.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-snowy-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-snowy-rainy.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-snowy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-snowy.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-sun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-sun.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-sunny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-sunny.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-windy-variant.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-windy-variant.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/weather-windy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/weather-windy.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/window-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/window-dark.png
--------------------------------------------------------------------------------
/themes/ranch_with_three_stall_garage/window-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/ranch_with_three_stall_garage/window-light.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/car.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/door-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/door-close.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/door-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/door-open.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/garage-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/garage-close.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/garage-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/garage-open.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/house.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/house.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/outside-light-off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/outside-light-off.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/outside-light-on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/outside-light-on.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/sprinkler-off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/sprinkler-off.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/sprinkler-on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/sprinkler-on.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/utility-electricity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/utility-electricity.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/utility-water.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/utility-water.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-cloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-cloudy.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-exceptional.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-exceptional.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-fog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-fog.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-hail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-hail.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-lightning-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-lightning-rainy.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-lightning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-lightning.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-partlycloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-partlycloudy.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-pouring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-pouring.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-rainy.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-snowy-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-snowy-rainy.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-snowy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-snowy.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-sun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-sun.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-sunny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-sunny.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-windy-variant.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-windy-variant.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/weather-windy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/weather-windy.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/window-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/window-dark.png
--------------------------------------------------------------------------------
/themes/two_story_with_garage/window-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/postlund/home-card/8d21f1addbc8718450d4e31804be0aaba8b5bec9/themes/two_story_with_garage/window-light.png
--------------------------------------------------------------------------------