Skip to content

Commit e2b72b1

Browse files
authored
Merge branch 'dev' into picture-card-image
2 parents 905bc08 + 501c72d commit e2b72b1

File tree

54 files changed

+4119
-612
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+4119
-612
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
title: Lawn mower
3+
---
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import type { PropertyValues, TemplateResult } from "lit";
2+
import { html, LitElement } from "lit";
3+
import { customElement, property, query } from "lit/decorators";
4+
import "../../../../src/components/ha-card";
5+
import "../../../../src/dialogs/more-info/more-info-content";
6+
import type { MockHomeAssistant } from "../../../../src/fake_data/provide_hass";
7+
import { provideHass } from "../../../../src/fake_data/provide_hass";
8+
import "../../components/demo-more-infos";
9+
import { LawnMowerEntityFeature } from "../../../../src/data/lawn_mower";
10+
11+
const ALL_FEATURES =
12+
LawnMowerEntityFeature.START_MOWING +
13+
LawnMowerEntityFeature.PAUSE +
14+
LawnMowerEntityFeature.DOCK;
15+
16+
const ENTITIES = [
17+
{
18+
entity_id: "lawn_mower.full_featured",
19+
state: "docked",
20+
attributes: {
21+
friendly_name: "Full featured mower",
22+
supported_features: ALL_FEATURES,
23+
},
24+
},
25+
{
26+
entity_id: "lawn_mower.mowing",
27+
state: "mowing",
28+
attributes: {
29+
friendly_name: "Mowing",
30+
supported_features: ALL_FEATURES,
31+
},
32+
},
33+
{
34+
entity_id: "lawn_mower.returning",
35+
state: "returning",
36+
attributes: {
37+
friendly_name: "Returning",
38+
supported_features:
39+
LawnMowerEntityFeature.START_MOWING +
40+
LawnMowerEntityFeature.PAUSE +
41+
LawnMowerEntityFeature.DOCK,
42+
},
43+
},
44+
{
45+
entity_id: "lawn_mower.paused",
46+
state: "paused",
47+
attributes: {
48+
friendly_name: "Paused",
49+
supported_features: ALL_FEATURES,
50+
},
51+
},
52+
{
53+
entity_id: "lawn_mower.error",
54+
state: "error",
55+
attributes: {
56+
friendly_name: "Error",
57+
supported_features:
58+
LawnMowerEntityFeature.START_MOWING + LawnMowerEntityFeature.DOCK,
59+
},
60+
},
61+
{
62+
entity_id: "lawn_mower.basic",
63+
state: "docked",
64+
attributes: {
65+
friendly_name: "Basic mower",
66+
supported_features: LawnMowerEntityFeature.START_MOWING,
67+
},
68+
},
69+
];
70+
71+
@customElement("demo-more-info-lawn-mower")
72+
class DemoMoreInfoLawnMower extends LitElement {
73+
@property({ attribute: false }) public hass!: MockHomeAssistant;
74+
75+
@query("demo-more-infos") private _demoRoot!: HTMLElement;
76+
77+
protected render(): TemplateResult {
78+
return html`
79+
<demo-more-infos
80+
.hass=${this.hass}
81+
.entities=${ENTITIES.map((ent) => ent.entity_id)}
82+
></demo-more-infos>
83+
`;
84+
}
85+
86+
protected firstUpdated(changedProperties: PropertyValues) {
87+
super.firstUpdated(changedProperties);
88+
const hass = provideHass(this._demoRoot);
89+
hass.updateTranslations(null, "en");
90+
hass.addEntities(ENTITIES);
91+
}
92+
}
93+
94+
declare global {
95+
interface HTMLElementTagNameMap {
96+
"demo-more-info-lawn-mower": DemoMoreInfoLawnMower;
97+
}
98+
}

gallery/src/pages/more-info/vacuum.ts

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,101 @@ import { provideHass } from "../../../../src/fake_data/provide_hass";
88
import "../../components/demo-more-infos";
99
import { VacuumEntityFeature } from "../../../../src/data/vacuum";
1010

