Compare commits

..

3 Commits

Author SHA1 Message Date
Bram Kragten
df7a36e743 Update text 2025-11-14 16:24:46 +01:00
Bram Kragten
5786fe4b8d update link 2025-11-14 16:18:33 +01:00
Bram Kragten
6fa274e4bf Add device database toggle to analytics 2025-11-14 16:10:46 +01:00
5 changed files with 112 additions and 49 deletions

View File

@@ -115,7 +115,7 @@
"home-assistant-js-websocket": "9.5.0", "home-assistant-js-websocket": "9.5.0",
"idb-keyval": "6.2.2", "idb-keyval": "6.2.2",
"intl-messageformat": "10.7.18", "intl-messageformat": "10.7.18",
"js-yaml": "4.1.1", "js-yaml": "4.1.0",
"leaflet": "1.9.4", "leaflet": "1.9.4",
"leaflet-draw": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch", "leaflet-draw": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch",
"leaflet.markercluster": "1.5.3", "leaflet.markercluster": "1.5.3",
@@ -201,7 +201,7 @@
"gulp-rename": "2.1.0", "gulp-rename": "2.1.0",
"html-minifier-terser": "7.2.0", "html-minifier-terser": "7.2.0",
"husky": "9.1.7", "husky": "9.1.7",
"jsdom": "27.2.0", "jsdom": "27.1.0",
"jszip": "3.10.1", "jszip": "3.10.1",
"lint-staged": "16.2.6", "lint-staged": "16.2.6",
"lit-analyzer": "2.0.3", "lit-analyzer": "2.0.3",

View File

