diff --git a/.eslintrc.json b/.eslintrc.json
index 4b4cc1aa..e2484ad2 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -6,7 +6,7 @@
"es6": true
},
"parserOptions": {
- "ecmaVersion": 2018,
+ "ecmaVersion": 2020,
"sourceType": "module"
}
}
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..1534e0ff
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,14 @@
+version: 2
+updates:
+ # Maintain dependencies for GitHub Actions
+ - package-ecosystem: 'github-actions'
+ directory: '/'
+ schedule:
+ interval: 'monthly'
+
+ # Maintain dependencies for npm
+ - package-ecosystem: 'npm'
+ directory: '/'
+ schedule:
+ interval: 'monthly'
+ open-pull-requests-limit: 10
diff --git a/.prettierrc.json b/.prettierrc.json
deleted file mode 100644
index 544138be..00000000
--- a/.prettierrc.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "singleQuote": true
-}
diff --git a/LICENSE.md b/LICENSE.md
index 6893c343..bc9c0bcf 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2019 Custom cards for Home Assistant
+Copyright (c) 2022 Denys Dovhan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index af73acb5..ae80392a 100644
--- a/README.md
+++ b/README.md
@@ -49,7 +49,7 @@ Just search for `Vacuum Card` in plugins tab.
```
4. Add `custom:vacuum-card` to Lovelace UI as any other card (using either editor or YAML configuration).
-## Using the card
+## Usage
This card can be configured using Lovelace UI editor.
@@ -88,9 +88,10 @@ stats:
unit: hours
subtitle: Sensors
cleaning:
- - attribute: cleaned_area
- unit: m2
- subtitle: Cleaning area
+ - value_template: >-
+ {{ (states('sensor.vacuum_main_brush_left') | float(0) / 3600) | round(1) }}
+ subtitle: Main brush
+ unit: hours
- attribute: cleaning_time
unit: minutes
subtitle: Cleaning time
@@ -127,12 +128,13 @@ Here is what every option means:
You can use any attribute of vacuum or even any entity by `entity_id` to display by stats section:
-| Name | Type | Default | Description |
-| ----------- | :------: | -------- | ----------------------------------------------- |
-| `entity_id` | `string` | Optional | An entity_id with state, i.e. `sensor.vacuum`. |
-| `attribute` | `string` | Optional | Attribute name of the stat, i.e. `filter_left`. |
-| `unit` | `string` | Optional | Unit of measure, i.e. `hours`. |
-| `subtitle` | `string` | Optional | Friendly name of the stat, i.e. `Filter`. |
+| Name | Type | Default | Description |
+| ---------------- | :------: | -------- | ----------------------------------------------- |
+| `entity_id` | `string` | Optional | An entity_id with state, i.e. `sensor.vacuum`. |
+| `attribute` | `string` | Optional | Attribute name of the stat, i.e. `filter_left`. |
+| `value_template` | `string` | Optional | Jinja2 template returning a value. |
+| `unit` | `string` | Optional | Unit of measure, i.e. `hours`. |
+| `subtitle` | `string` | Optional | Friendly name of the stat, i.e. `Filter`. |
### `actions` object
@@ -154,6 +156,46 @@ You can defined [custom scripts][ha-scripts] for custom actions i.e cleaning spe
| `icon` | `string` | Optional | Any icon for action button. |
| `service_data` | `object` | `service_data` for `service` call |
+## Theming
+
+This card can be styled by changing the values of these CSS properties (globally or per-card via [`card-mod`][card-mod]):
+
+| Variable | Default value | Description |
+| --------------------------- | ---------------------------------------------------------------- | ------------------------------------ |
+| `--vc-background` | `var(--ha-card-background, var(--card-background-color, white))` | Background of the card |
+| `--vc-primary-text-color` | `var(--primary-text-color)` | Vacuum name, stats values, etc |
+| `--vc-secondary-text-color` | `var(--secondary-text-color)` | Status, stats units and titles, etc |
+| `--vc-icon-color` | `var(--secondary-text-color)` | Colors of icons |
+| `--vc-toolbar-background` | `var(--vc-background)` | Background of the toolbar |
+| `--vc-toolbar-text-color` | `var(--secondary-text-color)` | Color of the toolbar texts |
+| `--vc-toolbar-icon-color` | `var(--secondary-text-color)` | Color of the toolbar icons |
+| `--vc-divider-color` | `var(--entities-divider-color, var(--divider-color))` | Color of dividers |
+| `--vc-spacing` | `10px` | Paddings and margins inside the card |
+
+### Styling via theme
+
+Here is an example of customization via theme. Read more in the [Frontend documentation](https://www.home-assistant.io/integrations/frontend/).
+
+```yaml
+my-custom-theme:
+ vc-background: '#17A8F4'
+ vc-spacing: 5px
+```
+
+### Styling via card-mod
+
+You can use [`card-mod`][card-mod] to customize the card on per-card basis, like this:
+
+```yaml
+type: 'custom:vacuum-card'
+style: |
+ ha-card {
+ --vc-background: #17A8F4;
+ --vc-spacing: 5px;
+ }
+ ...
+```
+
## Animations
I've added some animations for this card to make it alive. Animations are applied only for `image` property. Here's how they look like:
@@ -199,52 +241,18 @@ This card relies on basic vacuum services, like `pause`, `start`, `stop`, `retur
If this card works with your vacuum cleaner, please open a PR and your model to the list.
-- Roborock S7
-- Roborock S6 MaxV
-- Roborock S6
-- Roborock S6 Pure
-- Roborock S5
-- Roborock S5 Max
-- Roborock S50
-- Roborock S4
-- Roborock S4 Max
-- Roborock E25
-- Roborock E4
-- Mijia Robot Vacuum Cleaner 1C (STYTJ01ZHM)
-- Xiaomi Mi Robot (STYJ02YM)
-- Xiaomi Mi Robot 1S
-- Xiaomi Mi Roborock V1 (SDJQR02RR)
-- Xiaomi Mijia 1C
-- Roomba 675
-- Roomba 676
-- Roomba 960
-- Roomba 980
-- Roomba 981
-- Roomba i3
-- Roomba i7+
-- Roomba e5
-- Roomba S9
-- Braava M6
-- Roomba s9+
-- Roomba j7
-- Dyson 360 Eye
-- Neato D7
-- Neato D6
-- Neato D4
-- Shark IQ
-- Ecovacs Deebot 950
-- EcoVacs Deebot OZMO T8 AIVI
-- EcoVacs Deebot N79
-- EcoVacs Deebot N8
-- EcoVacs Deebot N8+
-- Eufy Robovac 30c
-- Eufy Robovac 15C Max
-- Mi Robot Vacuum-Mop P
-- EcoVacs T9 AIVI
-- Dreame Z10 Pro
-- Dreame L10 Pro
-- Dreame D9
-- Dreame F9
+- **Roborock** S7, S6 (MaxV, Pure), S5 (Max), S50, S4 (Max), E25, E4
+- **Mijia** Robot Vacuum Cleaner 1C (STYTJ01ZHM)
+- **Xiaomi** Mi Robot (STYJ02YM), Mi Robot 1S, Mi Roborock V1 (SDJQR02RR), Mijia 1C, Mi Robot Vacuum-Mop P
+- **Roomba** 675, 676, 960980, 981, i3, i7+, e5, S9, s9+, j7
+- **Braava** M6
+- **Dyson** 360 Eye
+- **Neato** D7, D6, D4
+- **Shark** IQ
+- **Ecova**cs Deebot 950, Deebot OZMO T8 AIVI, Deebot N79, Deebot N8, Deebot N8+, T9 AIVI
+- **Eufy** Robovac 30c, Robovac 15C Max
+- **EcoVacs** T9 AIVI
+- **Dreame** Z10 Pro, L10 Pro, D9, F9
- 360 S7 Pro
- [_Your vacuum?_][edit-readme]
@@ -284,12 +292,13 @@ MIT © [Denys Dovhan][denysdovhan]
[home-assistant]: https://www.home-assistant.io/
[hacs]: https://hacs.xyz
-[preview-image]: https://user-images.githubusercontent.com/3459374/83282788-c9e30280-a1e2-11ea-8e13-6208169ddc0a.png
+[preview-image]: https://user-images.githubusercontent.com/3459374/164231294-d2c26bbd-ae34-4b41-b909-3a0ae259259e.png
[cleaning-gif]: https://user-images.githubusercontent.com/3459374/81119202-fa60b500-8f32-11ea-9b23-325efa93d7ab.gif
[returning-gif]: https://user-images.githubusercontent.com/3459374/81119452-765afd00-8f33-11ea-9dc5-9c26ba3f8c45.gif
[latest-release]: https://github.com/denysdovhan/vacuum-card/releases/latest
[ha-scripts]: https://www.home-assistant.io/docs/scripts/
[edit-readme]: https://github.com/denysdovhan/vacuum-card/edit/master/README.md
+[card-mod]: https://github.com/thomasloven/lovelace-card-mod
[add-translation]: https://github.com/denysdovhan/vacuum-card/blob/master/CONTRIBUTING.md#how-to-add-translation
[macbury-smart-house]: https://macbury.github.io/SmartHouse/HomeAssistant/Vacuum/
[bbbenji-card]: https://gist.github.com/bbbenji/24372e423f8669b2e6713638d8f8ceb2
diff --git a/package-lock.json b/package-lock.json
index e9b62865..a3f72fbd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,8 @@
"license": "MIT",
"dependencies": {
"custom-card-helpers": "^1.6.4",
- "lit-element": "^2.3.1",
+ "ha-template": "^1.0.1",
+ "lit": "^2.0.0",
"lodash.get": "^4.4.2"
},
"devDependencies": {
@@ -493,6 +494,11 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
+ "node_modules/@lit/reactive-element": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.0.tgz",
+ "integrity": "sha512-0TKSIuJHXNLM0k98fi0AdMIdUoHIYlDHTP+0Vruc2SOs4T6vU1FinXgSvYd8mSrkt+8R+qdRAXvjpqrMXMyBgw=="
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
@@ -1269,6 +1275,11 @@
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
"dev": true
},
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz",
+ "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg=="
+ },
"node_modules/@types/uglify-js": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz",
@@ -3661,6 +3672,14 @@
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
"dev": true
},
+ "node_modules/ha-template": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ha-template/-/ha-template-1.0.1.tgz",
+ "integrity": "sha512-Yn/GTXuiiu1g7X/5GDdf3x2uWHNzTkC418mqGmT3e9uGHmPsEsDZJrEQfBWlpWiv7QHfW9ORAhXbi5JyeJQ7oQ==",
+ "peerDependencies": {
+ "lit": "^2.0.0"
+ }
+ },
"node_modules/handlebars": {
"version": "4.7.7",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
@@ -4977,6 +4996,16 @@
"node": ">=8"
}
},
+ "node_modules/lit": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.0.tgz",
+ "integrity": "sha512-FDyxUuczo6cJJY/2Bkgfh1872U4ikUvmK1Cb6+lYC1CW+QOo8CaWXCpvPKFzYsz0ojUxoruBLVrECc7VI2f1dQ==",
+ "dependencies": {
+ "@lit/reactive-element": "^1.3.0",
+ "lit-element": "^3.2.0",
+ "lit-html": "^2.2.0"
+ }
+ },
"node_modules/lit-element": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-2.3.1.tgz",
@@ -4990,6 +5019,23 @@
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.2.1.tgz",
"integrity": "sha512-GSJHHXMGLZDzTRq59IUfL9FCdAlGfqNp/dEa7k7aBaaWD+JKaCjsAk9KYm2V12ItonVaYx2dprN66Zdm1AuBTQ=="
},
+ "node_modules/lit/node_modules/lit-element": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.0.tgz",
+ "integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
+ "dependencies": {
+ "@lit/reactive-element": "^1.3.0",
+ "lit-html": "^2.2.0"
+ }
+ },
+ "node_modules/lit/node_modules/lit-html": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.0.tgz",
+ "integrity": "sha512-dJnevgV8VkCuOXLWrjQopDE8nSy8CzipZ/ATfYQv7z7Dct4abblcKecf50gkIScuwCTzKvRLgvTgV0zzagW4gA==",
+ "dependencies": {
+ "@types/trusted-types": "^2.0.2"
+ }
+ },
"node_modules/loader-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz",
@@ -12454,6 +12500,11 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
+ "@lit/reactive-element": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.0.tgz",
+ "integrity": "sha512-0TKSIuJHXNLM0k98fi0AdMIdUoHIYlDHTP+0Vruc2SOs4T6vU1FinXgSvYd8mSrkt+8R+qdRAXvjpqrMXMyBgw=="
+ },
"@nodelib/fs.scandir": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
@@ -13075,6 +13126,11 @@
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
"dev": true
},
+ "@types/trusted-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz",
+ "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg=="
+ },
"@types/uglify-js": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz",
@@ -14901,6 +14957,12 @@
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
"dev": true
},
+ "ha-template": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ha-template/-/ha-template-1.0.1.tgz",
+ "integrity": "sha512-Yn/GTXuiiu1g7X/5GDdf3x2uWHNzTkC418mqGmT3e9uGHmPsEsDZJrEQfBWlpWiv7QHfW9ORAhXbi5JyeJQ7oQ==",
+ "requires": {}
+ },
"handlebars": {
"version": "4.7.7",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
@@ -15851,6 +15913,35 @@
}
}
},
+ "lit": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.0.tgz",
+ "integrity": "sha512-FDyxUuczo6cJJY/2Bkgfh1872U4ikUvmK1Cb6+lYC1CW+QOo8CaWXCpvPKFzYsz0ojUxoruBLVrECc7VI2f1dQ==",
+ "requires": {
+ "@lit/reactive-element": "^1.3.0",
+ "lit-element": "^3.2.0",
+ "lit-html": "^2.2.0"
+ },
+ "dependencies": {
+ "lit-element": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.0.tgz",
+ "integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
+ "requires": {
+ "@lit/reactive-element": "^1.3.0",
+ "lit-html": "^2.2.0"
+ }
+ },
+ "lit-html": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.0.tgz",
+ "integrity": "sha512-dJnevgV8VkCuOXLWrjQopDE8nSy8CzipZ/ATfYQv7z7Dct4abblcKecf50gkIScuwCTzKvRLgvTgV0zzagW4gA==",
+ "requires": {
+ "@types/trusted-types": "^2.0.2"
+ }
+ }
+ }
+ },
"lit-element": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-2.3.1.tgz",
diff --git a/package.json b/package.json
index 7622de7b..970c4224 100755
--- a/package.json
+++ b/package.json
@@ -24,7 +24,8 @@
"license": "MIT",
"dependencies": {
"custom-card-helpers": "^1.6.4",
- "lit-element": "^2.3.1",
+ "ha-template": "^1.0.1",
+ "lit": "^2.0.0",
"lodash.get": "^4.4.2"
},
"devDependencies": {
@@ -64,6 +65,9 @@
"*.js": "eslint --fix",
"*.{js,json,css,yml,md}": "prettier --write"
},
+ "prettier": {
+ "singleQuote": true
+ },
"release": {
"plugins": [
"@semantic-release/commit-analyzer",
diff --git a/rollup.config.js b/rollup.config.js
index 36a31b15..af32bbd2 100755
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -38,7 +38,14 @@ export default {
exclude: 'node_modules/**',
}),
postcss({
- plugins: [postcssPresetEnv()],
+ plugins: [
+ postcssPresetEnv({
+ stage: 1,
+ features: {
+ 'nesting-rules': true,
+ },
+ }),
+ ],
extract: false,
}),
postcssLit({
diff --git a/src/styles.css b/src/styles.css
index 5ce16a13..84736f4b 100755
--- a/src/styles.css
+++ b/src/styles.css
@@ -1,4 +1,17 @@
:host {
+ --vc-background: var(
+ --ha-card-background,
+ var(--card-background-color, white)
+ );
+ --vc-primary-text-color: var(--primary-text-color);
+ --vc-secondary-text-color: var(--secondary-text-color);
+ --vc-icon-color: var(--secondary-text-color);
+ --vc-toolbar-background: var(--vc-background);
+ --vc-toolbar-text-color: var(--secondary-text-color);
+ --vc-toolbar-icon-color: var(--secondary-text-color);
+ --vc-divider-color: var(--entities-divider-color, var(--divider-color));
+ --vc-spacing: 10px;
+
display: flex;
flex: 1;
flex-direction: column;
@@ -8,25 +21,41 @@ ha-card {
flex-direction: column;
flex: 1;
position: relative;
- padding: 0px;
- border-radius: 4px;
+ overflow: hidden;
}
.preview {
- background: var(--primary-color);
- cursor: pointer;
+ background: var(--vc-background);
+ overflow: hidden;
position: relative;
text-align: center;
- border-radius: 4px 4px 0 0;
+
+ &.not-available {
+ filter: grayscale(1);
+ }
}
-.preview.not-available {
- filter: grayscale(1);
+.header {
+ display: flex;
+ justify-content: space-between;
+}
+
+.tips {
+ display: flex;
+ gap: var(--vc-spacing);
+ flex-grow: 1;
+ flex-wrap: wrap;
+ padding: var(--vc-spacing);
+
+ & .tip {
+ cursor: pointer;
+ }
}
.map {
max-width: 95%;
image-rendering: crisp-edges;
+ cursor: pointer;
}
@keyframes cleaning {
@@ -103,7 +132,9 @@ ha-card {
max-width: 90%;
max-height: 200px;
image-rendering: crisp-edges;
- margin: 30px auto 20px auto;
+ margin: var(--vc-spacing) auto;
+ cursor: pointer;
+ filter: brightness(0.9);
}
.vacuum.on,
@@ -131,24 +162,8 @@ ha-card {
flex-grow: 1;
}
-.header {
- height: 40px;
+.more-info ha-icon {
display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- color: var(--text-primary-color);
-}
-
-.battery {
- text-align: right;
- font-weight: bold;
- padding: 8px;
-}
-
-.source {
- padding-left: 7px;
- text-align: center;
}
.status {
@@ -159,117 +174,100 @@ ha-card {
}
.status-text {
- color: var(--text-primary-color);
+ color: var(--vc-secondary-text-color);
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
- margin-left: calc(20px + 9px); /* size + margin of spinner */
+ margin-left: calc(28px + var(--vc-spacing)); /* size + margin of spinner */
}
-.status ha-circular-progress {
- --mdc-theme-primary: var(
- --card-background-color
- ); /* hack to override the color */
- min-width: 24px;
- width: 24px;
- height: 24px;
- margin-left: 9px;
+.status mwc-circular-progress {
+ --mdc-theme-primary: var(--vc-secondary-text-color) !important;
+ margin-left: var(--vc-spacing);
}
.vacuum-name {
text-align: center;
font-weight: bold;
- color: var(--text-primary-color);
+ color: var(--vc-primary-text-color);
font-size: 16px;
}
.not-available .offline {
text-align: center;
- color: var(--text-primary-color);
+ color: var(--vc-primary-text-color);
font-size: 16px;
}
.metadata {
- margin: 10px auto;
+ margin: var(--vc-spacing) auto;
}
.stats {
- border-top: 1px solid rgba(255, 255, 255, 0.2);
+ border-top: 1px solid var(--vc-divider-color);
display: flex;
flex-direction: row;
justify-content: space-evenly;
- color: var(--text-primary-color);
+ color: var(--vc-secondary-text-color);
}
.stats-block {
- margin: 10px 0px;
+ cursor: pointer;
+ margin: var(--vc-spacing) 0px;
text-align: center;
- border-right: 1px solid rgba(255, 255, 255, 0.2);
+ border-right: 1px solid var(--vc-divider-color);
flex-grow: 1;
-}
-.stats-block:last-child {
- border: 0px;
+ &:last-of-type {
+ border-right: 0px;
+ }
}
.stats-value {
font-size: 20px;
- font-weight: bold;
+ color: var(--vc-primary-text-color);
}
ha-icon {
- color: #fff;
+ color: var(--vc-icon-color);
}
.toolbar {
- background: var(--lovelace-background, var(--primary-background-color));
- border-radius: 0 0 4px 4px;
+ background: var(--vc-toolbar-background);
min-height: 30px;
display: flex;
flex-direction: row;
flex-flow: row wrap;
flex-wrap: wrap;
justify-content: space-evenly;
+ padding: 5px;
+ border-top: 1px solid var(--vc-divider-color);
}
.toolbar ha-icon-button {
- color: var(--primary-color);
+ color: var(--vc-toolbar-text-color);
flex-direction: column;
width: 44px;
height: 44px;
--mdc-icon-button-size: 44px;
- margin: 5px 0;
-}
-
-.toolbar ha-icon-button:first-child {
- margin-left: 5px;
-}
-
-.toolbar ha-icon-button:last-child {
- margin-right: 5px;
}
.toolbar paper-button {
- color: var(--primary-color);
- flex-direction: column;
+ color: var(--vc-toolbar-text-color);
+ display: flex;
+ align-items: center;
margin-right: 10px;
padding: 15px 10px;
cursor: pointer;
-}
-.toolbar ha-icon-button:active,
-.toolbar paper-button:active {
- opacity: 0.4;
- background: rgba(0, 0, 0, 0.1);
-}
-
-.toolbar paper-button {
- color: var(--primary-color);
- flex-direction: row;
+ & ha-icon {
+ margin-right: 5px;
+ color: var(--vc-toolbar-icon-color);
+ }
}
.toolbar ha-icon {
- color: var(--primary-color);
+ color: var(--vc-toolbar-icon-color);
display: flex;
}
diff --git a/src/translations/cs.json b/src/translations/cs.json
index ddae1612..567a9041 100644
--- a/src/translations/cs.json
+++ b/src/translations/cs.json
@@ -1,59 +1,59 @@
{
- "status": {
- "cleaning": "Vysává se",
- "auto": "Automatické vysávání",
- "spot": "Vysávání na místě",
- "edge": "Vysávání při okraji",
- "single_room": "Vysávání jedné místnosti",
- "paused": "Pozastaveno",
- "idle": "Nečinný",
- "stop": "Stopped",
- "charging": "Nabíjí se",
- "returning home": "Vrací se do stanice",
- "returning": "Vrací se",
- "docked": "Ve stanici",
- "unknown": "Neznámý",
- "offline": "Vypnuto",
- "error": "Chyba"
- },
- "source": {
- "gentle": "Mírný",
- "silent": "Tichý",
- "standard": "Standardní",
- "medium": "Střední",
- "turbo": "Turbo",
- "normal": "Normální",
- "high": "Vysoký",
- "strong": "Silný",
- "quiet": "Tichý",
- "max": "Max",
- "max+": "Max+"
- },
- "common": {
- "name": "Karta vysavače",
- "description": "Karta vysavače vám dovolí ovládat svůj vysavač.",
- "start": "Začni vysávat",
- "continue": "Pokračuj",
- "pause": "Pozastav",
- "stop": "Zastav",
- "return_to_base": "Vrať se domů",
- "locate": "Lokalizuj",
- "not_available": "Vysavač není dostupný"
- },
- "error": {
- "missing_entity": "Je vyžadováno specifikování entity!"
- },
- "warning": {
- "actions_array": "VAROVÁNÍ: 'actions' jsou rezervovány pro přepsání původních akcí u existujících tlačítek. Pokud jste chtěli měli v plánu přidat další akce, použijte namísto toho možnost 'shortcuts'."
- },
- "editor": {
- "entity": "Entita (Povinný)",
- "map": "Mapa (Nepovinný)",
- "image": "Fotka (Nepovinný)",
- "compact_view": "Kompaktní zobrazení",
- "compact_view_aria_label_on": "Zapni kompaktní zobrazení",
- "compact_view_aria_label_off": "Vypni kompaktní zobrazení",
- "show_name": "Zobraz název",
+ "status": {
+ "cleaning": "Vysává se",
+ "auto": "Automatické vysávání",
+ "spot": "Vysávání na místě",
+ "edge": "Vysávání při okraji",
+ "single_room": "Vysávání jedné místnosti",
+ "paused": "Pozastaveno",
+ "idle": "Nečinný",
+ "stop": "Stopped",
+ "charging": "Nabíjí se",
+ "returning home": "Vrací se do stanice",
+ "returning": "Vrací se",
+ "docked": "Ve stanici",
+ "unknown": "Neznámý",
+ "offline": "Vypnuto",
+ "error": "Chyba"
+ },
+ "source": {
+ "gentle": "Mírný",
+ "silent": "Tichý",
+ "standard": "Standardní",
+ "medium": "Střední",
+ "turbo": "Turbo",
+ "normal": "Normální",
+ "high": "Vysoký",
+ "strong": "Silný",
+ "quiet": "Tichý",
+ "max": "Max",
+ "max+": "Max+"
+ },
+ "common": {
+ "name": "Karta vysavače",
+ "description": "Karta vysavače vám dovolí ovládat svůj vysavač.",
+ "start": "Začni vysávat",
+ "continue": "Pokračuj",
+ "pause": "Pozastav",
+ "stop": "Zastav",
+ "return_to_base": "Vrať se domů",
+ "locate": "Lokalizuj",
+ "not_available": "Vysavač není dostupný"
+ },
+ "error": {
+ "missing_entity": "Je vyžadováno specifikování entity!"
+ },
+ "warning": {
+ "actions_array": "VAROVÁNÍ: 'actions' jsou rezervovány pro přepsání původních akcí u existujících tlačítek. Pokud jste chtěli měli v plánu přidat další akce, použijte namísto toho možnost 'shortcuts'."
+ },
+ "editor": {
+ "entity": "Entita (Povinný)",
+ "map": "Mapa (Nepovinný)",
+ "image": "Fotka (Nepovinný)",
+ "compact_view": "Kompaktní zobrazení",
+ "compact_view_aria_label_on": "Zapni kompaktní zobrazení",
+ "compact_view_aria_label_off": "Vypni kompaktní zobrazení",
+ "show_name": "Zobraz název",
"show_name_aria_label_on": "Zapni zobrazení názvu",
"show_name_aria_label_off": "Vypni zobrazení názvu",
"show_status": "Zobraz status",
@@ -63,5 +63,5 @@
"show_toolbar_aria_label_on": "Zapni zobrazení lišty",
"show_toolbar_aria_label_off": "Vypni zobrazení lišty",
"code_only_note": "Poznámka: Nastavení akcí a infa je dostupné pouze v editoru kódu."
- }
}
+}
diff --git a/src/vacuum-card-editor.js b/src/vacuum-card-editor.js
index 15b2f32f..bc70b43f 100644
--- a/src/vacuum-card-editor.js
+++ b/src/vacuum-card-editor.js
@@ -1,5 +1,4 @@
-import { LitElement, html, css } from 'lit-element';
-import { nothing } from 'lit-html';
+import { LitElement, html, css, nothing } from 'lit';
import { fireEvent } from 'custom-card-helpers';
import localize from './localize';
diff --git a/src/vacuum-card.js b/src/vacuum-card.js
index df0d8622..ca07c467 100755
--- a/src/vacuum-card.js
+++ b/src/vacuum-card.js
@@ -1,12 +1,14 @@
-import { LitElement, html } from 'lit-element';
-import { nothing } from 'lit-html';
+import { LitElement, html, nothing } from 'lit';
import { hasConfigOrEntityChanged, fireEvent } from 'custom-card-helpers';
+import registerTemplates from 'ha-template';
import get from 'lodash.get';
-import './vacuum-card-editor';
import localize from './localize';
import styles from './styles.css';
import defaultImage from './vacuum.svg';
import { version } from '../package.json';
+import './vacuum-card-editor';
+
+registerTemplates();
console.info(
`%c VACUUM-CARD %c ${version} `,
@@ -149,15 +151,15 @@ class VacuumCard extends LitElement {
}
}
- handleMore() {
+ handleMore(entityId = this.entity.entity_id) {
fireEvent(
this,
'hass-more-info',
{
- entityId: this.entity.entity_id,
+ entityId,
},
{
- bubbles: true,
+ bubbles: false,
composed: true,
}
);
@@ -165,76 +167,31 @@ class VacuumCard extends LitElement {
handleSpeed(e) {
const fan_speed = e.target.getAttribute('value');
- this.callService('set_fan_speed', false, { fan_speed });
- }
-
- handleStart() {
- const actions = this.config.actions;
- if (!actions || !actions.start) {
- this.callService('start');
- return;
- }
-
- this.callAction(actions.start);
+ this.callService('set_fan_speed', { isRequest: false }, { fan_speed });
}
- handlePause() {
- const actions = this.config.actions;
- if (!actions || !actions.pause) {
- this.callService('pause');
- return;
- }
-
- this.callAction(actions.pause);
- }
-
- handleResume() {
- const actions = this.config.actions;
- if (!actions || !actions.resume) {
- this.callService('start');
- return;
- }
-
- this.callAction(actions.resume);
- }
+ handleAction(action, params = { isRequest: true }) {
+ const actions = this.config.actions || {};
- handleStop() {
- const actions = this.config.actions;
- if (!actions || !actions.stop) {
- this.callService('stop');
- return;
- }
-
- this.callAction(actions.stop);
- }
-
- handleLocate() {
- const actions = this.config.actions;
- if (!actions || !actions.locate) {
- this.callService('locate', false);
- return;
- }
-
- this.callAction(actions.locate);
- }
-
- handleReturnToBase() {
- const actions = this.config.actions;
- if (!actions || !actions.return_to_base) {
- this.callService('return_to_base');
- return;
- }
+ return () => {
+ if (!actions[action]) {
+ this.callService(params.defaultService || action, {
+ isRequest: params.isRequest,
+ });
+ return;
+ }
- this.callAction(actions.return_to_base);
+ this.callAction(actions[action]);
+ };
}
- callService(service, isRequest = true, options = {}) {
+ callService(service, params = { isRequest: true }, options = {}) {
this.hass.callService('vacuum', service, {
entity_id: this.config.entity,
...options,
});
- if (isRequest) {
+ if (params.isRequest) {
this.requestInProgress = true;
this.requestUpdate();
}
@@ -279,24 +236,39 @@ class VacuumCard extends LitElement {
const selected = sources.indexOf(source);
return html`
-