11+
const ALL_FEATURES =
12+
VacuumEntityFeature.STATE +
13+
VacuumEntityFeature.START +
14+
VacuumEntityFeature.PAUSE +
15+
VacuumEntityFeature.STOP +
16+
VacuumEntityFeature.RETURN_HOME +
17+
VacuumEntityFeature.FAN_SPEED +
18+
VacuumEntityFeature.BATTERY +
19+
VacuumEntityFeature.STATUS +
20+
VacuumEntityFeature.LOCATE +
21+
VacuumEntityFeature.CLEAN_SPOT +
22+
VacuumEntityFeature.CLEAN_AREA;
23+
1124
const ENTITIES = [
1225
{
13-
entity_id: "vacuum.first_floor_vacuum",
26+
entity_id: "vacuum.full_featured",
27+
state: "docked",
28+
attributes: {
29+
friendly_name: "Full featured vacuum",
30+
supported_features: ALL_FEATURES,
31+
battery_level: 85,
32+
battery_icon: "mdi:battery-80",
33+
fan_speed: "balanced",
34+
fan_speed_list: ["silent", "standard", "balanced", "turbo", "max"],
35+
status: "Charged",
36+
},
37+
},
38+
{
39+
entity_id: "vacuum.cleaning_vacuum",
40+
state: "cleaning",
41+
attributes: {
42+
friendly_name: "Cleaning vacuum",
43+
supported_features: ALL_FEATURES,
44+
battery_level: 62,
45+
battery_icon: "mdi:battery-60",
46+
fan_speed: "turbo",
47+
fan_speed_list: ["silent", "standard", "balanced", "turbo", "max"],
48+
status: "Cleaning bedroom",
49+
},
50+
},
51+
{
52+
entity_id: "vacuum.returning_vacuum",
53+
state: "returning",
54+
attributes: {
55+
friendly_name: "Returning vacuum",
56+
supported_features:
57+
VacuumEntityFeature.STATE +
58+
VacuumEntityFeature.START +
59+
VacuumEntityFeature.PAUSE +
60+
VacuumEntityFeature.STOP +
61+
VacuumEntityFeature.RETURN_HOME +
62+
VacuumEntityFeature.BATTERY,
63+
battery_level: 23,
64+
battery_icon: "mdi:battery-20",
65+
status: "Returning to dock",
66+
},
67+
},
68+
{
69+
entity_id: "vacuum.error_vacuum",
70+
state: "error",
71+
attributes: {
72+
friendly_name: "Error vacuum",
73+
supported_features:
74+
VacuumEntityFeature.STATE +
75+
VacuumEntityFeature.START +
76+
VacuumEntityFeature.STOP +
77+
VacuumEntityFeature.RETURN_HOME +
78+
VacuumEntityFeature.LOCATE,
79+
status: "Stuck on obstacle",
80+
},
81+
},
82+
{
83+
entity_id: "vacuum.basic_vacuum",
1484
state: "docked",
1585
attributes: {
16-
friendly_name: "First floor vacuum",
86+
friendly_name: "Basic vacuum",
1787
supported_features:
1888
VacuumEntityFeature.START +
1989
VacuumEntityFeature.STOP +
2090
VacuumEntityFeature.RETURN_HOME,
2191
},
2292
},
93+
{
94+
entity_id: "vacuum.paused_vacuum",
95+
state: "paused",
96+
attributes: {
97+
friendly_name: "Paused vacuum",
98+
supported_features: ALL_FEATURES,
99+
battery_level: 45,
100+
battery_icon: "mdi:battery-40",
101+
fan_speed: "standard",
102+
fan_speed_list: ["silent", "standard", "balanced", "turbo", "max"],
103+
status: "Paused",
104+
},
105+
},
23106
];
24107

25108
@customElement("demo-more-info-vacuum")

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
"fuse.js": "7.3.0",
9898
"google-timezones-json": "1.2.0",
9999
"gulp-zopfli-green": "7.0.0",
100-
"hls.js": "1.6.15",
100+
"hls.js": "1.6.16",
101101
"home-assistant-js-websocket": "9.6.0",
102102
"idb-keyval": "6.2.2",
103103
"intl-messageformat": "11.2.0",
@@ -204,7 +204,7 @@
204204
"terser-webpack-plugin": "5.4.0",
205205
"ts-lit-plugin": "2.0.2",
206206
"typescript": "6.0.2",
207-
"typescript-eslint": "8.58.1",
207+
"typescript-eslint": "8.58.2",
208208
"vite-tsconfig-paths": "6.1.1",
209209
"vitest": "4.1.4",
210210
"webpack-stats-plugin": "1.1.3",