@@ -5,6 +5,7 @@ export interface AnalyticsPreferences {
diagnostics?: boolean; diagnostics?: boolean;
usage?: boolean; usage?: boolean;
statistics?: boolean; statistics?: boolean;
snapshots?: boolean;
} }
export interface Analytics { export interface Analytics {

View File

@@ -1,6 +1,5 @@
import { mdiOpenInNew } from "@mdi/js";
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit"; import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
import { css, html, LitElement } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import "../../../components/ha-analytics"; import "../../../components/ha-analytics";
@@ -17,6 +16,8 @@ import {
import { haStyle } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import { documentationUrl } from "../../../util/documentation-url"; import { documentationUrl } from "../../../util/documentation-url";
import { isDevVersion } from "../../../common/config/version";
import type { HaSwitch } from "../../../components/ha-switch";
@customElement("ha-config-analytics") @customElement("ha-config-analytics")
class ConfigAnalytics extends LitElement { class ConfigAnalytics extends LitElement {
@@ -34,10 +35,22 @@ class ConfigAnalytics extends LitElement {
: undefined; : undefined;
return html` return html`
<ha-card outlined> <ha-card
outlined
.header=${this.hass.localize("ui.panel.config.analytics.header") ||
"Home Assistant analytics"}
>
<div class="card-content"> <div class="card-content">
${error ? html`<div class="error">${error}</div>` : ""} ${error ? html`<div class="error">${error}</div>` : nothing}
<p>${this.hass.localize("ui.panel.config.analytics.intro")}</p> <p>
${this.hass.localize("ui.panel.config.analytics.intro")}
<a
href=${documentationUrl(this.hass, "/integrations/analytics/")}
target="_blank"
rel="noreferrer"
>${this.hass.localize("ui.panel.config.analytics.learn_more")} </a
>.
</p>
<ha-analytics <ha-analytics
translation_key_panel="config" translation_key_panel="config"
@analytics-preferences-changed=${this._preferencesChanged} @analytics-preferences-changed=${this._preferencesChanged}
@@ -45,26 +58,50 @@ class ConfigAnalytics extends LitElement {
.analytics=${this._analyticsDetails} .analytics=${this._analyticsDetails}
></ha-analytics> ></ha-analytics>
</div> </div>
<div class="card-actions">
<ha-button @click=${this._save}>
${this.hass.localize(
"ui.panel.config.core.section.core.core_config.save_button"
)}
</ha-button>
</div>
</ha-card> </ha-card>
<div class="footer"> ${isDevVersion(this.hass.config.version)
<ha-button ? html`<ha-card
size="small" outlined
appearance="plain" .header=${this.hass.localize(
href=${documentationUrl(this.hass, "/integrations/analytics/")} "ui.panel.config.analytics.preferences.snapshots.header"
target="_blank" )}
rel="noreferrer" >
> <div class="card-content">
<ha-svg-icon slot="end" .path=${mdiOpenInNew}></ha-svg-icon> <p>
${this.hass.localize("ui.panel.config.analytics.learn_more")} ${this.hass.localize(
</ha-button> "ui.panel.config.analytics.preferences.snapshots.info"
</div> )}
<a
href=${documentationUrl(this.hass, "/device-database/")}
target="_blank"
rel="noreferrer"
>${this.hass.localize(
"ui.panel.config.analytics.preferences.snapshots.learn_more"
)} </a
>.
</p>
<ha-settings-row>
<span slot="heading" data-for="snapshots">
${this.hass.localize(
`ui.panel.config.analytics.preferences.snapshots.title`
)}
</span>
<span slot="description" data-for="snapshots">
${this.hass.localize(
`ui.panel.config.analytics.preferences.snapshots.description`
)}
</span>
<ha-switch
@change=${this._handleDeviceRowClick}
.checked=${!!this._analyticsDetails?.preferences.snapshots}
.disabled=${this._analyticsDetails === undefined}
name="snapshots"
>
</ha-switch>
</ha-settings-row>
</div>
</ha-card>`
: nothing}
`; `;
} }
@@ -96,11 +133,25 @@ class ConfigAnalytics extends LitElement {
} }
} }
private _handleDeviceRowClick(ev: Event) {
const target = ev.target as HaSwitch;
this._analyticsDetails = {
...this._analyticsDetails!,
preferences: {
...this._analyticsDetails!.preferences,
snapshots: target.checked,
},
};
this._save();
}
private _preferencesChanged(event: CustomEvent): void { private _preferencesChanged(event: CustomEvent): void {
this._analyticsDetails = { this._analyticsDetails = {
...this._analyticsDetails!, ...this._analyticsDetails!,
preferences: event.detail.preferences, preferences: event.detail.preferences,
}; };
this._save();
} }
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
@@ -127,6 +178,9 @@ class ConfigAnalytics extends LitElement {
padding: 32px 0 16px; padding: 32px 0 16px;
text-align: center; text-align: center;
} }
ha-card:not(:first-of-type) {
margin-top: 24px;
}
ha-button[size="small"] ha-svg-icon { ha-button[size="small"] ha-svg-icon {
--mdc-icon-size: 16px; --mdc-icon-size: 16px;

View File

@@ -6760,6 +6760,7 @@
}, },
"analytics": { "analytics": {
"caption": "Analytics", "caption": "Analytics",
"header": "Home Assistant analytics",
"description": "Learn how to share data to improve Home Assistant", "description": "Learn how to share data to improve Home Assistant",
"preferences": { "preferences": {
"base": { "base": {
@@ -6777,10 +6778,17 @@
"diagnostics": { "diagnostics": {
"title": "Diagnostics", "title": "Diagnostics",
"description": "Share crash reports when unexpected errors occur." "description": "Share crash reports when unexpected errors occur."
},
"snapshots": {
"title": "Devices",
"description": "Generic information of your devices.",
"header": "Device analytics",
"info": "Anonymously share data about your devices to help build the Open Home Foundations device database. This free, open source resource helps users find useful information about smart home devices. Only device-specific details (like model or manufacturer) are shared — never personally identifying information (like the names you assign).",
"learn_more": "Learn more about the device database and how we process your data"
} }
}, },
"need_base_enabled": "You need to enable basic analytics for this option to be available", "need_base_enabled": "You need to enable basic analytics for this option to be available",
"learn_more": "How we process your data", "learn_more": "Learn how we process your data",
"intro": "Share anonymized information from your installation to help make Home Assistant better and help us convince manufacturers to add local control and privacy-focused features.", "intro": "Share anonymized information from your installation to help make Home Assistant better and help us convince manufacturers to add local control and privacy-focused features.",
"download_device_info": "Preview device analytics" "download_device_info": "Preview device analytics"
}, },

View File

@@ -5,10 +5,10 @@ __metadata:
version: 8 version: 8
cacheKey: 10 cacheKey: 10
"@acemir/cssom@npm:^0.9.23": "@acemir/cssom@npm:^0.9.19":
version: 0.9.23 version: 0.9.19
resolution: "@acemir/cssom@npm:0.9.23" resolution: "@acemir/cssom@npm:0.9.19"
checksum: 10/752294359ddf691f402bf871f347c1d5ea8532ead5e197cf60eeb7ab25bdd6f6e98fc7fad74042f2e423bb45fe7e4a049db645e01fa0781a0ed4ea2cec911047 checksum: 10/1c7066c002c170d5a775533cb83ff7eb7415a8cc514995325c3d135803fa4a3feffccf21ba0b520b804cdc5fccef8476d7ef83d0e4876dd7bd007ab64d535588
languageName: node languageName: node
linkType: hard linkType: hard
@@ -38,7 +38,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@asamuzakjp/dom-selector@npm:^6.7.4": "@asamuzakjp/dom-selector@npm:^6.7.3":
version: 6.7.4 version: 6.7.4
resolution: "@asamuzakjp/dom-selector@npm:6.7.4" resolution: "@asamuzakjp/dom-selector@npm:6.7.4"
dependencies: dependencies:
@@ -6975,14 +6975,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cssstyle@npm:^5.3.3": "cssstyle@npm:^5.3.2":
version: 5.3.3 version: 5.3.2
resolution: "cssstyle@npm:5.3.3" resolution: "cssstyle@npm:5.3.2"
dependencies: dependencies:
"@asamuzakjp/css-color": "npm:^4.0.3" "@asamuzakjp/css-color": "npm:^4.0.3"
"@csstools/css-syntax-patches-for-csstree": "npm:^1.0.14" "@csstools/css-syntax-patches-for-csstree": "npm:^1.0.14"
css-tree: "npm:^3.1.0" css-tree: "npm:^3.1.0"
checksum: 10/8c6133761395f03d50e74ff4c05473b4835b79013efed3f4b79dc452d94a7122082887d89c3c1164bba0e8919be209b75e4f4706197c086fc9f4b50182ab03d6 checksum: 10/2f628254c738556c6394dbe705d7cadd8a8867767feb00bc8a4980a43b405fc891f72687cc2f04a8b15185009e9713f0f96bc9311e7781d848b0d145056b9f1f
languageName: node languageName: node
linkType: hard linkType: hard
@@ -9337,8 +9337,8 @@ __metadata:
husky: "npm:9.1.7" husky: "npm:9.1.7"
idb-keyval: "npm:6.2.2" idb-keyval: "npm:6.2.2"
intl-messageformat: "npm:10.7.18" intl-messageformat: "npm:10.7.18"
js-yaml: "npm:4.1.1" js-yaml: "npm:4.1.0"
jsdom: "npm:27.2.0" jsdom: "npm:27.1.0"
jszip: "npm:3.10.1" jszip: "npm:3.10.1"
leaflet: "npm:1.9.4" leaflet: "npm:1.9.4"
leaflet-draw: "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch" leaflet-draw: "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch"
@@ -10407,24 +10407,24 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"js-yaml@npm:4.1.1, js-yaml@npm:^4.1.0": "js-yaml@npm:4.1.0, js-yaml@npm:^4.1.0":
version: 4.1.1 version: 4.1.0
resolution: "js-yaml@npm:4.1.1" resolution: "js-yaml@npm:4.1.0"
dependencies: dependencies:
argparse: "npm:^2.0.1" argparse: "npm:^2.0.1"
bin: bin:
js-yaml: bin/js-yaml.js js-yaml: bin/js-yaml.js
checksum: 10/a52d0519f0f4ef5b4adc1cde466cb54c50d56e2b4a983b9d5c9c0f2f99462047007a6274d7e95617a21d3c91fde3ee6115536ed70991cd645ba8521058b78f77 checksum: 10/c138a34a3fd0d08ebaf71273ad4465569a483b8a639e0b118ff65698d257c2791d3199e3f303631f2cb98213fa7b5f5d6a4621fd0fff819421b990d30d967140
languageName: node languageName: node
linkType: hard linkType: hard
"jsdom@npm:27.2.0": "jsdom@npm:27.1.0":
version: 27.2.0 version: 27.1.0
resolution: "jsdom@npm:27.2.0" resolution: "jsdom@npm:27.1.0"
dependencies: dependencies:
"@acemir/cssom": "npm:^0.9.23" "@acemir/cssom": "npm:^0.9.19"
"@asamuzakjp/dom-selector": "npm:^6.7.4" "@asamuzakjp/dom-selector": "npm:^6.7.3"
cssstyle: "npm:^5.3.3" cssstyle: "npm:^5.3.2"
data-urls: "npm:^6.0.0" data-urls: "npm:^6.0.0"
decimal.js: "npm:^10.6.0" decimal.js: "npm:^10.6.0"
html-encoding-sniffer: "npm:^4.0.0" html-encoding-sniffer: "npm:^4.0.0"
@@ -10447,7 +10447,7 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
canvas: canvas:
optional: true optional: true
checksum: 10/78458e0230fd18ceef1e8753ab44eadf436654540a3d1dc5068f49b87c2bd1752b8fff25c9e1f30ee406ae3e80cc3f81668f778b8220a7bf9386a0a826dee088 checksum: 10/9e2bd9824abed594da64fc58f1bdb817c7f82ba3025cef4817e6709807f886ac71b7b6a0f4f69ba604e9137bbcd6b7246b98dec53bde95500f5ac4b39a8ebb00
languageName: node languageName: node
linkType: hard linkType: hard