src/common/entity/state_active.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export function stateActive(stateObj: HassEntity, state?: string): boolean {
3737
case "person":
3838
return compareState !== "not_home";
3939
case "lawn_mower":
40-
return ["mowing", "error"].includes(compareState);
40+
return !["docked", "paused"].includes(compareState);
4141
case "lock":
4242
return compareState !== "locked";
4343
case "media_player":

src/components/ha-form/compute-initial-ha-form-data.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export const computeInitialHaFormData = (
7979
"attribute" in selector ||
8080
"file" in selector ||
8181
"icon" in selector ||
82+
"serial" in selector ||
8283
"template" in selector ||
8384
"text" in selector ||
8485
"theme" in selector ||

src/components/ha-gauge.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ export class HaGauge extends LitElement {
4848

4949
private _sortedLevels?: LevelDefinition[];
5050

51+
private _rescaleOnConnect = false;
52+
53+
public connectedCallback(): void {
54+
super.connectedCallback();
55+
if (this._rescaleOnConnect) {
56+
this._rescaleSvg();
57+
this._rescaleOnConnect = false;
58+
}
59+
}
60+
5161
protected firstUpdated(changedProperties: PropertyValues) {
5262
super.firstUpdated(changedProperties);
5363
afterNextRender(() => {
@@ -212,6 +222,13 @@ export class HaGauge extends LitElement {
212222
// Set the viewbox of the SVG containing the value to perfectly
213223
// fit the text
214224
// That way it will auto-scale correctly
225+
226+
if (!this.isConnected) {
227+
// Retry this later if we're disconnected, otherwise we get a 0 bbox and missing label
228+
this._rescaleOnConnect = true;
229+
return;
230+
}
231+
215232
const svgRoot = this.shadowRoot!.querySelector(".text")!;
216233
const box = svgRoot.querySelector("text")!.getBBox()!;
217234
svgRoot.setAttribute(

src/components/ha-icon.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ const CUSTOM_ICONS: Record<string, () => Promise<string>> = {
3939
import("../resources/music-assistant-logo-svg").then(
4040
(mod) => mod.mdiMusicAssistant
4141
),
42+
esphome: () =>
43+
import("../resources/esphome-logo-svg").then((mod) => mod.mdiEsphomeLogo),
4244
};
4345

4446
@customElement("ha-icon")

src/components/ha-navigation-picker.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import { caseInsensitiveStringCompare } from "../common/string/compare";
77
import { getConfigEntries, type ConfigEntry } from "../data/config_entries";
88
import { fetchConfig } from "../data/lovelace/config/types";
99
import { SYSTEM_PANELS } from "../data/panel";
10-
import { computeNavigationPathInfo } from "../data/compute-navigation-path-info";
10+
import {
11+
CONFIG_SUB_ROUTES,
12+
computeNavigationPathInfo,
13+
} from "../data/compute-navigation-path-info";
1114
import { findRelated, type RelatedResult } from "../data/search";
1215
import { PANEL_DASHBOARDS } from "../panels/config/lovelace/dashboards/ha-config-lovelace-dashboards";
1316
import { computeAreaPath } from "../panels/lovelace/strategies/areas/helpers/areas-strategy-helper";
@@ -335,6 +338,19 @@ export class HaNavigationPicker extends LitElement {
335338
});
336339
}
337340

341+
for (const [subPath, route] of Object.entries(CONFIG_SUB_ROUTES)) {
342+
const path = `/config/${subPath}`;
343+
const label = this.hass!.localize(route.translationKey) || subPath;
344+
otherRoutes.push({
345+
id: path,
346+
primary: label,
347+
secondary: path,
348+
icon_path: route.iconPath,
349+
sorting_label: createSortingLabel(label, path),
350+
group: "other_routes",
351+
});
352+
}
353+
338354
this._navigationGroups = {
339355
related,
340356
dashboards,

src/components/ha-selector/ha-selector-theme.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export class HaThemeSelector extends LitElement {
1414

1515
@property() public label?: string;
1616

17+
@property() public helper?: string;
18+
1719
@property({ type: Boolean, reflect: true }) public disabled = false;
1820

1921
@property({ type: Boolean }) public required = true;
@@ -24,6 +26,7 @@ export class HaThemeSelector extends LitElement {
2426
.hass=${this.hass}
2527
.value=${this.value}
2628
.label=${this.label}
29+
.helper=${this.helper}
2730
.includeDefault=${this.selector.theme?.include_default}
2831
.disabled=${this.disabled}
2932
.required=${this.required}

0 commit comments

Comments
 (0)