Compare commits

..

1 Commits

Author SHA1 Message Date
Ludeeus 2a4cebf724 Block update on error and not running state 2021-03-01 23:12:13 +00:00
99 changed files with 1057 additions and 3761 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ on:
branches:
- dev
paths:
- src/translations/en.json
- translations/en.json
env:
NODE_VERSION: 12
-5
View File
@@ -85,11 +85,6 @@ gulp.task("copy-translations-app", async () => {
copyTranslations(staticDir);
});
gulp.task("copy-translations-supervisor", async () => {
const staticDir = paths.hassio_output_static;
copyTranslations(staticDir);
});
gulp.task("copy-static-app", async () => {
const staticDir = paths.app_output_static;
// Basic static files
-6
View File
@@ -10,8 +10,6 @@ require("./gen-icons-json.js");
require("./webpack.js");
require("./compress.js");
require("./rollup.js");
require("./gather-static.js");
require("./translations.js");
gulp.task(
"develop-hassio",
@@ -22,8 +20,6 @@ gulp.task(
"clean-hassio",
"gen-icons-json",
"gen-index-hassio-dev",
"build-supervisor-translations",
"copy-translations-supervisor",
env.useRollup() ? "rollup-watch-hassio" : "webpack-watch-hassio"
)
);
@@ -36,8 +32,6 @@ gulp.task(
},
"clean-hassio",
"gen-icons-json",
"build-supervisor-translations",
"copy-translations-supervisor",
env.useRollup() ? "rollup-prod-hassio" : "webpack-prod-hassio",
"gen-index-hassio-prod",
...// Don't compress running tests
+36 -72
View File
@@ -266,7 +266,6 @@ gulp.task(taskName, function () {
TRANSLATION_FRAGMENTS.forEach((fragment) => {
delete data.ui.panel[fragment];
});
delete data.supervisor;
return data;
})
)
@@ -343,62 +342,6 @@ gulp.task(
}
);
gulp.task("build-translation-fragment-supervisor", function () {
return gulp
.src(fullDir + "/*.json")
.pipe(transform((data) => data.supervisor))
.pipe(gulp.dest(workDir + "/supervisor"));
});
gulp.task("build-translation-flatten-supervisor", function () {
return gulp
.src(workDir + "/supervisor/*.json")
.pipe(
transform(function (data) {
// Polymer.AppLocalizeBehavior requires flattened json
return flatten(data);
})
)
.pipe(gulp.dest(outDir));
});
gulp.task("build-translation-write-metadata", function writeMetadata() {
return gulp
.src(
[
path.join(paths.translations_src, "translationMetadata.json"),
workDir + "/testMetadata.json",
workDir + "/translationFingerprints.json",
],
{ allowEmpty: true }
)
.pipe(merge({}))
.pipe(
transform(function (data) {
const newData = {};
Object.entries(data).forEach(([key, value]) => {
// Filter out translations without native name.
if (value.nativeName) {
newData[key] = value;
} else {
console.warn(
`Skipping language ${key}. Native name was not translated.`
);
}
});
return newData;
})
)
.pipe(
transform((data) => ({
fragments: TRANSLATION_FRAGMENTS,
translations: data,
}))
)
.pipe(rename("translationMetadata.json"))
.pipe(gulp.dest(workDir));
});
gulp.task(
"build-translations",
gulp.series(
@@ -410,20 +353,41 @@ gulp.task(
gulp.parallel(...splitTasks),
"build-flattened-translations",
"build-translation-fingerprints",
"build-translation-write-metadata"
)
);
gulp.task(
"build-supervisor-translations",
gulp.series(
"clean-translations",
"ensure-translations-build-dir",
"build-master-translation",
"build-merged-translations",
"build-translation-fragment-supervisor",
"build-translation-flatten-supervisor",
"build-translation-fingerprints",
"build-translation-write-metadata"
function writeMetadata() {
return gulp
.src(
[
path.join(paths.translations_src, "translationMetadata.json"),
workDir + "/testMetadata.json",
workDir + "/translationFingerprints.json",
],
{ allowEmpty: true }
)
.pipe(merge({}))
.pipe(
transform(function (data) {
const newData = {};
Object.entries(data).forEach(([key, value]) => {
// Filter out translations without native name.
if (value.nativeName) {
newData[key] = value;
} else {
console.warn(
`Skipping language ${key}. Native name was not translated.`
);
}
});
return newData;
})
)
.pipe(
transform((data) => ({
fragments: TRANSLATION_FRAGMENTS,
translations: data,
}))
)
.pipe(rename("translationMetadata.json"))
.pipe(gulp.dest(workDir));
}
)
);
+1 -6
View File
@@ -137,12 +137,7 @@ gulp.task("webpack-watch-hassio", () => {
isProdBuild: false,
latestBuild: true,
})
).watch({ ignored: /build-translations/ }, doneHandler());
gulp.watch(
path.join(paths.translations_src, "en.json"),
gulp.series("build-supervisor-translations", "copy-translations-supervisor")
);
).watch({}, doneHandler());
});
gulp.task("webpack-prod-hassio", () =>
-1
View File
@@ -34,7 +34,6 @@ module.exports = {
hassio_dir: path.resolve(__dirname, "../hassio"),
hassio_output_root: path.resolve(__dirname, "../hassio/build"),
hassio_output_static: path.resolve(__dirname, "../hassio/build/static"),
hassio_output_latest: path.resolve(
__dirname,
"../hassio/build/frontend_latest"
@@ -15,7 +15,6 @@ import {
HassioAddonInfo,
HassioAddonRepository,
} from "../../../src/data/hassio/addon";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import { HomeAssistant } from "../../../src/types";
import "../components/hassio-card-content";
import { filterAndSort } from "../components/hassio-filter-addons";
@@ -24,8 +23,6 @@ import { hassioStyle } from "../resources/hassio-style";
class HassioAddonRepositoryEl extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public repo!: HassioAddonRepository;
@property({ attribute: false }) public addons!: HassioAddonInfo[];
@@ -57,11 +54,7 @@ class HassioAddonRepositoryEl extends LitElement {
return html`
<div class="content">
<p class="description">
${this.supervisor.localize(
"store.no_results_found",
"repository",
repo.name
)}
No results found in "${repo.name}."
</p>
</div>
`;
@@ -90,13 +83,11 @@ class HassioAddonRepositoryEl extends LitElement {
: mdiPuzzle}
.iconTitle=${addon.installed
? addon.update_available
? this.supervisor.localize(
"common.new_version_available"
)
: this.supervisor.localize("addon.installed")
? "New version available"
: "Add-on is installed"
: addon.available
? this.supervisor.localize("addon.not_installed")
: this.supervisor.localize("addon.not_available")}
? "Add-on is not installed"
: "Add-on is not available on your system"}
.iconClass=${addon.installed
? addon.update_available
? "update"
+11 -13
View File
@@ -77,16 +77,13 @@ class HassioAddonStore extends LitElement {
return html`
<hass-tabs-subpage
.hass=${this.hass}
.localizeFunc=${this.supervisor.localize}
.narrow=${this.narrow}
.route=${this.route}
.tabs=${supervisorTabs}
hassio
main-page
supervisor
.tabs=${supervisorTabs}
>
<span slot="header">
${this.supervisor.localize("panel.store")}
</span>
<span slot="header">Add-on Store</span>
<ha-button-menu
corner="BOTTOM_START"
slot="toolbar-icon"
@@ -96,15 +93,15 @@ class HassioAddonStore extends LitElement {
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item>
${this.supervisor.localize("store.repositories")}
Repositories
</mwc-list-item>
<mwc-list-item>
${this.supervisor.localize("common.reload")}
Reload
</mwc-list-item>
${this.hass.userData?.showAdvanced &&
atLeastVersion(this.hass.config.version, 0, 117)
? html`<mwc-list-item>
${this.supervisor.localize("store.registries")}
Registries
</mwc-list-item>`
: ""}
</ha-button-menu>
@@ -125,9 +122,11 @@ class HassioAddonStore extends LitElement {
${!this.hass.userData?.showAdvanced
? html`
<div class="advanced">
Missing add-ons? Enable advanced mode on
<a href="/profile" target="_top">
${this.supervisor.localize("store.missing_addons")}
your profile page
</a>
.
</div>
`
: ""}
@@ -159,7 +158,6 @@ class HassioAddonStore extends LitElement {
.repo=${repo}
.addons=${filteredAddons}
.filter=${filter!}
.supervisor=${this.supervisor}
></hassio-addon-repository>
`
: html``;
@@ -189,13 +187,13 @@ class HassioAddonStore extends LitElement {
private async _manageRepositories() {
showRepositoriesDialog(this, {
supervisor: this.supervisor,
repos: this.supervisor.addon.repositories,
loadData: () => this._loadData(),
});
}
private async _manageRegistries() {
showRegistriesDialog(this, { supervisor: this.supervisor });
showRegistriesDialog(this);
}
private async _loadData() {
@@ -25,7 +25,6 @@ import {
fetchHassioHardwareAudio,
HassioHardwareAudioDevice,
} from "../../../../src/data/hassio/hardware";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
@@ -35,8 +34,6 @@ import { hassioStyle } from "../../resources/hassio-style";
class HassioAddonAudio extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@@ -51,16 +48,12 @@ class HassioAddonAudio extends LitElement {
protected render(): TemplateResult {
return html`
<ha-card
.header=${this.supervisor.localize("addon.configuration.audio.header")}
>
<ha-card header="Audio">
<div class="card-content">
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
<paper-dropdown-menu
.label=${this.supervisor.localize(
"addon.configuration.audio.input"
)}
label="Input"
@iron-select=${this._setInputDevice}
>
<paper-listbox
@@ -71,17 +64,15 @@ class HassioAddonAudio extends LitElement {
${this._inputDevices &&
this._inputDevices.map((item) => {
return html`
<paper-item device=${item.device || ""}>
${item.name}
</paper-item>
<paper-item device=${item.device || ""}
>${item.name}</paper-item
>
`;
})}
</paper-listbox>
</paper-dropdown-menu>
<paper-dropdown-menu
.label=${this.supervisor.localize(
"addon.configuration.audio.output"
)}
label="Output"
@iron-select=${this._setOutputDevice}
>
<paper-listbox
@@ -102,7 +93,7 @@ class HassioAddonAudio extends LitElement {
</div>
<div class="card-actions">
<ha-progress-button @click=${this._saveSettings}>
${this.supervisor.localize("common.save")}
Save
</ha-progress-button>
</div>
</ha-card>
@@ -161,7 +152,7 @@ class HassioAddonAudio extends LitElement {
const noDevice: HassioHardwareAudioDevice = {
device: "default",
name: this.supervisor.localize("addon.configuration.audio.default"),
name: "Default",
};
try {
@@ -198,7 +189,7 @@ class HassioAddonAudio extends LitElement {
try {
await setHassioAddonOption(this.hass, this.addon.slug, data);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
await suggestAddonRestart(this, this.hass, this.addon);
}
} catch {
this._error = "Failed to set addon audio device";
@@ -9,7 +9,6 @@ import {
} from "lit-element";
import "../../../../src/components/ha-circular-progress";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
@@ -21,8 +20,6 @@ import "./hassio-addon-network";
class HassioAddonConfigDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon?: HassioAddonDetails;
protected render(): TemplateResult {
@@ -42,7 +39,6 @@ class HassioAddonConfigDashboard extends LitElement {
<hassio-addon-config
.hass=${this.hass}
.addon=${this.addon}
.supervisor=${this.supervisor}
></hassio-addon-config>
`
: ""}
@@ -51,7 +47,6 @@ class HassioAddonConfigDashboard extends LitElement {
<hassio-addon-network
.hass=${this.hass}
.addon=${this.addon}
.supervisor=${this.supervisor}
></hassio-addon-network>
`
: ""}
@@ -60,12 +55,11 @@ class HassioAddonConfigDashboard extends LitElement {
<hassio-addon-audio
.hass=${this.hass}
.addon=${this.addon}
.supervisor=${this.supervisor}
></hassio-addon-audio>
`
: ""}
`
: this.supervisor.localize("addon.configuration.no_configuration")}
: "This add-on does not expose configuration for you to mess with.... 👋"}
</div>
`;
}
@@ -32,7 +32,6 @@ import {
setHassioAddonOption,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { showConfirmationDialog } from "../../../../src/dialogs/generic/show-dialog-box";
import { haStyle } from "../../../../src/resources/styles";
import type { HomeAssistant } from "../../../../src/types";
@@ -47,8 +46,6 @@ class HassioAddonConfig extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ type: Boolean }) private _configHasChanged = false;
@property({ type: Boolean }) private _valid = true;
@@ -65,15 +62,6 @@ class HassioAddonConfig extends LitElement {
@query("ha-yaml-editor") private _editor?: HaYamlEditor;
public computeLabel = (entry: HaFormSchema): string => {
return (
this.addon.translations[this.hass.language]?.configuration?.[entry.name]
?.name ||
this.addon.translations.en?.configuration?.[entry.name].name ||
entry.name
);
};
private _filteredShchema = memoizeOne(
(options: Record<string, unknown>, schema: HaFormSchema[]) => {
return schema.filter((entry) => entry.name in options || entry.required);
@@ -93,25 +81,17 @@ class HassioAddonConfig extends LitElement {
<h1>${this.addon.name}</h1>
<ha-card>
<div class="header">
<h2>
${this.supervisor.localize("addon.configuration.options.header")}
</h2>
<h2>Configuration</h2>
<div class="card-menu">
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
<mwc-icon-button slot="trigger">
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item .disabled=${!this._canShowSchema}>
${this._yamlMode
? this.supervisor.localize(
"addon.configuration.options.edit_in_ui"
)
: this.supervisor.localize(
"addon.configuration.options.edit_in_yaml"
)}
${this._yamlMode ? "Edit in UI" : "Edit in YAML"}
</mwc-list-item>
<mwc-list-item class="warning">
${this.supervisor.localize("common.reset_defaults")}
Reset to defaults
</mwc-list-item>
</ha-button-menu>
</div>
@@ -122,7 +102,6 @@ class HassioAddonConfig extends LitElement {
? html`<ha-form
.data=${this._options!}
@value-changed=${this._configChanged}
.computeLabel=${this.computeLabel}
.schema=${this._showOptional
? this.addon.schema!
: this._filteredShchema(
@@ -138,20 +117,12 @@ class HassioAddonConfig extends LitElement {
(this._canShowSchema && this.addon.schema) ||
this._valid
? ""
: html`
<div class="errors">
${this.supervisor.localize(
"addon.configuration.options.invalid_yaml"
)}
</div>
`}
: html` <div class="errors">Invalid YAML</div> `}
</div>
${hasHiddenOptions
? html`<ha-formfield
class="show-additional"
.label=${this.supervisor.localize(
"addon.configuration.options.show_unused_optional"
)}
label="Show unused optional configuration options"
>
<ha-switch
@change=${this._toggleOptional}
@@ -165,7 +136,7 @@ class HassioAddonConfig extends LitElement {
@click=${this._saveTapped}
.disabled=${!this._configHasChanged || !this._valid}
>
Save ${this.supervisor.localize("common.save")}
Save
</ha-progress-button>
</div>
</ha-card>
@@ -230,10 +201,10 @@ class HassioAddonConfig extends LitElement {
button.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize("confirm.reset_options.title"),
text: this.supervisor.localize("confirm.reset_options.text"),
confirmText: this.supervisor.localize("common.reset_options"),
dismissText: this.supervisor.localize("common.cancel"),
title: this.addon.name,
text: "Are you sure you want to reset all your options?",
confirmText: "reset options",
dismissText: "no",
});
if (!confirmed) {
@@ -255,11 +226,9 @@ class HassioAddonConfig extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
this._error = this.supervisor.localize(
"addon.common.update_available",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to reset addon configuration, ${extractApiErrorMessage(
err
)}`;
}
button.progress = false;
}
@@ -283,14 +252,12 @@ class HassioAddonConfig extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
await suggestAddonRestart(this, this.hass, this.addon);
}
} catch (err) {
this._error = this.supervisor.localize(
"addon.configuration.options.failed_to_save",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to save addon configuration, ${extractApiErrorMessage(
err
)}`;
}
button.progress = false;
}
@@ -19,7 +19,6 @@ import {
setHassioAddonOption,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
@@ -39,8 +38,6 @@ interface NetworkItemInput extends PaperInputElement {
class HassioAddonNetwork extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@@ -58,30 +55,16 @@ class HassioAddonNetwork extends LitElement {
}
return html`
<ha-card
.header=${this.supervisor.localize(
"addon.configuration.network.header"
)}
>
<ha-card header="Network">
<div class="card-content">
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
<table>
<tbody>
<tr>
<th>
${this.supervisor.localize(
"addon.configuration.network.container"
)}
</th>
<th>
${this.supervisor.localize(
"addon.configuration.network.host"
)}
</th>
<th>
${this.supervisor.localize("common.description")}
</th>
<th>Container</th>
<th>Host</th>
<th>Description</th>
</tr>
${this._config!.map((item) => {
return html`
@@ -90,15 +73,13 @@ class HassioAddonNetwork extends LitElement {
<td>
<paper-input
@value-changed=${this._configChanged}
placeholder="${this.supervisor.localize(
"addon.configuration.network.disabled"
)}"
placeholder="disabled"
.value=${item.host ? String(item.host) : ""}
.container=${item.container}
no-label-float
></paper-input>
</td>
<td>${this._computeDescription(item)}</td>
<td>${item.description}</td>
</tr>
`;
})}
@@ -107,10 +88,10 @@ class HassioAddonNetwork extends LitElement {
</div>
<div class="card-actions">
<ha-progress-button class="warning" @click=${this._resetTapped}>
${this.supervisor.localize("common.reset_defaults")}
Reset to defaults
</ha-progress-button>
<ha-progress-button @click=${this._saveTapped}>
${this.supervisor.localize("common.save")}
Save
</ha-progress-button>
</div>
</ha-card>
@@ -124,15 +105,6 @@ class HassioAddonNetwork extends LitElement {
}
}
private _computeDescription = (item: NetworkItem): string => {
return (
this.addon.translations[this.hass.language]?.network?.[item.container]
?.description ||
this.addon.translations.en?.network?.[item.container]?.description ||
item.description
);
};
private _setNetworkConfig(): void {
const network = this.addon.network || {};
const description = this.addon.network_description || {};
@@ -175,14 +147,12 @@ class HassioAddonNetwork extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
await suggestAddonRestart(this, this.hass, this.addon);
}
} catch (err) {
this._error = this.supervisor.localize(
"addon.failed_to_reset",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to set addon network configuration, ${extractApiErrorMessage(
err
)}`;
}
button.progress = false;
@@ -211,14 +181,12 @@ class HassioAddonNetwork extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
await suggestAddonRestart(this, this.hass, this.addon);
}
} catch (err) {
this._error = this.supervisor.localize(
"addon.failed_to_save",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to set addon network configuration, ${extractApiErrorMessage(
err
)}`;
}
button.progress = false;
}
@@ -1,4 +1,3 @@
import "../../../../src/components/ha-card";
import {
css,
CSSResult,
@@ -20,14 +19,11 @@ import "../../../../src/layouts/hass-loading-screen";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
@customElement("hassio-addon-documentation-tab")
class HassioAddonDocumentationDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon?: HassioAddonDetails;
@internalProperty() private _error?: string;
@@ -85,11 +81,9 @@ class HassioAddonDocumentationDashboard extends LitElement {
this.addon!.slug
);
} catch (err) {
this._error = this.supervisor.localize(
"addon.documentation.get_logs",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to get addon documentation, ${extractApiErrorMessage(
err
)}`;
}
}
}
@@ -79,7 +79,7 @@ class HassioAddonDashboard extends LitElement {
const addonTabs: PageNavigation[] = [
{
translationKey: "addon.panel.info",
name: "Info",
path: `/hassio/addon/${this.addon.slug}/info`,
iconPath: mdiInformationVariant,
},
@@ -87,7 +87,7 @@ class HassioAddonDashboard extends LitElement {
if (this.addon.documentation) {
addonTabs.push({
translationKey: "addon.panel.documentation",
name: "Documentation",
path: `/hassio/addon/${this.addon.slug}/documentation`,
iconPath: mdiFileDocument,
});
@@ -96,12 +96,12 @@ class HassioAddonDashboard extends LitElement {
if (this.addon.version) {
addonTabs.push(
{
translationKey: "addon.panel.configuration",
name: "Configuration",
path: `/hassio/addon/${this.addon.slug}/config`,
iconPath: mdiCogs,
},
{
translationKey: "addon.panel.log",
name: "Log",
path: `/hassio/addon/${this.addon.slug}/logs`,
iconPath: mdiMathLog,
}
@@ -113,12 +113,11 @@ class HassioAddonDashboard extends LitElement {
return html`
<hass-tabs-subpage
.hass=${this.hass}
.localizeFunc=${this.supervisor.localize}
.narrow=${this.narrow}
.backPath=${this.addon.version ? "/hassio/dashboard" : "/hassio/store"}
.route=${route}
hassio
.tabs=${addonTabs}
supervisor
>
<span slot="header">${this.addon.name}</span>
<hassio-addon-router
+159 -235
View File
@@ -50,7 +50,6 @@ import {
startHassioAddon,
stopHassioAddon,
uninstallHassioAddon,
updateHassioAddon,
validateHassioAddonOption,
} from "../../../../src/data/hassio/addon";
import {
@@ -69,8 +68,8 @@ import { HomeAssistant } from "../../../../src/types";
import { bytesToString } from "../../../../src/util/bytes-to-string";
import "../../components/hassio-card-content";
import "../../components/supervisor-metric";
import { showDialogSupervisorAddonUpdate } from "../../dialogs/addon/show-dialog-addon-update";
import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown";
import { showDialogSupervisorUpdate } from "../../dialogs/update/show-dialog-update";
import { hassioStyle } from "../../resources/hassio-style";
import { addonArchIsSupported } from "../../util/addon";
@@ -80,6 +79,63 @@ const STAGE_ICON = {
deprecated: mdiExclamationThick,
};
const PERMIS_DESC = {
stage: {
title: "Add-on Stage",
description: `Add-ons can have one of three stages:\n\n<ha-svg-icon path="${STAGE_ICON.stable}"></ha-svg-icon> **Stable**: These are add-ons ready to be used in production.\n\n<ha-svg-icon path="${STAGE_ICON.experimental}"></ha-svg-icon> **Experimental**: These may contain bugs, and may be unfinished.\n\n<ha-svg-icon path="${STAGE_ICON.deprecated}"></ha-svg-icon> **Deprecated**: These add-ons will no longer receive any updates.`,
},
rating: {
title: "Add-on Security Rating",
description:
"Home Assistant provides a security rating to each of the add-ons, which indicates the risks involved when using this add-on. The more access an add-on requires on your system, the lower the score, thus raising the possible security risks.\n\nA score is on a scale from 1 to 6. Where 1 is the lowest score (considered the most insecure and highest risk) and a score of 6 is the highest score (considered the most secure and lowest risk).",
},
host_network: {
title: "Host Network",
description:
"Add-ons usually run in their own isolated network layer, which prevents them from accessing the network of the host operating system. In some cases, this network isolation can limit add-ons in providing their services and therefore, the isolation can be lifted by the add-on author, giving the add-on full access to the network capabilities of the host machine. This gives the add-on more networking capabilities but lowers the security, hence, the security rating of the add-on will be lowered when this option is used by the add-on.",
},
homeassistant_api: {
title: "Home Assistant API Access",
description:
"This add-on is allowed to access your running Home Assistant instance directly via the Home Assistant API. This mode handles authentication for the add-on as well, which enables an add-on to interact with Home Assistant without the need for additional authentication tokens.",
},
full_access: {
title: "Full Hardware Access",
description:
"This add-on is given full access to the hardware of your system, by request of the add-on author. Access is comparable to the privileged mode in Docker. Since this opens up possible security risks, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on.",
},
hassio_api: {
title: "Supervisor API Access",
description:
"The add-on was given access to the Supervisor API, by request of the add-on author. By default, the add-on can access general version information of your system. When the add-on requests 'manager' or 'admin' level access to the API, it will gain access to control multiple parts of your Home Assistant system. This permission is indicated by this badge and will impact the security score of the addon negatively.",
},
docker_api: {
title: "Full Docker Access",
description:
"The add-on author has requested the add-on to have management access to the Docker instance running on your system. This mode gives the add-on full access and control to your entire Home Assistant system, which adds security risks, and could damage your system when misused. Therefore, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on.",
},
host_pid: {
title: "Host Processes Namespace",
description:
"Usually, the processes the add-on runs, are isolated from all other system processes. The add-on author has requested the add-on to have access to the system processes running on the host system instance, and allow the add-on to spawn processes on the host system as well. This mode gives the add-on full access and control to your entire Home Assistant system, which adds security risks, and could damage your system when misused. Therefore, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on.",
},
apparmor: {
title: "AppArmor",
description:
"AppArmor ('Application Armor') is a Linux kernel security module that restricts add-ons capabilities like network access, raw socket access, and permission to read, write, or execute specific files.\n\nAdd-on authors can provide their security profiles, optimized for the add-on, or request it to be disabled. If AppArmor is disabled, it will raise security risks and therefore, has a negative impact on the security score of the add-on.",
},
auth_api: {
title: "Home Assistant Authentication",
description:
"An add-on can authenticate users against Home Assistant, allowing add-ons to give users the possibility to log into applications running inside add-ons, using their Home Assistant username/password. This badge indicates if the add-on author requests this capability.",
},
ingress: {
title: "Ingress",
description:
"This add-on is using Ingress to embed its interface securely into Home Assistant.",
},
};
@customElement("hassio-addon-info")
class HassioAddonInfo extends LitElement {
@property({ type: Boolean }) public narrow!: boolean;
@@ -106,11 +162,11 @@ class HassioAddonInfo extends LitElement {
: undefined;
const metrics = [
{
description: this.supervisor.localize("addon.dashboard.cpu_usage"),
description: "Add-on CPU Usage",
value: this._metrics?.cpu_percent,
},
{
description: this.supervisor.localize("addon.dashboard.ram_usage"),
description: "Add-on RAM Usage",
value: this._metrics?.memory_percent,
tooltip: `${bytesToString(this._metrics?.memory_usage)}/${bytesToString(
this._metrics?.memory_limit
@@ -120,28 +176,14 @@ class HassioAddonInfo extends LitElement {
return html`
${this.addon.update_available
? html`
<ha-card
.header="${this.supervisor.localize(
"common.update_available",
"count",
1
)}🎉"
>
<ha-card header="Update available! 🎉">
<div class="card-content">
<hassio-card-content
.hass=${this.hass}
.title="${this.supervisor.localize(
"addon.dashboard.new_update_available",
"name",
this.addon.name,
"version",
this.addon.version_latest
)}"
.description="${this.supervisor.localize(
"common.running_version",
"version",
this.addon.version
)}"
.title="${this.addon.name} ${this.addon
.version_latest} is available"
.description="You are currently running version ${this.addon
.version}"
icon=${mdiArrowUpBoldCircle}
iconClass="update"
></hassio-card-content>
@@ -152,32 +194,29 @@ class HassioAddonInfo extends LitElement {
)
? html`
<p class="warning">
${this.supervisor.localize(
"addon.dashboard.not_available_arch"
)}
This add-on is not compatible with the processor of
your device or the operating system you have installed
on your device.
</p>
`
: html`
<p class="warning">
${this.supervisor.localize(
"addon.dashboard.not_available_arch",
"core_version_installed",
this.supervisor.core.version,
"core_version_needed",
addonStoreInfo.homeassistant
)}
You are running Home Assistant
${this.supervisor.core.version}, to update to this
version of the add-on you need at least version
${addonStoreInfo.homeassistant} of Home Assistant
</p>
`
: ""}
</div>
<div class="card-actions">
<mwc-button @click=${this._updateClicked}>
${this.supervisor.localize("common.update")}
Update
</mwc-button>
${this.addon.changelog
? html`
<mwc-button @click=${this._openChangelog}>
${this.supervisor.localize("addon.dashboard.changelog")}
Changelog
</mwc-button>
`
: ""}
@@ -188,19 +227,12 @@ class HassioAddonInfo extends LitElement {
${!this.addon.protected
? html`
<ha-card class="warning">
<h1 class="card-header">${this.supervisor.localize(
"addon.dashboard.protection_mode.title"
)}
</h1>
<h1 class="card-header">Warning: Protection mode is disabled!</h1>
<div class="card-content">
${this.supervisor.localize("addon.dashboard.protection_mode.content")}
Protection mode on this add-on is disabled! This gives the add-on full access to the entire system, which adds security risks, and could damage your system when used incorrectly. Only disable the protection mode if you know, need AND trust the source of this add-on.
</div>
<div class="card-actions protection-enable">
<mwc-button @click=${this._protectionToggled}>
${this.supervisor.localize(
"addon.dashboard.protection_mode.enable"
)}
</mwc-button>
<mwc-button @click=${this._protectionToggled}>Enable Protection mode</mwc-button>
</div>
</div>
</ha-card>
@@ -217,18 +249,14 @@ class HassioAddonInfo extends LitElement {
${this._computeIsRunning
? html`
<ha-svg-icon
.title=${this.supervisor.localize(
"dashboard.addon_running"
)}
title="Add-on is running"
class="running"
.path=${mdiCircle}
></ha-svg-icon>
`
: html`
<ha-svg-icon
.title=${this.supervisor.localize(
"dashboard.addon_stopped"
)}
title="Add-on is stopped"
class="stopped"
.path=${mdiCircle}
></ha-svg-icon>
@@ -242,29 +270,21 @@ class HassioAddonInfo extends LitElement {
? html`
Current version: ${this.addon.version}
<div class="changelog" @click=${this._openChangelog}>
(<span class="changelog-link">
${this.supervisor.localize("addon.dashboard.changelog")} </span
>)
(<span class="changelog-link">changelog</span>)
</div>
`
: html`<span class="changelog-link" @click=${this._openChangelog}>
${this.supervisor.localize("addon.dashboard.changelog")}
</span>`}
: html`<span class="changelog-link" @click=${this._openChangelog}
>Changelog</span
>`}
</div>
<div class="description light-color">
${this.addon.description}.<br />
${this.supervisor.localize(
"addon.dashboard.visit_addon_page",
"name",
html`<a
href="${this.addon.url!}"
target="_blank"
rel="noreferrer"
>
${this.addon.name}
</a>`
)}
Visit
<a href="${this.addon.url!}" target="_blank" rel="noreferrer">
${this.addon.name} page</a
>
for details.
</div>
<div class="addon-container">
<div>
@@ -285,9 +305,7 @@ class HassioAddonInfo extends LitElement {
})}
@click=${this._showMoreInfo}
id="stage"
.label=${this.supervisor.localize(
"addon.dashboard.capability.label.stage"
)}
label="stage"
description=""
>
<ha-svg-icon
@@ -313,9 +331,7 @@ class HassioAddonInfo extends LitElement {
<ha-label-badge
@click=${this._showMoreInfo}
id="host_network"
.label=${this.supervisor.localize(
"addon.dashboard.capability.label.host"
)}
label="host"
description=""
>
<ha-svg-icon .path=${mdiNetwork}></ha-svg-icon>
@@ -327,9 +343,7 @@ class HassioAddonInfo extends LitElement {
<ha-label-badge
@click=${this._showMoreInfo}
id="full_access"
.label=${this.supervisor.localize(
"addon.dashboard.capability.label.hardware"
)}
label="hardware"
description=""
>
<ha-svg-icon .path=${mdiChip}></ha-svg-icon>
@@ -341,9 +355,7 @@ class HassioAddonInfo extends LitElement {
<ha-label-badge
@click=${this._showMoreInfo}
id="homeassistant_api"
.label=${this.supervisor.localize(
"addon.dashboard.capability.label.hass"
)}
label="hass"
description=""
>
<ha-svg-icon .path=${mdiHomeAssistant}></ha-svg-icon>
@@ -355,12 +367,8 @@ class HassioAddonInfo extends LitElement {
<ha-label-badge
@click=${this._showMoreInfo}
id="hassio_api"
.label=${this.supervisor.localize(
"addon.dashboard.capability.label.hassio"
)}
.description=${this.supervisor.localize(
`addon.dashboard.capability.role.${this.addon.hassio_role}`
) || this.addon.hassio_role}
label="hassio"
.description=${this.addon.hassio_role}
>
<ha-svg-icon .path=${mdiHomeAssistant}></ha-svg-icon>
</ha-label-badge>
@@ -371,9 +379,7 @@ class HassioAddonInfo extends LitElement {
<ha-label-badge
@click=${this._showMoreInfo}
id="docker_api"
.label=".${this.supervisor.localize(
"addon.dashboard.capability.label.docker"
)}"
label="docker"
description=""
>
<ha-svg-icon .path=${mdiDocker}></ha-svg-icon>
@@ -385,9 +391,7 @@ class HassioAddonInfo extends LitElement {
<ha-label-badge
@click=${this._showMoreInfo}
id="host_pid"
.label=${this.supervisor.localize(
"addon.dashboard.capability.label.host_pid"
)}
label="host pid"
description=""
>
<ha-svg-icon .path=${mdiPound}></ha-svg-icon>
@@ -400,9 +404,7 @@ class HassioAddonInfo extends LitElement {
@click=${this._showMoreInfo}
class=${this._computeApparmorClassName}
id="apparmor"
.label=${this.supervisor.localize(
"addon.dashboard.capability.label.apparmor"
)}
label="apparmor"
description=""
>
<ha-svg-icon .path=${mdiShield}></ha-svg-icon>
@@ -414,9 +416,7 @@ class HassioAddonInfo extends LitElement {
<ha-label-badge
@click=${this._showMoreInfo}
id="auth_api"
.label=${this.supervisor.localize(
"addon.dashboard.capability.label.auth"
)}
label="auth"
description=""
>
<ha-svg-icon .path=${mdiKey}></ha-svg-icon>
@@ -428,9 +428,7 @@ class HassioAddonInfo extends LitElement {
<ha-label-badge
@click=${this._showMoreInfo}
id="ingress"
.label=${this.supervisor.localize(
"addon.dashboard.capability.label.ingress"
)}
label="ingress"
description=""
>
<ha-svg-icon
@@ -451,14 +449,10 @@ class HassioAddonInfo extends LitElement {
>
<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize(
"addon.dashboard.option.boot.title"
)}
Start on boot
</span>
<span slot="description">
${this.supervisor.localize(
"addon.dashboard.option.boot.description"
)}
Make the add-on start during a system boot
</span>
<ha-switch
@change=${this._startOnBootToggled}
@@ -471,14 +465,10 @@ class HassioAddonInfo extends LitElement {
? html`
<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize(
"addon.dashboard.option.watchdog.title"
)}
Watchdog
</span>
<span slot="description">
${this.supervisor.localize(
"addon.dashboard.option.boot.description"
)}
This will start the add-on if it crashes
</span>
<ha-switch
@change=${this._watchdogToggled}
@@ -493,14 +483,11 @@ class HassioAddonInfo extends LitElement {
? html`
<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize(
"addon.dashboard.option.auto_update.title"
)}
Auto update
</span>
<span slot="description">
${this.supervisor.localize(
"addon.dashboard.option.boot.description"
)}
Auto update the add-on when there is a new
version available
</span>
<ha-switch
@change=${this._autoUpdateToggled}
@@ -510,22 +497,21 @@ class HassioAddonInfo extends LitElement {
</ha-settings-row>
`
: ""}
${!this._computeCannotIngressSidebar && this.addon.ingress
${this.addon.ingress
? html`
<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize(
"addon.dashboard.option.ingress_panel.title"
)}
Show in sidebar
</span>
<span slot="description">
${this.supervisor.localize(
"addon.dashboard.option.ingress_panel.description"
)}
${this._computeCannotIngressSidebar
? "This option requires Home Assistant 0.92 or later."
: "Add this add-on to your sidebar"}
</span>
<ha-switch
@change=${this._panelToggled}
.checked=${this.addon.ingress_panel}
.disabled=${this._computeCannotIngressSidebar}
haptic
></ha-switch>
</ha-settings-row>
@@ -535,14 +521,10 @@ class HassioAddonInfo extends LitElement {
? html`
<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize(
"addon.dashboard.option.protected.title"
)}
Protection mode
</span>
<span slot="description">
${this.supervisor.localize(
"addon.dashboard.option.protected.description"
)}
Blocks elevated system access from the add-on
</span>
<ha-switch
@change=${this._protectionToggled}
@@ -560,7 +542,7 @@ class HassioAddonInfo extends LitElement {
${this.addon.state === "started"
? html`<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize("addon.dashboard.hostname")}
Hostname
</span>
<code slot="description">
${this.addon.hostname}
@@ -587,20 +569,17 @@ class HassioAddonInfo extends LitElement {
)
? html`
<p class="warning">
${this.supervisor.localize(
"addon.dashboard.not_available_arch"
)}
This add-on is not compatible with the processor of your
device or the operating system you have installed on your
device.
</p>
`
: html`
<p class="warning">
${this.supervisor.localize(
"addon.dashboard.not_available_version",
"core_version_installed",
this.supervisor.core.version,
"core_version_needed",
addonStoreInfo!.homeassistant
)}
You are running Home Assistant
${this.supervisor.core.version}, to install this add-on you
need at least version ${addonStoreInfo!.homeassistant} of
Home Assistant
</p>
`
: ""}
@@ -614,18 +593,18 @@ class HassioAddonInfo extends LitElement {
class="warning"
@click=${this._stopClicked}
>
${this.supervisor.localize("addon.dashboard.stop")}
Stop
</ha-progress-button>
<ha-progress-button
class="warning"
@click=${this._restartClicked}
>
${this.supervisor.localize("addon.dashboard.restart")}
Restart
</ha-progress-button>
`
: html`
<ha-progress-button @click=${this._startClicked}>
${this.supervisor.localize("addon.dashboard.start")}
Start
</ha-progress-button>
`
: html`
@@ -633,7 +612,7 @@ class HassioAddonInfo extends LitElement {
.disabled=${!this.addon.available}
@click=${this._installClicked}
>
${this.supervisor.localize("addon.dashboard.install")}
Install
</ha-progress-button>
`}
</div>
@@ -648,9 +627,7 @@ class HassioAddonInfo extends LitElement {
rel="noopener"
>
<mwc-button>
${this.supervisor.localize(
"addon.dashboard.open_web_ui"
)}
Open web UI
</mwc-button>
</a>
`
@@ -658,9 +635,7 @@ class HassioAddonInfo extends LitElement {
${this._computeShowIngressUI
? html`
<mwc-button @click=${this._openIngress}>
${this.supervisor.localize(
"addon.dashboard.open_web_ui"
)}
Open web UI
</mwc-button>
`
: ""}
@@ -668,7 +643,7 @@ class HassioAddonInfo extends LitElement {
class="warning"
@click=${this._uninstallClicked}
>
${this.supervisor.localize("addon.dashboard.uninstall")}
Uninstall
</ha-progress-button>
${this.addon.build
? html`
@@ -677,7 +652,7 @@ class HassioAddonInfo extends LitElement {
.hass=${this.hass}
.path="hassio/addons/${this.addon.slug}/rebuild"
>
${this.supervisor.localize("addon.dashboard.rebuild")}
Rebuild
</ha-call-api-button>
`
: ""}`
@@ -737,21 +712,8 @@ class HassioAddonInfo extends LitElement {
private _showMoreInfo(ev): void {
const id = ev.currentTarget.id;
showHassioMarkdownDialog(this, {
title: this.supervisor.localize(`addon.dashboard.capability.${id}.title`),
content:
id === "stage"
? this.supervisor.localize(
`addon.dashboard.capability.${id}.description`,
"icon_stable",
`<ha-svg-icon path="${STAGE_ICON.stable}"></ha-svg-icon>`,
"icon_experimental",
`<ha-svg-icon path="${STAGE_ICON.experimental}"></ha-svg-icon>`,
"icon_deprecated",
`<ha-svg-icon path="${STAGE_ICON.deprecated}"></ha-svg-icon>`
)
: this.supervisor.localize(
`addon.dashboard.capability.${id}.description`
),
title: PERMIS_DESC[id].title,
content: PERMIS_DESC[id].description,
});
}
@@ -804,11 +766,9 @@ class HassioAddonInfo extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
this._error = this.supervisor.localize(
"addon.failed_to_save",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to set addon option, ${extractApiErrorMessage(
err
)}`;
}
}
@@ -826,11 +786,9 @@ class HassioAddonInfo extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
this._error = this.supervisor.localize(
"addon.failed_to_save",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to set addon option, ${extractApiErrorMessage(
err
)}`;
}
}
@@ -848,11 +806,9 @@ class HassioAddonInfo extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
this._error = this.supervisor.localize(
"addon.failed_to_save",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to set addon option, ${extractApiErrorMessage(
err
)}`;
}
}
@@ -870,11 +826,9 @@ class HassioAddonInfo extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
this._error = this.supervisor.localize(
"addon.failed_to_save",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to set addon security option, ${extractApiErrorMessage(
err
)}`;
}
}
@@ -892,11 +846,9 @@ class HassioAddonInfo extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
this._error = this.supervisor.localize(
"addon.failed_to_save",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to set addon option, ${extractApiErrorMessage(
err
)}`;
}
}
@@ -907,14 +859,12 @@ class HassioAddonInfo extends LitElement {
this.addon.slug
);
showHassioMarkdownDialog(this, {
title: this.supervisor.localize("addon.dashboard.changelog"),
title: "Changelog",
content,
});
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize(
"addon.dashboard.action_error.get_changelog"
),
title: "Failed to get addon changelog",
text: extractApiErrorMessage(err),
});
}
@@ -934,7 +884,7 @@ class HassioAddonInfo extends LitElement {
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize("addon.dashboard.action_error.install"),
title: "Failed to install addon",
text: extractApiErrorMessage(err),
});
}
@@ -955,7 +905,7 @@ class HassioAddonInfo extends LitElement {
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize("addon.dashboard.action_error.stop"),
title: "Failed to stop addon",
text: extractApiErrorMessage(err),
});
}
@@ -976,7 +926,7 @@ class HassioAddonInfo extends LitElement {
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize("addon.dashboard.action_error.restart"),
title: "Failed to restart addon",
text: extractApiErrorMessage(err),
});
}
@@ -984,32 +934,12 @@ class HassioAddonInfo extends LitElement {
}
private async _updateClicked(): Promise<void> {
showDialogSupervisorUpdate(this, {
showDialogSupervisorAddonUpdate(this, {
addon: this.addon,
supervisor: this.supervisor,
name: this.addon.name,
version: this.addon.version_latest,
snapshotParams: {
name: `addon_${this.addon.slug}_${this.addon.version}`,
addons: [this.addon.slug],
homeassistant: false,
},
updateHandler: async () => await this._updateAddon(),
});
}
private async _updateAddon(): Promise<void> {
await updateHassioAddon(this.hass, this.addon.slug);
fireEvent(this, "supervisor-colllection-refresh", {
colllection: "addon",
});
const eventdata = {
success: true,
response: undefined,
path: "update",
};
fireEvent(this, "hass-api-called", eventdata);
}
private async _startClicked(ev: CustomEvent): Promise<void> {
const button = ev.currentTarget as any;
button.progress = true;
@@ -1020,15 +950,11 @@ class HassioAddonInfo extends LitElement {
);
if (!validate.valid) {
await showConfirmationDialog(this, {
title: this.supervisor.localize(
"addon.dashboard.action_error.start_invalid_config"
),
title: "Failed to start addon - configuration validation failed!",
text: validate.message.split(" Got ")[0],
confirm: () => this._openConfiguration(),
confirmText: this.supervisor.localize(
"addon.dashboard.action_error.go_to_config"
),
dismissText: this.supervisor.localize("common.cancel"),
confirmText: "Go to configuration",
dismissText: "Cancel",
});
button.progress = false;
return;
@@ -1053,7 +979,7 @@ class HassioAddonInfo extends LitElement {
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize("addon.dashboard.action_error.start"),
title: "Failed to start addon",
text: extractApiErrorMessage(err),
});
}
@@ -1091,9 +1017,7 @@ class HassioAddonInfo extends LitElement {
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize(
"addon.dashboard.action_error.uninstall"
),
title: "Failed to uninstall addon",
text: extractApiErrorMessage(err),
});
}
@@ -9,7 +9,6 @@ import {
} from "lit-element";
import "../../../../src/components/ha-circular-progress";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
@@ -19,8 +18,6 @@ import "./hassio-addon-logs";
class HassioAddonLogDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon?: HassioAddonDetails;
protected render(): TemplateResult {
@@ -31,7 +28,6 @@ class HassioAddonLogDashboard extends LitElement {
<div class="content">
<hassio-addon-logs
.hass=${this.hass}
.supervisor=${this.supervisor}
.addon=${this.addon}
></hassio-addon-logs>
</div>
+2 -11
View File
@@ -15,7 +15,6 @@ import {
HassioAddonDetails,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import "../../components/hassio-ansi-to-html";
@@ -25,8 +24,6 @@ import { hassioStyle } from "../../resources/hassio-style";
class HassioAddonLogs extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@@ -51,9 +48,7 @@ class HassioAddonLogs extends LitElement {
: ""}
</div>
<div class="card-actions">
<mwc-button @click=${this._refresh}>
${this.supervisor.localize("common.refresh")}
</mwc-button>
<mwc-button @click=${this._refresh}>Refresh</mwc-button>
</div>
</ha-card>
`;
@@ -81,11 +76,7 @@ class HassioAddonLogs extends LitElement {
try {
this._content = await fetchHassioAddonLogs(this.hass, this.addon.slug);
} catch (err) {
this._error = this.supervisor.localize(
"addon.logs.get_logs",
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to get addon logs, ${extractApiErrorMessage(err)}`;
}
}
+1 -1
View File
@@ -44,7 +44,7 @@ class HassioCardContent extends LitElement {
${this.iconImage
? html`
<div class="icon_image ${this.iconClass}">
<img src="${this.iconImage}" .title=${this.iconTitle} />
<img src="${this.iconImage}" title="${this.iconTitle}" />
<div></div>
</div>
`
+1 -1
View File
@@ -26,7 +26,7 @@ class SupervisorMetric extends LitElement {
<span slot="heading">
${this.description}
</span>
<div slot="description" .title=${this.tooltip ?? ""}>
<div slot="description" title="${this.tooltip ?? ""}">
<span class="value">
${roundedValue}%
</span>
+7 -11
View File
@@ -27,15 +27,17 @@ class HassioAddons extends LitElement {
protected render(): TemplateResult {
return html`
<div class="content">
<h1>${this.supervisor.localize("dashboard.addons")}</h1>
<h1>Add-ons</h1>
<div class="card-group">
${!this.supervisor.supervisor.addons?.length
? html`
<ha-card>
<div class="card-content">
You don't have any add-ons installed yet. Head over to
<button class="link" @click=${this._openStore}>
${this.supervisor.localize("dashboard.no_addons")}
the add-on store
</button>
to get started!
</div>
</ha-card>
`
@@ -56,16 +58,10 @@ class HassioAddons extends LitElement {
? mdiArrowUpBoldCircle
: mdiPuzzle}
.iconTitle=${addon.state !== "started"
? this.supervisor.localize(
"dashboard.addon_stopped"
)
? "Add-on is stopped"
: addon.update_available!
? this.supervisor.localize(
"dashboard.addon_new_version"
)
: this.supervisor.localize(
"dashboard.addon_running"
)}
? "New version available"
: "Add-on is running"}
.iconClass=${addon.update_available
? addon.state === "started"
? "update"
+3 -6
View File
@@ -29,16 +29,13 @@ class HassioDashboard extends LitElement {
return html`
<hass-tabs-subpage
.hass=${this.hass}
.localizeFunc=${this.supervisor.localize}
.narrow=${this.narrow}
hassio
main-page
.route=${this.route}
.tabs=${supervisorTabs}
main-page
supervisor
>
<span slot="header">
${this.supervisor.localize("panel.dashboard")}
</span>
<span slot="header">Dashboard</span>
<div class="content">
<hassio-update
.hass=${this.hass}
+25 -86
View File
@@ -10,11 +10,9 @@ import {
TemplateResult,
} from "lit-element";
import memoizeOne from "memoize-one";
import { atLeastVersion } from "../../../src/common/config/version";
import { fireEvent } from "../../../src/common/dom/fire_event";
import "../../../src/components/buttons/ha-progress-button";
import "../../../src/components/ha-card";
import "../../../src/components/ha-settings-row";
import "../../../src/components/ha-svg-icon";
import {
extractApiErrorMessage,
@@ -26,24 +24,16 @@ import {
HassioHomeAssistantInfo,
HassioSupervisorInfo,
} from "../../../src/data/hassio/supervisor";
import { updateCore } from "../../../src/data/supervisor/core";
import {
Supervisor,
supervisorApiWsRequest,
} from "../../../src/data/supervisor/supervisor";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import {
showAlertDialog,
showConfirmationDialog,
} from "../../../src/dialogs/generic/show-dialog-box";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types";
import { showDialogSupervisorUpdate } from "../dialogs/update/show-dialog-update";
import { showDialogSupervisorCoreUpdate } from "../dialogs/core/show-dialog-core-update";
import { hassioStyle } from "../resources/hassio-style";
const computeVersion = (key: string, version: string): string => {
return key === "os" ? version : `${key}-${version}`;
};
@customElement("hassio-update")
export class HassioUpdate extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@@ -69,12 +59,9 @@ export class HassioUpdate extends LitElement {
return html`
<div class="content">
<h1>
${this.supervisor.localize(
"common.update_available",
"count",
updatesAvailable
)}
🎉
${updatesAvailable > 1
? "Updates Available 🎉"
: "Update Available 🎉"}
</h1>
<div class="card-group">
${this._renderUpdateCard(
@@ -123,30 +110,14 @@ export class HassioUpdate extends LitElement {
<div class="icon">
<ha-svg-icon .path=${mdiHomeAssistant}></ha-svg-icon>
</div>
<div class="update-heading">${name}</div>
<ha-settings-row two-line>
<span slot="heading">
${this.supervisor.localize("common.version")}
</span>
<span slot="description">
${computeVersion(key, object.version!)}
</span>
</ha-settings-row>
<ha-settings-row two-line>
<span slot="heading">
${this.supervisor.localize("common.newest_version")}
</span>
<span slot="description">
${computeVersion(key, object.version_latest!)}
</span>
</ha-settings-row>
<div class="update-heading">${name} ${object.version_latest}</div>
<div class="warning">
You are currently running version ${object.version}
</div>
</div>
<div class="card-actions">
<a href="${releaseNotesUrl}" target="_blank" rel="noreferrer">
<mwc-button>
${this.supervisor.localize("common.release_notes")}
</mwc-button>
<mwc-button>Release notes</mwc-button>
</a>
<ha-progress-button
.apiPath=${apiPath}
@@ -155,7 +126,7 @@ export class HassioUpdate extends LitElement {
.version=${object.version_latest}
@click=${this._confirmUpdate}
>
${this.supervisor.localize("common.update")}
Update
</ha-progress-button>
</div>
</ha-card>
@@ -165,35 +136,15 @@ export class HassioUpdate extends LitElement {
private async _confirmUpdate(ev): Promise<void> {
const item = ev.currentTarget;
if (item.key === "core") {
showDialogSupervisorUpdate(this, {
supervisor: this.supervisor,
name: "Home Assistant Core",
version: this.supervisor.core.version,
snapshotParams: {
name: `core_${this.supervisor.core.version}`,
folders: ["homeassistant"],
homeassistant: true,
},
updateHandler: async () => this._updateCore(),
});
showDialogSupervisorCoreUpdate(this, { supervisor: this.supervisor });
return;
}
item.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize(
"confirm.update.title",
"name",
item.name
),
text: this.supervisor.localize(
"confirm.update.text",
"name",
item.name,
"version",
computeVersion(item.key, item.version)
),
confirmText: this.supervisor.localize("common.update"),
dismissText: this.supervisor.localize("common.cancel"),
title: `Update ${item.name}`,
text: `Are you sure you want to update ${item.name} to version ${item.version}?`,
confirmText: "update",
dismissText: "cancel",
});
if (!confirmed) {
@@ -201,15 +152,7 @@ export class HassioUpdate extends LitElement {
return;
}
try {
if (atLeastVersion(this.hass.config.version, 2021, 2, 4)) {
await supervisorApiWsRequest(this.hass.connection, {
method: "post",
endpoint: item.apiPath.replace("hassio", ""),
timeout: null,
});
} else {
await this.hass.callApi<HassioResponse<void>>("POST", item.apiPath);
}
await this.hass.callApi<HassioResponse<void>>("POST", item.apiPath);
fireEvent(this, "supervisor-colllection-refresh", {
colllection: item.key,
});
@@ -222,7 +165,7 @@ export class HassioUpdate extends LitElement {
!ignoredStatusCodes.has(err.status_code)
) {
showAlertDialog(this, {
title: this.supervisor.localize("common.error.update_failed"),
title: "Update failed",
text: extractApiErrorMessage(err),
});
}
@@ -230,13 +173,6 @@ export class HassioUpdate extends LitElement {
item.progress = false;
}
private async _updateCore(): Promise<void> {
await updateCore(this.hass);
fireEvent(this, "supervisor-colllection-refresh", {
colllection: "core",
});
}
static get styles(): CSSResult[] {
return [
haStyle,
@@ -254,6 +190,9 @@ export class HassioUpdate extends LitElement {
margin-bottom: 0.5em;
color: var(--primary-text-color);
}
.warning {
color: var(--secondary-text-color);
}
.card-content {
height: calc(100% - 47px);
box-sizing: border-box;
@@ -261,13 +200,13 @@ export class HassioUpdate extends LitElement {
.card-actions {
text-align: right;
}
.errors {
color: var(--error-color);
padding: 16px;
}
a {
text-decoration: none;
}
ha-settings-row {
padding: 0;
--paper-item-body-two-line-min-height: 32px;
}
`,
];
}
@@ -6,6 +6,7 @@ import {
html,
internalProperty,
LitElement,
property,
TemplateResult,
} from "lit-element";
import { fireEvent } from "../../../../src/common/dom/fire_event";
@@ -14,16 +15,25 @@ import "../../../../src/components/ha-dialog";
import "../../../../src/components/ha-settings-row";
import "../../../../src/components/ha-svg-icon";
import "../../../../src/components/ha-switch";
import {
HassioAddonDetails,
updateHassioAddon,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { createHassioPartialSnapshot } from "../../../../src/data/hassio/snapshot";
import { haStyle, haStyleDialog } from "../../../../src/resources/styles";
import type { HomeAssistant } from "../../../../src/types";
import { SupervisorDialogSupervisorUpdateParams } from "./show-dialog-update";
import { SupervisorDialogSupervisorAddonUpdateParams } from "./show-dialog-addon-update";
@customElement("dialog-supervisor-addon-update")
class DialogSupervisorAddonUpdate extends LitElement {
@property({ attribute: false }) public supervisor!: Supervisor;
@customElement("dialog-supervisor-update")
class DialogSupervisorUpdate extends LitElement {
public hass!: HomeAssistant;
public addon!: HassioAddonDetails;
@internalProperty() private _opened = false;
@internalProperty() private _createSnapshot = true;
@@ -32,22 +42,20 @@ class DialogSupervisorUpdate extends LitElement {
@internalProperty() private _error?: string;
@internalProperty()
private _dialogParams?: SupervisorDialogSupervisorUpdateParams;
public async showDialog(
params: SupervisorDialogSupervisorUpdateParams
params: SupervisorDialogSupervisorAddonUpdateParams
): Promise<void> {
this._opened = true;
this._dialogParams = params;
this.addon = params.addon;
this.supervisor = params.supervisor;
await this.updateComplete;
}
public closeDialog(): void {
this._action = null;
this._createSnapshot = true;
this._opened = false;
this._error = undefined;
this._dialogParams = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -60,77 +68,52 @@ class DialogSupervisorUpdate extends LitElement {
}
protected render(): TemplateResult {
if (!this._dialogParams) {
return html``;
}
return html`
<ha-dialog .open=${this._opened} scrimClickAction escapeKeyAction>
${this._action === null
? html`<slot name="heading">
<h2 id="title" class="header_title">
${this._dialogParams.supervisor.localize(
"confirm.update.title",
"name",
this._dialogParams.name
)}
Update ${this.addon.name}
</h2>
</slot>
<div>
${this._dialogParams.supervisor.localize(
"confirm.update.text",
"name",
this._dialogParams.name,
"version",
this._dialogParams.version
)}
Are you sure you want to update the ${this.addon.name} add-on to
version ${this.addon.version_latest}?
</div>
<ha-settings-row>
<span slot="heading">
${this._dialogParams.supervisor.localize(
"dialog.update.snapshot"
)}
Snapshot
</span>
<span slot="description">
${this._dialogParams.supervisor.localize(
"dialog.update.create_snapshot",
"name",
this._dialogParams.name
)}
Create a snapshot of the ${this.addon.name} add-on before
updating
</span>
<ha-switch
.checked=${this._createSnapshot}
haptic
title="Create snapshot"
@click=${this._toggleSnapshot}
>
</ha-switch>
</ha-settings-row>
<mwc-button @click=${this.closeDialog} slot="secondaryAction">
${this._dialogParams.supervisor.localize("common.cancel")}
Cancel
</mwc-button>
<mwc-button
.disabled=${this._error !== undefined}
.disabled=${this._error !== undefined ||
this.supervisor.info.state !== "running"}
@click=${this._update}
slot="primaryAction"
>
${this._dialogParams.supervisor.localize("common.update")}
Update
</mwc-button>`
: html`<ha-circular-progress alt="Updating" size="large" active>
</ha-circular-progress>
<p class="progress-text">
${this._action === "update"
? this._dialogParams.supervisor.localize(
"dialog.update.updating",
"name",
this._dialogParams.name,
"version",
this._dialogParams.version
)
: this._dialogParams.supervisor.localize(
"dialog.update.snapshotting",
"name",
this._dialogParams.name
)}
? `Updating ${this.addon.name} to version ${this.addon.version_latest}`
: "Creating snapshot of Home Assistant Core"}
</p>`}
${this._error ? html`<p class="error">${this._error}</p>` : ""}
</ha-dialog>
@@ -145,10 +128,11 @@ class DialogSupervisorUpdate extends LitElement {
if (this._createSnapshot) {
this._action = "snapshot";
try {
await createHassioPartialSnapshot(
this.hass,
this._dialogParams!.snapshotParams
);
await createHassioPartialSnapshot(this.hass, {
name: `addon_${this.addon.slug}_${this.addon.version}`,
addons: [this.addon.slug],
homeassistant: false,
});
} catch (err) {
this._error = extractApiErrorMessage(err);
this._action = null;
@@ -158,13 +142,16 @@ class DialogSupervisorUpdate extends LitElement {
this._action = "update";
try {
await this._dialogParams!.updateHandler!();
await updateHassioAddon(this.hass, this.addon.slug);
} catch (err) {
this._error = extractApiErrorMessage(err);
this._action = null;
return;
}
fireEvent(this, "supervisor-colllection-refresh", { colllection: "addon" });
fireEvent(this, "supervisor-colllection-refresh", {
colllection: "supervisor",
});
this.closeDialog();
}
@@ -198,6 +185,6 @@ class DialogSupervisorUpdate extends LitElement {
declare global {
interface HTMLElementTagNameMap {
"dialog-supervisor-update": DialogSupervisorUpdate;
"dialog-supervisor-addon-update": DialogSupervisorAddonUpdate;
}
}
@@ -0,0 +1,19 @@
import { fireEvent } from "../../../../src/common/dom/fire_event";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
export interface SupervisorDialogSupervisorAddonUpdateParams {
addon: HassioAddonDetails;
supervisor: Supervisor;
}
export const showDialogSupervisorAddonUpdate = (
element: HTMLElement,
dialogParams: SupervisorDialogSupervisorAddonUpdateParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "dialog-supervisor-addon-update",
dialogImport: () => import("./dialog-supervisor-addon-update"),
dialogParams,
});
};
@@ -0,0 +1,182 @@
import "@material/mwc-button/mwc-button";
import {
css,
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
TemplateResult,
} from "lit-element";
import { fireEvent } from "../../../../src/common/dom/fire_event";
import "../../../../src/components/ha-circular-progress";
import "../../../../src/components/ha-dialog";
import "../../../../src/components/ha-settings-row";
import "../../../../src/components/ha-svg-icon";
import "../../../../src/components/ha-switch";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { createHassioPartialSnapshot } from "../../../../src/data/hassio/snapshot";
import { updateCore } from "../../../../src/data/supervisor/core";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle, haStyleDialog } from "../../../../src/resources/styles";
import type { HomeAssistant } from "../../../../src/types";
import { SupervisorDialogSupervisorCoreUpdateParams } from "./show-dialog-core-update";
@customElement("dialog-supervisor-core-update")
class DialogSupervisorCoreUpdate extends LitElement {
@property({ attribute: false }) public supervisor!: Supervisor;
public hass!: HomeAssistant;
@internalProperty() private _opened = false;
@internalProperty() private _createSnapshot = true;
@internalProperty() private _action: "snapshot" | "update" | null = null;
@internalProperty() private _error?: string;
public async showDialog(
params: SupervisorDialogSupervisorCoreUpdateParams
): Promise<void> {
this._opened = true;
this.supervisor = params.supervisor;
await this.updateComplete;
}
public closeDialog(): void {
this._action = null;
this._createSnapshot = true;
this._opened = false;
this._error = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
public focus(): void {
this.updateComplete.then(() =>
(this.shadowRoot?.querySelector(
"[dialogInitialFocus]"
) as HTMLElement)?.focus()
);
}
protected render(): TemplateResult {
return html`
<ha-dialog .open=${this._opened} scrimClickAction escapeKeyAction>
${this._action === null
? html`<slot name="heading">
<h2 id="title" class="header_title">
Update Home Assistant Core
</h2>
</slot>
<div>
Are you sure you want to update Home Assistant Core to version
${this.supervisor.core.version_latest}?
</div>
<ha-settings-row three-rows>
<span slot="heading">
Snapshot
</span>
<span slot="description">
Create a snapshot of Home Assistant Core before updating
</span>
<ha-switch
.checked=${this._createSnapshot}
haptic
title="Create snapshot"
@click=${this._toggleSnapshot}
>
</ha-switch>
</ha-settings-row>
<mwc-button @click=${this.closeDialog} slot="secondaryAction">
Cancel
</mwc-button>
<mwc-button
.disabled=${this._error !== undefined ||
this.supervisor.info.state !== "running"}
@click=${this._update}
slot="primaryAction"
>
Update
</mwc-button>`
: html`<ha-circular-progress alt="Updating" size="large" active>
</ha-circular-progress>
<p class="progress-text">
${this._action === "update"
? `Updating Home Assistant Core to version ${this.supervisor.core.version_latest}`
: "Creating snapshot of Home Assistant Core"}
</p>`}
${this._error ? html`<p class="error">${this._error}</p>` : ""}
</ha-dialog>
`;
}
private _toggleSnapshot() {
this._createSnapshot = !this._createSnapshot;
}
private async _update() {
if (this._createSnapshot) {
this._action = "snapshot";
try {
await createHassioPartialSnapshot(this.hass, {
name: `core_${this.supervisor.core.version}`,
folders: ["homeassistant"],
homeassistant: true,
});
} catch (err) {
this._error = extractApiErrorMessage(err);
this._action = null;
return;
}
}
this._action = "update";
try {
await updateCore(this.hass);
} catch (err) {
if (this.hass.connection.connected) {
this._error = extractApiErrorMessage(err);
this._action = null;
return;
}
}
fireEvent(this, "supervisor-colllection-refresh", { colllection: "core" });
this.closeDialog();
}
static get styles(): CSSResult[] {
return [
haStyle,
haStyleDialog,
css`
.form {
color: var(--primary-text-color);
}
ha-settings-row {
margin-top: 32px;
padding: 0;
}
ha-circular-progress {
display: block;
margin: 32px;
text-align: center;
}
.progress-text {
text-align: center;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"dialog-supervisor-core-update": DialogSupervisorCoreUpdate;
}
}
@@ -0,0 +1,17 @@
import { fireEvent } from "../../../../src/common/dom/fire_event";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
export interface SupervisorDialogSupervisorCoreUpdateParams {
supervisor: Supervisor;
}
export const showDialogSupervisorCoreUpdate = (
element: HTMLElement,
dialogParams: SupervisorDialogSupervisorCoreUpdateParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "dialog-supervisor-core-update",
dialogImport: () => import("./dialog-supervisor-core-update"),
dialogParams,
});
};
@@ -35,7 +35,6 @@ import {
updateNetworkInterface,
WifiConfiguration,
} from "../../../../src/data/hassio/network";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import {
showAlertDialog,
showConfirmationDialog,
@@ -52,8 +51,6 @@ export class DialogHassioNetwork extends LitElement
implements HassDialog<HassioNetworkDialogParams> {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@internalProperty() private _accessPoints?: AccessPoints;
@internalProperty() private _curTabIndex = 0;
@@ -76,8 +73,7 @@ export class DialogHassioNetwork extends LitElement
this._params = params;
this._dirty = false;
this._curTabIndex = 0;
this.supervisor = params.supervisor;
this._interfaces = params.supervisor.network.interfaces.sort((a, b) => {
this._interfaces = params.network.interfaces.sort((a, b) => {
return a.primary > b.primary ? -1 : 1;
});
this._interface = { ...this._interfaces[this._curTabIndex] };
@@ -108,7 +104,7 @@ export class DialogHassioNetwork extends LitElement
<div slot="heading">
<ha-header-bar>
<span slot="title">
${this.supervisor.localize("dialog.network.title")}
Network settings
</span>
<mwc-icon-button slot="actionItems" dialogAction="cancel">
<ha-svg-icon .path=${mdiClose}></ha-svg-icon>
@@ -143,13 +139,7 @@ export class DialogHassioNetwork extends LitElement
? html`
<ha-expansion-panel header="Wi-Fi" outlined>
${this._interface?.wifi?.ssid
? html`<p>
${this.supervisor.localize(
"dialog.network.connected_to",
"ssid",
this._interface?.wifi?.ssid
)}
</p>`
? html`<p>Connected to: ${this._interface?.wifi?.ssid}</p>`
: ""}
<mwc-button
class="scan"
@@ -159,7 +149,7 @@ export class DialogHassioNetwork extends LitElement
${this._scanning
? html`<ha-circular-progress active size="small">
</ha-circular-progress>`
: this.supervisor.localize("dialog.network.scan_ap")}
: "Scan for accesspoints"}
</mwc-button>
${this._accessPoints &&
this._accessPoints.accesspoints &&
@@ -191,11 +181,7 @@ export class DialogHassioNetwork extends LitElement
${this._wifiConfiguration
? html`
<div class="radio-row">
<ha-formfield
.label=${this.supervisor.localize(
"dialog.network.open"
)}
>
<ha-formfield label="open">
<ha-radio
@change=${this._handleRadioValueChangedAp}
.ap=${this._wifiConfiguration}
@@ -207,11 +193,7 @@ export class DialogHassioNetwork extends LitElement
>
</ha-radio>
</ha-formfield>
<ha-formfield
.label=${this.supervisor.localize(
"dialog.network.wep"
)}
>
<ha-formfield label="wep">
<ha-radio
@change=${this._handleRadioValueChangedAp}
.ap=${this._wifiConfiguration}
@@ -221,11 +203,7 @@ export class DialogHassioNetwork extends LitElement
>
</ha-radio>
</ha-formfield>
<ha-formfield
.label=${this.supervisor.localize(
"dialog.network.wpa"
)}
>
<ha-formfield label="wpa-psk">
<ha-radio
@change=${this._handleRadioValueChangedAp}
.ap=${this._wifiConfiguration}
@@ -259,21 +237,18 @@ export class DialogHassioNetwork extends LitElement
: ""}
${this._dirty
? html`<div class="warning">
${this.supervisor.localize("dialog.network.warning")}
If you are changing the Wi-Fi, IP or gateway addresses, you might
lose the connection!
</div>`
: ""}
</div>
<div class="buttons">
<mwc-button
.label=${this.supervisor.localize("common.cancel")}
@click=${this.closeDialog}
>
</mwc-button>
<mwc-button label="close" @click=${this.closeDialog}> </mwc-button>
<mwc-button @click=${this._updateNetwork} .disabled=${!this._dirty}>
${this._processing
? html`<ha-circular-progress active size="small">
</ha-circular-progress>`
: this.supervisor.localize("common.save")}
: "Save"}
</mwc-button>
</div>`;
}
@@ -310,9 +285,7 @@ export class DialogHassioNetwork extends LitElement
outlined
>
<div class="radio-row">
<ha-formfield
.label=${this.supervisor.localize("dialog.network.dhcp")}
>
<ha-formfield label="DHCP">
<ha-radio
@change=${this._handleRadioValueChanged}
.version=${version}
@@ -322,9 +295,7 @@ export class DialogHassioNetwork extends LitElement
>
</ha-radio>
</ha-formfield>
<ha-formfield
.label=${this.supervisor.localize("dialog.network.static")}
>
<ha-formfield label="Static">
<ha-radio
@change=${this._handleRadioValueChanged}
.version=${version}
@@ -334,10 +305,7 @@ export class DialogHassioNetwork extends LitElement
>
</ha-radio>
</ha-formfield>
<ha-formfield
.label=${this.supervisor.localize("dialog.network.disabled")}
class="warning"
>
<ha-formfield label="Disabled" class="warning">
<ha-radio
@change=${this._handleRadioValueChanged}
.version=${version}
@@ -353,7 +321,7 @@ export class DialogHassioNetwork extends LitElement
<paper-input
class="flex-auto"
id="address"
.label=${this.supervisor.localize("dialog.network.ip_netmask")}
label="IP address/Netmask"
.version=${version}
.value=${this._toString(this._interface![version].address)}
@value-changed=${this._handleInputValueChanged}
@@ -362,7 +330,7 @@ export class DialogHassioNetwork extends LitElement
<paper-input
class="flex-auto"
id="gateway"
.label=${this.supervisor.localize("dialog.network.gateway")}
label="Gateway address"
.version=${version}
.value=${this._interface![version].gateway}
@value-changed=${this._handleInputValueChanged}
@@ -371,7 +339,7 @@ export class DialogHassioNetwork extends LitElement
<paper-input
class="flex-auto"
id="nameservers"
.label=${this.supervisor.localize("dialog.network.dns_servers")}
label="DNS servers"
.version=${version}
.value=${this._toString(this._interface![version].nameservers)}
@value-changed=${this._handleInputValueChanged}
@@ -456,7 +424,7 @@ export class DialogHassioNetwork extends LitElement
);
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize("dialog.network.failed_to_change"),
title: "Failed to change network settings",
text: extractApiErrorMessage(err),
});
this._processing = false;
@@ -469,9 +437,10 @@ export class DialogHassioNetwork extends LitElement
private async _handleTabActivated(ev: CustomEvent): Promise<void> {
if (this._dirty) {
const confirm = await showConfirmationDialog(this, {
text: this.supervisor.localize("dialog.network.unsaved"),
confirmText: this.supervisor.localize("common.yes"),
dismissText: this.supervisor.localize("common.no"),
text:
"You have unsaved changes, these will get lost if you change tabs, do you want to continue?",
confirmText: "yes",
dismissText: "no",
});
if (!confirm) {
this.requestUpdate("_interface");
@@ -1,9 +1,9 @@
import { fireEvent } from "../../../../src/common/dom/fire_event";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { NetworkInfo } from "../../../../src/data/hassio/network";
import "./dialog-hassio-network";
export interface HassioNetworkDialogParams {
supervisor: Supervisor;
network: NetworkInfo;
loadData: () => Promise<void>;
}
@@ -22,18 +22,14 @@ import {
fetchHassioDockerRegistries,
removeHassioDockerRegistry,
} from "../../../../src/data/hassio/docker";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { showAlertDialog } from "../../../../src/dialogs/generic/show-dialog-box";
import { haStyle, haStyleDialog } from "../../../../src/resources/styles";
import type { HomeAssistant } from "../../../../src/types";
import { RegistriesDialogParams } from "./show-dialog-registries";
@customElement("dialog-hassio-registries")
class HassioRegistriesDialog extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) private _registries?: {
registry: string;
username: string;
@@ -59,8 +55,8 @@ class HassioRegistriesDialog extends LitElement {
.heading=${createCloseHeading(
this.hass,
this._addingRegistry
? this.supervisor.localize("dialog.registries.title_add")
: this.supervisor.localize("dialog.registries.title_manage")
? "Add New Docker Registry"
: "Manage Docker Registries"
)}
>
<div class="form">
@@ -70,9 +66,7 @@ class HassioRegistriesDialog extends LitElement {
@value-changed=${this._inputChanged}
class="flex-auto"
name="registry"
.label=${this.supervisor.localize(
"dialog.registries.registry"
)}
label="Registry"
required
auto-validate
></paper-input>
@@ -80,9 +74,7 @@ class HassioRegistriesDialog extends LitElement {
@value-changed=${this._inputChanged}
class="flex-auto"
name="username"
.label=${this.supervisor.localize(
"dialog.registries.username"
)}
label="Username"
required
auto-validate
></paper-input>
@@ -90,9 +82,7 @@ class HassioRegistriesDialog extends LitElement {
@value-changed=${this._inputChanged}
class="flex-auto"
name="password"
.label=${this.supervisor.localize(
"dialog.registries.password"
)}
label="Password"
type="password"
required
auto-validate
@@ -104,7 +94,7 @@ class HassioRegistriesDialog extends LitElement {
)}
@click=${this._addNewRegistry}
>
${this.supervisor.localize("dialog.registries.add_registry")}
Add registry
</mwc-button>
`
: html`${this._registries?.length
@@ -113,16 +103,11 @@ class HassioRegistriesDialog extends LitElement {
<mwc-list-item class="option" hasMeta twoline>
<span>${entry.registry}</span>
<span slot="secondary"
>${this.supervisor.localize(
"dialog.registries.username"
)}:
${entry.username}</span
>Username: ${entry.username}</span
>
<mwc-icon-button
.entry=${entry}
.title=${this.supervisor.localize(
"dialog.registries.remove"
)}
title="Remove"
slot="meta"
@click=${this._removeRegistry}
>
@@ -133,17 +118,11 @@ class HassioRegistriesDialog extends LitElement {
})
: html`
<mwc-list-item>
<span
>${this.supervisor.localize(
"dialog.registries.no_registries"
)}</span
>
<span>No registries configured</span>
</mwc-list-item>
`}
<mwc-button @click=${this._addRegistry}>
${this.supervisor.localize(
"dialog.registries.add_new_registry"
)}
Add new registry
</mwc-button> `}
</div>
</ha-dialog>
@@ -155,9 +134,8 @@ class HassioRegistriesDialog extends LitElement {
this[`_${target.name}`] = target.value;
}
public async showDialog(dialogParams: RegistriesDialogParams): Promise<void> {
public async showDialog(_dialogParams: any): Promise<void> {
this._opened = true;
this.supervisor = dialogParams.supervisor;
await this._loadRegistries();
await this.updateComplete;
}
@@ -200,7 +178,7 @@ class HassioRegistriesDialog extends LitElement {
this._addingRegistry = false;
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize("dialog.registries.failed_to_add"),
title: "Failed to add registry",
text: extractApiErrorMessage(err),
});
}
@@ -214,7 +192,7 @@ class HassioRegistriesDialog extends LitElement {
await this._loadRegistries();
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize("dialog.registries.failed_to_remove"),
title: "Failed to remove registry",
text: extractApiErrorMessage(err),
});
}
@@ -1,18 +1,10 @@
import { fireEvent } from "../../../../src/common/dom/fire_event";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import "./dialog-hassio-registries";
export interface RegistriesDialogParams {
supervisor: Supervisor;
}
export const showRegistriesDialog = (
element: HTMLElement,
dialogParams: RegistriesDialogParams
): void => {
export const showRegistriesDialog = (element: HTMLElement): void => {
fireEvent(element, "show-dialog", {
dialogTag: "dialog-hassio-registries",
dialogImport: () => import("./dialog-hassio-registries"),
dialogParams,
dialogParams: {},
});
};
@@ -18,7 +18,7 @@ import {
} from "lit-element";
import memoizeOne from "memoize-one";
import "../../../../src/components/ha-circular-progress";
import { createCloseHeading } from "../../../../src/components/ha-dialog";
import "../../../../src/components/ha-dialog";
import "../../../../src/components/ha-svg-icon";
import {
fetchHassioAddonsInfo,
@@ -26,7 +26,6 @@ import {
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { setSupervisorOption } from "../../../../src/data/hassio/supervisor";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { haStyle, haStyleDialog } from "../../../../src/resources/styles";
import type { HomeAssistant } from "../../../../src/types";
import { HassioRepositoryDialogParams } from "./show-dialog-repositories";
@@ -35,8 +34,6 @@ import { HassioRepositoryDialogParams } from "./show-dialog-repositories";
class HassioRepositoriesDialog extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) private _repos: HassioAddonRepository[] = [];
@property({ attribute: false })
@@ -50,11 +47,9 @@ class HassioRepositoriesDialog extends LitElement {
@internalProperty() private _error?: string;
public async showDialog(
dialogParams: HassioRepositoryDialogParams
): Promise<void> {
this._dialogParams = dialogParams;
this.supervisor = dialogParams.supervisor;
public async showDialog(_dialogParams: any): Promise<void> {
this._dialogParams = _dialogParams;
this._repos = _dialogParams.repos;
this._opened = true;
await this.updateComplete;
}
@@ -71,19 +66,14 @@ class HassioRepositoriesDialog extends LitElement {
);
protected render(): TemplateResult {
const repositories = this._filteredRepositories(
this.supervisor.addon.repositories
);
const repositories = this._filteredRepositories(this._repos);
return html`
<ha-dialog
.open=${this._opened}
@closing=${this.closeDialog}
scrimClickAction
escapeKeyAction
.heading=${createCloseHeading(
this.hass,
this.supervisor.localize("dialog.repositories.title")
)}
heading="Manage add-on repositories"
>
${this._error ? html`<div class="error">${this._error}</div>` : ""}
<div class="form">
@@ -98,9 +88,7 @@ class HassioRepositoriesDialog extends LitElement {
</paper-item-body>
<mwc-icon-button
.slug=${repo.slug}
.title=${this.supervisor.localize(
"dialog.repositories.remove"
)}
title="Remove"
@click=${this._removeRepository}
>
<ha-svg-icon .path=${mdiDelete}></ha-svg-icon>
@@ -117,13 +105,13 @@ class HassioRepositoriesDialog extends LitElement {
<paper-input
class="flex-auto"
id="repository_input"
.label=${this.supervisor.localize("dialog.repositories.add")}
label="Add repository"
@keydown=${this._handleKeyAdd}
></paper-input>
<mwc-button @click=${this._addRepository}>
${this._prosessing
? html`<ha-circular-progress active></ha-circular-progress>`
: this.supervisor.localize("dialog.repositories.add")}
: "Add"}
</mwc-button>
</div>
</div>
@@ -1,9 +1,9 @@
import { fireEvent } from "../../../../src/common/dom/fire_event";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { HassioAddonRepository } from "../../../../src/data/hassio/addon";
import "./dialog-hassio-repositories";
export interface HassioRepositoryDialogParams {
supervisor: Supervisor;
repos: HassioAddonRepository[];
loadData: () => Promise<void>;
}
+5 -11
View File
@@ -4,7 +4,6 @@ import {
restartHassioAddon,
} from "../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import {
showAlertDialog,
showConfirmationDialog,
@@ -14,25 +13,20 @@ import { HomeAssistant } from "../../../src/types";
export const suggestAddonRestart = async (
element: LitElement,
hass: HomeAssistant,
supervisor: Supervisor,
addon: HassioAddonDetails
): Promise<void> => {
const confirmed = await showConfirmationDialog(element, {
title: supervisor.localize("common.restart_name", "name", addon.name),
text: supervisor.localize("dialog.restart_addon.text"),
confirmText: supervisor.localize("dialog.restart_addon.confirm_text"),
dismissText: supervisor.localize("common.cancel"),
title: addon.name,
text: "Do you want to restart the add-on with your changes?",
confirmText: "restart add-on",
dismissText: "no",
});
if (confirmed) {
try {
await restartHassioAddon(hass, addon.slug);
} catch (err) {
showAlertDialog(element, {
title: supervisor.localize(
"common.failed_to_restart_name",
"name",
addon.name
),
title: "Failed to restart",
text: extractApiErrorMessage(err),
});
}
@@ -1,21 +0,0 @@
import { fireEvent } from "../../../../src/common/dom/fire_event";
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
export interface SupervisorDialogSupervisorUpdateParams {
supervisor: Supervisor;
name: string;
version: string;
snapshotParams: any;
updateHandler: () => Promise<void>;
}
export const showDialogSupervisorUpdate = (
element: HTMLElement,
dialogParams: SupervisorDialogSupervisorUpdateParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "dialog-supervisor-update",
dialogImport: () => import("./dialog-supervisor-update"),
dialogParams,
});
};
+13 -3
View File
@@ -3,7 +3,7 @@ import { atLeastVersion } from "../../src/common/config/version";
import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element";
import { fireEvent } from "../../src/common/dom/fire_event";
import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
import { Supervisor } from "../../src/data/supervisor/supervisor";
import { supervisorCollection } from "../../src/data/supervisor/supervisor";
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
import "../../src/layouts/hass-loading-screen";
import { HomeAssistant, Route } from "../../src/types";
@@ -14,8 +14,6 @@ import { SupervisorBaseElement } from "./supervisor-base-element";
export class HassioMain extends SupervisorBaseElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public panel!: HassioPanelInfo;
@property({ type: Boolean }) public narrow!: boolean;
@@ -74,6 +72,18 @@ export class HassioMain extends SupervisorBaseElement {
}
protected render() {
if (!this.supervisor || !this.hass) {
return html`<hass-loading-screen></hass-loading-screen>`;
}
if (
Object.keys(supervisorCollection).some(
(colllection) => !this.supervisor![colllection]
)
) {
return html`<hass-loading-screen></hass-loading-screen>`;
}
return html`
<hassio-router
.hass=${this.hass}
+7 -12
View File
@@ -19,7 +19,6 @@ import {
} from "../../src/panels/my/ha-panel-my";
import { navigate } from "../../src/common/navigate";
import { HomeAssistant, Route } from "../../src/types";
import { Supervisor } from "../../src/data/supervisor/supervisor";
const REDIRECTS: Redirects = {
supervisor_logs: {
@@ -49,9 +48,7 @@ const REDIRECTS: Redirects = {
class HassioMyRedirect extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public route!: Route;
@property() public route!: Route;
@internalProperty() public _error?: TemplateResult | string;
@@ -61,17 +58,15 @@ class HassioMyRedirect extends LitElement {
const redirect = REDIRECTS[path];
if (!redirect) {
this._error = this.supervisor.localize(
"my.not_supported",
"link",
html`<a
this._error = html`This redirect is not supported by your Home Assistant
instance. Check the
<a
target="_blank"
rel="noreferrer noopener"
href="https://my.home-assistant.io/faq.html#supported-pages"
>My Home Assistant FAQ</a
>
${this.supervisor.localize("my.faq_link")}
</a>`
);
for the supported redirects and the version they where introduced.`;
return;
}
@@ -79,7 +74,7 @@ class HassioMyRedirect extends LitElement {
try {
url = this._createRedirectUrl(redirect);
} catch (err) {
this._error = this.supervisor.localize("my.error");
this._error = "An unknown error occured";
return;
}
+1 -15
View File
@@ -7,10 +7,7 @@ import {
property,
TemplateResult,
} from "lit-element";
import {
Supervisor,
supervisorCollection,
} from "../../src/data/supervisor/supervisor";
import { Supervisor } from "../../src/data/supervisor/supervisor";
import { HomeAssistant, Route } from "../../src/types";
import "./hassio-panel-router";
@@ -25,17 +22,6 @@ class HassioPanel extends LitElement {
@property({ attribute: false }) public route!: Route;
protected render(): TemplateResult {
if (!this.hass) {
return html`<hass-loading-screen></hass-loading-screen>`;
}
if (
Object.keys(supervisorCollection).some(
(colllection) => !this.supervisor[colllection]
)
) {
return html`<hass-loading-screen></hass-loading-screen>`;
}
return html`
<hassio-panel-router
.hass=${this.hass}
+4 -4
View File
@@ -3,22 +3,22 @@ import type { PageNavigation } from "../../src/layouts/hass-tabs-subpage";
export const supervisorTabs: PageNavigation[] = [
{
translationKey: "panel.dashboard",
name: "Dashboard",
path: `/hassio/dashboard`,
iconPath: mdiViewDashboard,
},
{
translationKey: "panel.store",
name: "Add-on Store",
path: `/hassio/store`,
iconPath: mdiStore,
},
{
translationKey: "panel.snapshots",
name: "Snapshots",
path: `/hassio/snapshots`,
iconPath: mdiBackupRestore,
},
{
translationKey: "panel.system",
name: "System",
path: `/hassio/system`,
iconPath: mdiCogs,
},
+34 -48
View File
@@ -55,8 +55,8 @@ import { hassioStyle } from "../resources/hassio-style";
interface CheckboxItem {
slug: string;
name: string;
checked: boolean;
name?: string;
}
@customElement("hassio-snapshots")
@@ -84,12 +84,13 @@ class HassioSnapshots extends LitElement {
@internalProperty() private _folderList: CheckboxItem[] = [
{
slug: "homeassistant",
name: "Home Assistant configuration",
checked: true,
},
{ slug: "ssl", checked: true },
{ slug: "share", checked: true },
{ slug: "media", checked: true },
{ slug: "addons/local", checked: true },
{ slug: "ssl", name: "SSL", checked: true },
{ slug: "share", name: "Share", checked: true },
{ slug: "media", name: "Media", checked: true },
{ slug: "addons/local", name: "Local add-ons", checked: true },
];
@internalProperty() private _error = "";
@@ -103,16 +104,13 @@ class HassioSnapshots extends LitElement {
return html`
<hass-tabs-subpage
.hass=${this.hass}
.localizeFunc=${this.supervisor.localize}
.narrow=${this.narrow}
hassio
main-page
.route=${this.route}
.tabs=${supervisorTabs}
main-page
supervisor
>
<span slot="header">
${this.supervisor.localize("panel.snapshots")}
</span>
<span slot="header">Snapshots</span>
<ha-button-menu
corner="BOTTOM_START"
slot="toolbar-icon"
@@ -122,50 +120,50 @@ class HassioSnapshots extends LitElement {
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item>
${this.supervisor.localize("common.reload")}
Reload
</mwc-list-item>
${atLeastVersion(this.hass.config.version, 0, 116)
? html`<mwc-list-item>
${this.supervisor.localize("snapshot.upload_snapshot")}
Upload snapshot
</mwc-list-item>`
: ""}
</ha-button-menu>
<div class="content">
<h1>
${this.supervisor.localize("snapshot.create_snapshot")}
Create Snapshot
</h1>
<p class="description">
${this.supervisor.localize("snapshot.description")}
Snapshots allow you to easily backup and restore all data of your
Home Assistant instance.
</p>
<div class="card-group">
<ha-card>
<div class="card-content">
<paper-input
autofocus
.label=${this.supervisor.localize("snapshot.name")}
label="Name"
name="snapshotName"
.value=${this._snapshotName}
@value-changed=${this._handleTextValueChanged}
></paper-input>
${this.supervisor.localize("snapshot.type")}:
Type:
<paper-radio-group
name="snapshotType"
type="${this.supervisor.localize("snapshot.type")}"
.selected=${this._snapshotType}
@selected-changed=${this._handleRadioValueChanged}
>
<paper-radio-button name="full">
${this.supervisor.localize("snapshot.full_snapshot")}
Full snapshot
</paper-radio-button>
<paper-radio-button name="partial">
${this.supervisor.localize("snapshot.partial_snapshot")}
Partial snapshot
</paper-radio-button>
</paper-radio-group>
${this._snapshotType === "full"
? undefined
: html`
${this.supervisor.localize("snapshot.folders")}:
Folders:
${this._folderList.map(
(folder, idx) => html`
<paper-checkbox
@@ -173,13 +171,11 @@ class HassioSnapshots extends LitElement {
.checked=${folder.checked}
@checked-changed=${this._folderChecked}
>
${this.supervisor.localize(
`snapshot.folder.${folder.slug}`
)}
${folder.name}
</paper-checkbox>
`
)}
${this.supervisor.localize("snapshot.addons")}:
Add-ons:
${this._addonList.map(
(addon, idx) => html`
<paper-checkbox
@@ -192,18 +188,18 @@ class HassioSnapshots extends LitElement {
`
)}
`}
${this.supervisor.localize("snapshot.security")}:
Security:
<paper-checkbox
name="snapshotHasPassword"
.checked=${this._snapshotHasPassword}
@checked-changed=${this._handleCheckboxValueChanged}
>
${this.supervisor.localize("snapshot.password_protection")}
Password protection
</paper-checkbox>
${this._snapshotHasPassword
? html`
<paper-input
.label=${this.supervisor.localize("snapshot.password")}
label="Password"
type="password"
name="snapshotPassword"
.value=${this._snapshotPassword}
@@ -218,22 +214,18 @@ class HassioSnapshots extends LitElement {
<div class="card-actions">
<ha-progress-button
@click=${this._createSnapshot}
.title=${this.supervisor.info.state !== "running"
? this.supervisor.localize(
"snapshot.create_blocked_not_running",
"state",
this.supervisor.info.state
)
: ""}
title="${this.supervisor.info.state !== "running"
? `Creating a snapshot is not possible right now because the system is in ${this.supervisor.info.state} state.`
: ""}"
.disabled=${this.supervisor.info.state !== "running"}
>
${this.supervisor.localize("snapshot.create")}
Create
</ha-progress-button>
</div>
</ha-card>
</div>
<h1>${this.supervisor.localize("snapshot.available_snapshots")}</h1>
<h1>Available Snapshots</h1>
<div class="card-group">
${this._snapshots === undefined
? undefined
@@ -241,7 +233,7 @@ class HassioSnapshots extends LitElement {
? html`
<ha-card>
<div class="card-content">
${this.supervisor.localize("snapshot.no_snapshots")}
You don't have any snapshots yet.
</div>
</ha-card>
`
@@ -342,12 +334,8 @@ class HassioSnapshots extends LitElement {
private async _createSnapshot(ev: CustomEvent): Promise<void> {
if (this.supervisor.info.state !== "running") {
await showAlertDialog(this, {
title: this.supervisor.localize("snapshot.could_not_create"),
text: this.supervisor.localize(
"snapshot.create_blocked_not_running",
"state",
this.supervisor.info.state
),
title: "Could not create snapshot",
text: `Creating a snapshot is not possible right now because the system is in ${this.supervisor.info.state} state.`,
});
}
const button = ev.currentTarget as any;
@@ -355,7 +343,7 @@ class HassioSnapshots extends LitElement {
this._error = "";
if (this._snapshotHasPassword && !this._snapshotPassword.length) {
this._error = this.supervisor.localize("snapshot.enter_password");
this._error = "Please enter a password.";
button.progress = false;
return;
}
@@ -404,9 +392,7 @@ class HassioSnapshots extends LitElement {
private _computeDetails(snapshot: HassioSnapshot) {
const type =
snapshot.type === "full"
? this.supervisor.localize("snapshot.full_snapshot")
: this.supervisor.localize("snapshot.partial_snapshot");
snapshot.type === "full" ? "Full snapshot" : "Partial snapshot";
return snapshot.protected ? `${type}, password protected` : type;
}
+46 -96
View File
@@ -6,7 +6,6 @@ import {
PropertyValues,
} from "lit-element";
import { atLeastVersion } from "../../src/common/config/version";
import { computeLocalize } from "../../src/common/translations/localize";
import { fetchHassioAddonsInfo } from "../../src/data/hassio/addon";
import { HassioResponse } from "../../src/data/hassio/common";
import {
@@ -30,7 +29,6 @@ import {
} from "../../src/data/supervisor/supervisor";
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
import { urlSyncMixin } from "../../src/state/url-sync-mixin";
import { getTranslation } from "../../src/util/common-translation";
declare global {
interface HASSDomEvents {
@@ -42,9 +40,7 @@ declare global {
export class SupervisorBaseElement extends urlSyncMixin(
ProvideHassLitMixin(LitElement)
) {
@property({ attribute: false }) public supervisor: Partial<Supervisor> = {
localize: () => "",
};
@property({ attribute: false }) public supervisor?: Supervisor;
@internalProperty() private _unsubs: Record<string, UnsubscribeFunc> = {};
@@ -53,15 +49,6 @@ export class SupervisorBaseElement extends urlSyncMixin(
Collection<unknown>
> = {};
@internalProperty() private _resources?: Record<string, any>;
@internalProperty() private _language = "en";
public connectedCallback(): void {
super.connectedCallback();
this._initializeLocalize();
}
public disconnectedCallback() {
super.disconnectedCallback();
Object.keys(this._unsubs).forEach((unsub) => {
@@ -69,50 +56,15 @@ export class SupervisorBaseElement extends urlSyncMixin(
});
}
protected updated(changedProperties: PropertyValues) {
super.updated(changedProperties);
if (changedProperties.has("_language")) {
if (changedProperties.get("_language") !== this._language) {
this._initializeLocalize();
}
}
}
protected _updateSupervisor(obj: Partial<Supervisor>): void {
this.supervisor = { ...this.supervisor, ...obj };
this.supervisor = { ...this.supervisor!, ...obj };
}
protected firstUpdated(changedProps: PropertyValues): void {
super.firstUpdated(changedProps);
if (this._language !== this.hass.language) {
this._language = this.hass.language;
}
this._initializeLocalize();
this._initSupervisor();
}
private async _initializeLocalize() {
const { language, data } = await getTranslation(
null,
this._language,
"/api/hassio/app/static/translations"
);
this._resources = {
[language]: data,
};
this.supervisor = {
...this.supervisor,
localize: await computeLocalize(
this.constructor.prototype,
this._language,
this._resources
),
};
}
private async _handleSupervisorStoreRefreshEvent(ev) {
const colllection = ev.detail.colllection;
if (atLeastVersion(this.hass.config.version, 2021, 2, 4)) {
@@ -152,54 +104,52 @@ export class SupervisorBaseElement extends urlSyncMixin(
}
});
Object.keys(this._collections).forEach((collection) => {
if (
this.supervisor === undefined ||
this.supervisor[collection] === undefined
) {
if (this.supervisor === undefined) {
Object.keys(this._collections).forEach((collection) =>
this._updateSupervisor({
[collection]: this._collections[collection].state,
});
}
});
} else {
const [
addon,
supervisor,
host,
core,
info,
os,
network,
resolution,
store,
] = await Promise.all([
fetchHassioAddonsInfo(this.hass),
fetchHassioSupervisorInfo(this.hass),
fetchHassioHostInfo(this.hass),
fetchHassioHomeAssistantInfo(this.hass),
fetchHassioInfo(this.hass),
fetchHassioHassOsInfo(this.hass),
fetchNetworkInfo(this.hass),
fetchHassioResolution(this.hass),
fetchSupervisorStore(this.hass),
]);
this._updateSupervisor({
addon,
supervisor,
host,
core,
info,
os,
network,
resolution,
store,
});
this.addEventListener("supervisor-update", (ev) =>
this._updateSupervisor(ev.detail)
);
})
);
}
return;
}
const [
addon,
supervisor,
host,
core,
info,
os,
network,
resolution,
store,
] = await Promise.all([
fetchHassioAddonsInfo(this.hass),
fetchHassioSupervisorInfo(this.hass),
fetchHassioHostInfo(this.hass),
fetchHassioHomeAssistantInfo(this.hass),
fetchHassioInfo(this.hass),
fetchHassioHassOsInfo(this.hass),
fetchNetworkInfo(this.hass),
fetchHassioResolution(this.hass),
fetchSupervisorStore(this.hass),
]);
this.supervisor = {
addon,
supervisor,
host,
core,
info,
os,
network,
resolution,
store,
};
this.addEventListener("supervisor-update", (ev) =>
this._updateSupervisor(ev.detail)
);
}
}
+16 -50
View File
@@ -10,7 +10,6 @@ import {
property,
TemplateResult,
} from "lit-element";
import { fireEvent } from "../../../src/common/dom/fire_event";
import "../../../src/components/buttons/ha-progress-button";
import "../../../src/components/ha-button-menu";
import "../../../src/components/ha-card";
@@ -20,7 +19,7 @@ import {
fetchHassioStats,
HassioStats,
} from "../../../src/data/hassio/common";
import { restartCore, updateCore } from "../../../src/data/supervisor/core";
import { restartCore } from "../../../src/data/supervisor/core";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import {
showAlertDialog,
@@ -30,7 +29,7 @@ import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types";
import { bytesToString } from "../../../src/util/bytes-to-string";
import "../components/supervisor-metric";
import { showDialogSupervisorUpdate } from "../dialogs/update/show-dialog-update";
import { showDialogSupervisorCoreUpdate } from "../dialogs/core/show-dialog-core-update";
import { hassioStyle } from "../resources/hassio-style";
@customElement("hassio-core-info")
@@ -44,11 +43,11 @@ class HassioCoreInfo extends LitElement {
protected render(): TemplateResult | void {
const metrics = [
{
description: this.supervisor.localize("system.core.cpu_usage"),
description: "Core CPU Usage",
value: this._metrics?.cpu_percent,
},
{
description: this.supervisor.localize("system.core.ram_usage"),
description: "Core RAM Usage",
value: this._metrics?.memory_percent,
tooltip: `${bytesToString(this._metrics?.memory_usage)}/${bytesToString(
this._metrics?.memory_limit
@@ -62,7 +61,7 @@ class HassioCoreInfo extends LitElement {
<div>
<ha-settings-row>
<span slot="heading">
${this.supervisor.localize("common.version")}
Version
</span>
<span slot="description">
core-${this.supervisor.core.version}
@@ -70,7 +69,7 @@ class HassioCoreInfo extends LitElement {
</ha-settings-row>
<ha-settings-row>
<span slot="heading">
${this.supervisor.localize("common.newest_version")}
Newest Version
</span>
<span slot="description">
core-${this.supervisor.core.version_latest}
@@ -78,10 +77,10 @@ class HassioCoreInfo extends LitElement {
${this.supervisor.core.update_available
? html`
<ha-progress-button
.title=${this.supervisor.localize("common.update")}
title="Update the core"
@click=${this._coreUpdate}
>
${this.supervisor.localize("common.update")}
Update
</ha-progress-button>
`
: ""}
@@ -105,13 +104,9 @@ class HassioCoreInfo extends LitElement {
slot="primaryAction"
class="warning"
@click=${this._coreRestart}
.title=${this.supervisor.localize(
"common.restart_name",
"name",
"Core"
)}
title="Restart Home Assistant Core"
>
${this.supervisor.localize("common.restart_name", "name", "Core")}
Restart Core
</ha-progress-button>
</div>
</ha-card>
@@ -131,18 +126,10 @@ class HassioCoreInfo extends LitElement {
button.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize(
"confirm.restart.title",
"name",
"Home Assistant Core"
),
text: this.supervisor.localize(
"confirm.restart.text",
"name",
"Home Assistant Core"
),
confirmText: this.supervisor.localize("common.restart"),
dismissText: this.supervisor.localize("common.cancel"),
title: "Restart Home Assistant Core",
text: "Are you sure you want to restart Home Assistant Core",
confirmText: "restart",
dismissText: "cancel",
});
if (!confirmed) {
@@ -155,11 +142,7 @@ class HassioCoreInfo extends LitElement {
} catch (err) {
if (this.hass.connection.connected) {
showAlertDialog(this, {
title: this.supervisor.localize(
"common.failed_to_restart_name",
"name",
"Home AssistantCore"
),
title: "Failed to restart Home Assistant Core",
text: extractApiErrorMessage(err),
});
}
@@ -169,24 +152,7 @@ class HassioCoreInfo extends LitElement {
}
private async _coreUpdate(): Promise<void> {
showDialogSupervisorUpdate(this, {
supervisor: this.supervisor,
name: "Home Assistant Core",
version: this.supervisor.core.version,
snapshotParams: {
name: `core_${this.supervisor.core.version}`,
folders: ["homeassistant"],
homeassistant: true,
},
updateHandler: async () => await this._updateCore(),
});
}
private async _updateCore(): Promise<void> {
await updateCore(this.hass);
fireEvent(this, "supervisor-colllection-refresh", {
colllection: "core",
});
showDialogSupervisorCoreUpdate(this, { supervisor: this.supervisor });
}
static get styles(): CSSResult[] {
+51 -60
View File
@@ -65,7 +65,7 @@ class HassioHostInfo extends LitElement {
const metrics = [
{
description: this.supervisor.localize("system.host.used_space"),
description: "Used Space",
value: this._getUsedSpace(
this.supervisor.host.disk_used,
this.supervisor.host.disk_total
@@ -80,13 +80,14 @@ class HassioHostInfo extends LitElement {
${this.supervisor.host.features.includes("hostname")
? html`<ha-settings-row>
<span slot="heading">
${this.supervisor.localize("system.host.hostname")}
Hostname
</span>
<span slot="description">
${this.supervisor.host.hostname}
</span>
<mwc-button
.label=${this.supervisor.localize("system.host.change")}
title="Change the hostname"
label="Change"
@click=${this._changeHostnameClicked}
>
</mwc-button>
@@ -95,13 +96,14 @@ class HassioHostInfo extends LitElement {
${this.supervisor.host.features.includes("network")
? html` <ha-settings-row>
<span slot="heading">
${this.supervisor.localize("system.host.ip_address")}
IP Address
</span>
<span slot="description">
${primaryIpAddress}
</span>
<mwc-button
.label=${this.supervisor.localize("system.host.change")}
title="Change the network"
label="Change"
@click=${this._changeNetworkClicked}
>
</mwc-button>
@@ -110,15 +112,18 @@ class HassioHostInfo extends LitElement {
<ha-settings-row>
<span slot="heading">
${this.supervisor.localize("system.host.operating_system")}
Operating System
</span>
<span slot="description">
${this.supervisor.host.operating_system}
</span>
${this.supervisor.os.update_available
? html`
<ha-progress-button @click=${this._osUpdate}>
${this.supervisor.localize("commmon.update")}
<ha-progress-button
title="Update the host OS"
@click=${this._osUpdate}
>
Update
</ha-progress-button>
`
: ""}
@@ -126,7 +131,7 @@ class HassioHostInfo extends LitElement {
${!this.supervisor.host.features.includes("hassos")
? html`<ha-settings-row>
<span slot="heading">
${this.supervisor.localize("system.host.docker_version")}
Docker version
</span>
<span slot="description">
${this.supervisor.info.docker}
@@ -136,7 +141,7 @@ class HassioHostInfo extends LitElement {
${this.supervisor.host.deployment
? html`<ha-settings-row>
<span slot="heading">
${this.supervisor.localize("system.host.deployment")}
Deployment
</span>
<span slot="description">
${this.supervisor.host.deployment}
@@ -149,9 +154,7 @@ class HassioHostInfo extends LitElement {
this.supervisor.host.disk_life_time >= 10
? html` <ha-settings-row>
<span slot="heading">
${this.supervisor.localize(
"system.host.emmc_lifetime_used"
)}
eMMC Lifetime Used
</span>
<span slot="description">
${this.supervisor.host.disk_life_time - 10}% -
@@ -174,18 +177,23 @@ class HassioHostInfo extends LitElement {
<div class="card-actions">
${this.supervisor.host.features.includes("reboot")
? html`
<ha-progress-button class="warning" @click=${this._hostReboot}>
${this.supervisor.localize("system.host.reboot_host")}
<ha-progress-button
title="Reboot the host OS"
class="warning"
@click=${this._hostReboot}
>
Reboot Host
</ha-progress-button>
`
: ""}
${this.supervisor.host.features.includes("shutdown")
? html`
<ha-progress-button
title="Shutdown the host OS"
class="warning"
@click=${this._hostShutdown}
>
${this.supervisor.localize("system.host.shutdown_host")}
Shutdown Host
</ha-progress-button>
`
: ""}
@@ -197,12 +205,14 @@ class HassioHostInfo extends LitElement {
<mwc-icon-button slot="trigger">
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item>
${this.supervisor.localize("system.host.hardware")}
<mwc-list-item title="Show a list of hardware">
Hardware
</mwc-list-item>
${this.supervisor.host.features.includes("hassos")
? html`<mwc-list-item>
${this.supervisor.localize("system.host.import_from_usb")}
? html`<mwc-list-item
title="Load HassOS configs or updates from USB"
>
Import from USB
</mwc-list-item>`
: ""}
</ha-button-menu>
@@ -241,14 +251,12 @@ class HassioHostInfo extends LitElement {
try {
const content = await fetchHassioHardwareInfo(this.hass);
showHassioMarkdownDialog(this, {
title: this.supervisor.localize("system.host.hardware"),
title: "Hardware",
content: `<pre>${safeDump(content, { indent: 2 })}</pre>`,
});
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize(
"system.host.failed_to_get_hardware_list"
),
title: "Failed to get hardware list",
text: extractApiErrorMessage(err),
});
}
@@ -259,10 +267,10 @@ class HassioHostInfo extends LitElement {
button.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize("system.host.reboot_host"),
text: this.supervisor.localize("system.host.confirm_reboot"),
confirmText: this.supervisor.localize("system.host.reboot_host"),
dismissText: this.supervisor.localize("common.cancel"),
title: "Reboot",
text: "Are you sure you want to reboot the host?",
confirmText: "reboot host",
dismissText: "no",
});
if (!confirmed) {
@@ -276,7 +284,7 @@ class HassioHostInfo extends LitElement {
// Ignore connection errors, these are all expected
if (err.status_code && !ignoredStatusCodes.has(err.status_code)) {
showAlertDialog(this, {
title: this.supervisor.localize("system.host.failed_to_reboot"),
title: "Failed to reboot",
text: extractApiErrorMessage(err),
});
}
@@ -289,10 +297,10 @@ class HassioHostInfo extends LitElement {
button.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize("system.host.shutdown_host"),
text: this.supervisor.localize("system.host.confirm_shutdown"),
confirmText: this.supervisor.localize("system.host.shutdown_host"),
dismissText: this.supervisor.localize("common.cancel"),
title: "Shutdown",
text: "Are you sure you want to shutdown the host?",
confirmText: "shutdown host",
dismissText: "no",
});
if (!confirmed) {
@@ -306,7 +314,7 @@ class HassioHostInfo extends LitElement {
// Ignore connection errors, these are all expected
if (err.status_code && !ignoredStatusCodes.has(err.status_code)) {
showAlertDialog(this, {
title: this.supervisor.localize("system.host.failed_to_shutdown"),
title: "Failed to shutdown",
text: extractApiErrorMessage(err),
});
}
@@ -319,19 +327,9 @@ class HassioHostInfo extends LitElement {
button.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize(
"confirm.update.title",
"name",
"Home Assistant Operating System"
),
text: this.supervisor.localize(
"confirm.update.text",
"name",
"Home Assistant Operating System",
"version",
this.supervisor.os.version_latest
),
confirmText: this.supervisor.localize("common.update"),
title: "Update",
text: "Are you sure you want to update the OS?",
confirmText: "update os",
dismissText: "no",
});
@@ -346,11 +344,7 @@ class HassioHostInfo extends LitElement {
} catch (err) {
if (this.hass.connection.connected) {
showAlertDialog(this, {
title: this.supervisor.localize(
"common.failed_to_update_name",
"name",
"Home Assistant Operating System"
),
title: "Failed to update",
text: extractApiErrorMessage(err),
});
}
@@ -360,7 +354,7 @@ class HassioHostInfo extends LitElement {
private async _changeNetworkClicked(): Promise<void> {
showNetworkDialog(this, {
supervisor: this.supervisor,
network: this.supervisor.network!,
loadData: () => this._loadData(),
});
}
@@ -368,11 +362,10 @@ class HassioHostInfo extends LitElement {
private async _changeHostnameClicked(): Promise<void> {
const curHostname: string = this.supervisor.host.hostname;
const hostname = await showPromptDialog(this, {
title: this.supervisor.localize("system.host.change_hostname"),
inputLabel: this.supervisor.localize("system.host.new_hostname"),
title: "Change Hostname",
inputLabel: "Please enter a new hostname:",
inputType: "string",
defaultValue: curHostname,
confirmText: this.supervisor.localize("common.update"),
});
if (hostname && hostname !== curHostname) {
@@ -383,7 +376,7 @@ class HassioHostInfo extends LitElement {
});
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize("system.host.failed_to_set_hostname"),
title: "Setting hostname failed",
text: extractApiErrorMessage(err),
});
}
@@ -398,9 +391,7 @@ class HassioHostInfo extends LitElement {
});
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize(
"system.host.failed_to_import_from_usb"
),
title: "Failed to import from USB",
text: extractApiErrorMessage(err),
});
}
+118 -145
View File
@@ -37,24 +37,54 @@ import { documentationUrl } from "../../../src/util/documentation-url";
import "../components/supervisor-metric";
import { hassioStyle } from "../resources/hassio-style";
const UNSUPPORTED_REASON_URL = {
container: "/more-info/unsupported/container",
dbus: "/more-info/unsupported/dbus",
docker_configuration: "/more-info/unsupported/docker_configuration",
docker_version: "/more-info/unsupported/docker_version",
job_conditions: "/more-info/unsupported/job_conditions",
lxc: "/more-info/unsupported/lxc",
network_manager: "/more-info/unsupported/network_manager",
os: "/more-info/unsupported/os",
privileged: "/more-info/unsupported/privileged",
systemd: "/more-info/unsupported/systemd",
const UNSUPPORTED_REASON = {
container: {
title: "Containers known to cause issues",
url: "/more-info/unsupported/container",
},
dbus: { title: "DBUS", url: "/more-info/unsupported/dbus" },
docker_configuration: {
title: "Docker Configuration",
url: "/more-info/unsupported/docker_configuration",
},
docker_version: {
title: "Docker Version",
url: "/more-info/unsupported/docker_version",
},
job_conditions: {
title: "Ignored job conditions",
url: "/more-info/unsupported/job_conditions",
},
lxc: { title: "LXC", url: "/more-info/unsupported/lxc" },
network_manager: {
title: "Network Manager",
url: "/more-info/unsupported/network_manager",
},
os: { title: "Operating System", url: "/more-info/unsupported/os" },
privileged: {
title: "Supervisor is not privileged",
url: "/more-info/unsupported/privileged",
},
systemd: { title: "Systemd", url: "/more-info/unsupported/systemd" },
};
const UNHEALTHY_REASON_URL = {
privileged: "/more-info/unsupported/privileged",
supervisor: "/more-info/unhealthy/supervisor",
setup: "/more-info/unhealthy/setup",
docker: "/more-info/unhealthy/docker",
const UNHEALTHY_REASON = {
privileged: {
title: "Supervisor is not privileged",
url: "/more-info/unsupported/privileged",
},
supervisor: {
title: "Supervisor was not able to update",
url: "/more-info/unhealthy/supervisor",
},
setup: {
title: "Setup of the Supervisor failed",
url: "/more-info/unhealthy/setup",
},
docker: {
title: "The Docker environment is not working properly",
url: "/more-info/unhealthy/docker",
},
};
@customElement("hassio-supervisor-info")
@@ -68,11 +98,11 @@ class HassioSupervisorInfo extends LitElement {
protected render(): TemplateResult | void {
const metrics = [
{
description: this.supervisor.localize("system.supervisor.cpu_usage"),
description: "Supervisor CPU Usage",
value: this._metrics?.cpu_percent,
},
{
description: this.supervisor.localize("system.supervisor.ram_usage"),
description: "Supervisor RAM Usage",
value: this._metrics?.memory_percent,
tooltip: `${bytesToString(this._metrics?.memory_usage)}/${bytesToString(
this._metrics?.memory_limit
@@ -85,7 +115,7 @@ class HassioSupervisorInfo extends LitElement {
<div>
<ha-settings-row>
<span slot="heading">
${this.supervisor.localize("common.version")}
Version
</span>
<span slot="description">
supervisor-${this.supervisor.supervisor.version}
@@ -93,7 +123,7 @@ class HassioSupervisorInfo extends LitElement {
</ha-settings-row>
<ha-settings-row>
<span slot="heading">
${this.supervisor.localize("common.newest_version")}
Newest Version
</span>
<span slot="description">
supervisor-${this.supervisor.supervisor.version_latest}
@@ -101,19 +131,17 @@ class HassioSupervisorInfo extends LitElement {
${this.supervisor.supervisor.update_available
? html`
<ha-progress-button
.title=${this.supervisor.localize(
"system.supervisor.update_supervisor"
)}
title="Update the supervisor"
@click=${this._supervisorUpdate}
>
${this.supervisor.localize("common.update")}
Update
</ha-progress-button>
`
: ""}
</ha-settings-row>
<ha-settings-row>
<span slot="heading">
${this.supervisor.localize("system.supervisor.channel")}
Channel
</span>
<span slot="description">
${this.supervisor.supervisor.channel}
@@ -122,26 +150,18 @@ class HassioSupervisorInfo extends LitElement {
? html`
<ha-progress-button
@click=${this._toggleBeta}
.title=${this.supervisor.localize(
"system.supervisor.leave_beta_description"
)}
title="Get stable updates for Home Assistant, supervisor and host"
>
${this.supervisor.localize(
"system.supervisor.leave_beta_action"
)}
Leave beta channel
</ha-progress-button>
`
: this.supervisor.supervisor.channel === "stable"
? html`
<ha-progress-button
@click=${this._toggleBeta}
.title=${this.supervisor.localize(
"system.supervisor.join_beta_description"
)}
title="Get beta updates for Home Assistant (RCs), supervisor and host"
>
${this.supervisor.localize(
"system.supervisor.join_beta_action"
)}
Join beta channel
</ha-progress-button>
`
: ""}
@@ -150,20 +170,16 @@ class HassioSupervisorInfo extends LitElement {
${this.supervisor.supervisor.supported
? html` <ha-settings-row three-line>
<span slot="heading">
${this.supervisor.localize(
"system.supervisor.share_diagnostics"
)}
Share Diagnostics
</span>
<div slot="description" class="diagnostics-description">
${this.supervisor.localize(
"system.supervisor.share_diagnostics_description"
)}
Share crash reports and diagnostic information.
<button
class="link"
.title=${this.supervisor.localize("common.show_more")}
title="Show more information about this"
@click=${this._diagnosticsInformationDialog}
>
${this.supervisor.localize("common.learn_more")}
Learn more
</button>
</div>
<ha-switch
@@ -173,12 +189,10 @@ class HassioSupervisorInfo extends LitElement {
></ha-switch>
</ha-settings-row>`
: html`<div class="error">
${this.supervisor.localize(
"system.supervisor.unsupported_title"
)}
You are running an unsupported installation.
<button
class="link"
.title=${this.supervisor.localize("common.learn_more")}
title="Learn more about how you can make your system compliant"
@click=${this._unsupportedDialog}
>
Learn more
@@ -186,12 +200,10 @@ class HassioSupervisorInfo extends LitElement {
</div>`}
${!this.supervisor.supervisor.healthy
? html`<div class="error">
${this.supervisor.localize(
"system.supervisor.unhealthy_title"
)}
Your installation is running in an unhealthy state.
<button
class="link"
.title=${this.supervisor.localize("common.learn_more")}
title="Learn more about why your system is marked as unhealthy"
@click=${this._unhealthyDialog}
>
Learn more
@@ -215,26 +227,16 @@ class HassioSupervisorInfo extends LitElement {
<div class="card-actions">
<ha-progress-button
@click=${this._supervisorReload}
.title=${this.supervisor.localize(
"system.supervisor.reload_supervisor"
)}
title="Reload parts of the Supervisor"
>
${this.supervisor.localize("system.supervisor.reload_supervisor")}
Reload Supervisor
</ha-progress-button>
<ha-progress-button
class="warning"
@click=${this._supervisorRestart}
.title=${this.supervisor.localize(
"common.restart_name",
"name",
"Supervisor"
)}
title="Restart the Supervisor"
>
${this.supervisor.localize(
"common.restart_name",
"name",
"Supervisor"
)}
Restart Supervisor
</ha-progress-button>
</div>
</ha-card>
@@ -255,23 +257,23 @@ class HassioSupervisorInfo extends LitElement {
if (this.supervisor.supervisor.channel === "stable") {
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize("system.supervisor.warning"),
text: html`${this.supervisor.localize("system.supervisor.beta_warning")}
title: "WARNING",
text: html` Beta releases are for testers and early adopters and can
contain unstable code changes.
<br />
<b>
${this.supervisor.localize("system.supervisor.beta_backup")}
Make sure you have backups of your data before you activate this
feature.
</b>
<br /><br />
${this.supervisor.localize("system.supervisor.beta_release_items")}
This includes beta releases for:
<li>Home Assistant Core</li>
<li>Home Assistant Supervisor</li>
<li>Home Assistant Operating System</li>
<br />
${this.supervisor.localize("system.supervisor.join_beta_action")}`,
confirmText: this.supervisor.localize(
"system.supervisor.beta_join_confirm"
),
dismissText: this.supervisor.localize("common.cancel"),
Do you want to join the beta channel?`,
confirmText: "join beta",
dismissText: "no",
});
if (!confirmed) {
@@ -289,9 +291,7 @@ class HassioSupervisorInfo extends LitElement {
await this._reloadSupervisor();
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize(
"system.supervisor.failed_to_set_option"
),
title: "Failed to set supervisor option",
text: extractApiErrorMessage(err),
});
} finally {
@@ -307,7 +307,7 @@ class HassioSupervisorInfo extends LitElement {
await this._reloadSupervisor();
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize("system.supervisor.failed_to_reload"),
title: "Failed to reload the supervisor",
text: extractApiErrorMessage(err),
});
} finally {
@@ -327,18 +327,10 @@ class HassioSupervisorInfo extends LitElement {
button.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize(
"confirm.restart.title",
"name",
"Supervisor"
),
text: this.supervisor.localize(
"confirm.restart.text",
"name",
"Supervisor"
),
confirmText: this.supervisor.localize("common.restart"),
dismissText: this.supervisor.localize("common.cancel"),
title: "Restart the Supervisor",
text: "Are you sure you want to restart the Supervisor",
confirmText: "restart",
dismissText: "cancel",
});
if (!confirmed) {
@@ -350,11 +342,7 @@ class HassioSupervisorInfo extends LitElement {
await restartSupervisor(this.hass);
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize(
"common.failed_to_restart_name",
"name",
"Supervisor"
),
title: "Failed to restart the supervisor",
text: extractApiErrorMessage(err),
});
} finally {
@@ -367,16 +355,10 @@ class HassioSupervisorInfo extends LitElement {
button.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize("confirm.update", "name", "Supervisor"),
text: this.supervisor.localize(
"confirm.text",
"name",
"Supervisor",
"version",
this.supervisor.supervisor.version_latest
),
confirmText: this.supervisor.localize("common.update"),
dismissText: this.supervisor.localize("common.cancel"),
title: "Update Supervisor",
text: `Are you sure you want to update supervisor to version ${this.supervisor.supervisor.version_latest}?`,
confirmText: "update",
dismissText: "cancel",
});
if (!confirmed) {
@@ -391,11 +373,7 @@ class HassioSupervisorInfo extends LitElement {
});
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize(
"common.failed_to_update_name",
"name",
"Supervisor"
),
title: "Failed to update the supervisor",
text: extractApiErrorMessage(err),
});
} finally {
@@ -405,41 +383,40 @@ class HassioSupervisorInfo extends LitElement {
private async _diagnosticsInformationDialog(): Promise<void> {
await showAlertDialog(this, {
title: this.supervisor.localize(
"system.supervisor.share_diagonstics_title"
),
text: this.supervisor.localize(
"system.supervisor.share_diagonstics_description",
"line_break",
html`<br /><br />`
),
title: "Help Improve Home Assistant",
text: html`Would you want to automatically share crash reports and
diagnostic information when the supervisor encounters unexpected errors?
<br /><br />
This will allow us to fix the problems, the information is only
accessible to the Home Assistant Core team and will not be shared with
others.
<br /><br />
The data does not include any private/sensitive information and you can
disable this in settings at any time you want.`,
});
}
private async _unsupportedDialog(): Promise<void> {
await showAlertDialog(this, {
title: this.supervisor.localize("system.supervisor.unsupported_title"),
text: html`${this.supervisor.localize(
"system.supervisor.unsupported_description"
)} <br /><br />
title: "You are running an unsupported installation",
text: html`Below is a list of issues found with your installation, click
on the links to learn how you can resolve the issues. <br /><br />
<ul>
${this.supervisor.resolution.unsupported.map(
(reason) => html`
(issue) => html`
<li>
${UNSUPPORTED_REASON_URL[reason]
${UNSUPPORTED_REASON[issue]
? html`<a
href="${documentationUrl(
this.hass,
UNSUPPORTED_REASON_URL[reason]
UNSUPPORTED_REASON[issue].url
)}"
target="_blank"
rel="noreferrer"
>
${this.supervisor.localize(
`system.supervisor.unsupported_reason.${reason}`
) || reason}
${UNSUPPORTED_REASON[issue].title}
</a>`
: reason}
: issue}
</li>
`
)}
@@ -449,28 +426,26 @@ class HassioSupervisorInfo extends LitElement {
private async _unhealthyDialog(): Promise<void> {
await showAlertDialog(this, {
title: this.supervisor.localize("system.supervisor.unhealthy_title"),
text: html`${this.supervisor.localize(
"system.supervisor.unhealthy_description"
)} <br /><br />
title: "Your installation is unhealthy",
text: html`Running an unhealthy installation will cause issues. Below is a
list of issues found with your installation, click on the links to learn
how you can resolve the issues. <br /><br />
<ul>
${this.supervisor.resolution.unhealthy.map(
(reason) => html`
(issue) => html`
<li>
${UNHEALTHY_REASON_URL[reason]
${UNHEALTHY_REASON[issue]
? html`<a
href="${documentationUrl(
this.hass,
UNHEALTHY_REASON_URL[reason]
UNHEALTHY_REASON[issue].url
)}"
target="_blank"
rel="noreferrer"
>
${this.supervisor.localize(
`system.supervisor.unhealthy_reason.${reason}`
) || reason}
${UNHEALTHY_REASON[issue].title}
</a>`
: reason}
: issue}
</li>
`
)}
@@ -486,9 +461,7 @@ class HassioSupervisorInfo extends LitElement {
await setSupervisorOption(this.hass, data);
} catch (err) {
showAlertDialog(this, {
title: this.supervisor.localize(
"system.supervisor.failed_to_set_option"
),
title: "Failed to set supervisor option",
text: extractApiErrorMessage(err),
});
}
+11 -17
View File
@@ -16,7 +16,6 @@ import "../../../src/components/buttons/ha-progress-button";
import "../../../src/components/ha-card";
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
import { fetchHassioLogs } from "../../../src/data/hassio/supervisor";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import "../../../src/layouts/hass-loading-screen";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types";
@@ -59,8 +58,6 @@ const logProviders: LogProvider[] = [
class HassioSupervisorLog extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@internalProperty() private _error?: string;
@internalProperty() private _selectedLogProvider = "supervisor";
@@ -79,7 +76,7 @@ class HassioSupervisorLog extends LitElement {
${this.hass.userData?.showAdvanced
? html`
<paper-dropdown-menu
.label=${this.supervisor.localize("system.log.log_provider")}
label="Log Provider"
@iron-select=${this._setLogProvider}
>
<paper-listbox
@@ -89,9 +86,9 @@ class HassioSupervisorLog extends LitElement {
>
${logProviders.map((provider) => {
return html`
<paper-item provider=${provider.key}>
${provider.name}
</paper-item>
<paper-item provider=${provider.key}
>${provider.name}</paper-item
>
`;
})}
</paper-listbox>
@@ -101,13 +98,14 @@ class HassioSupervisorLog extends LitElement {
<div class="card-content" id="content">
${this._content
? html`<hassio-ansi-to-html .content=${this._content}>
</hassio-ansi-to-html>`
? html`<hassio-ansi-to-html
.content=${this._content}
></hassio-ansi-to-html>`
: html`<hass-loading-screen no-toolbar></hass-loading-screen>`}
</div>
<div class="card-actions">
<ha-progress-button @click=${this._refresh}>
${this.supervisor.localize("common.refresh")}
Refresh
</ha-progress-button>
</div>
</ha-card>
@@ -136,13 +134,9 @@ class HassioSupervisorLog extends LitElement {
this._selectedLogProvider
);
} catch (err) {
this._error = this.supervisor.localize(
"system.log.get_logs",
"provider",
this._selectedLogProvider,
"error",
extractApiErrorMessage(err)
);
this._error = `Failed to get supervisor logs, ${extractApiErrorMessage(
err
)}`;
}
}
+4 -10
View File
@@ -32,16 +32,13 @@ class HassioSystem extends LitElement {
return html`
<hass-tabs-subpage
.hass=${this.hass}
.localizeFunc=${this.supervisor.localize}
.narrow=${this.narrow}
hassio
main-page
.route=${this.route}
.tabs=${supervisorTabs}
main-page
supervisor
>
<span slot="header">
${this.supervisor.localize("panel.system")}
</span>
<span slot="header">System</span>
<div class="content">
<div class="card-group">
<hassio-core-info
@@ -57,10 +54,7 @@ class HassioSystem extends LitElement {
.supervisor=${this.supervisor}
></hassio-host-info>
</div>
<hassio-supervisor-log
.hass=${this.hass}
.supervisor=${this.supervisor}
></hassio-supervisor-log>
<hassio-supervisor-log .hass=${this.hass}></hassio-supervisor-log>
</div>
</hass-tabs-subpage>
`;
+1 -1
View File
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name="home-assistant-frontend",
version="20210302.0",
version="20210301.0",
description="The Home Assistant frontend",
url="https://github.com/home-assistant/home-assistant-polymer",
author="The Home Assistant Authors",
+3 -4
View File
@@ -8,10 +8,9 @@ export const atLeastVersion = (
return (
Number(haMajor) > major ||
(Number(haMajor) === major &&
(patch === undefined
? Number(haMinor) >= minor
: Number(haMinor) > minor)) ||
(Number(haMajor) === major && (patch === undefined
? Number(haMinor) >= minor
: Number(haMinor) > minor)) ||
(patch !== undefined &&
Number(haMajor) === major &&
Number(haMinor) === minor &&
-1
View File
@@ -103,7 +103,6 @@ export const DOMAINS_WITH_MORE_INFO = [
"lock",
"media_player",
"person",
"remote",
"script",
"sun",
"timer",
+6 -10
View File
@@ -16,10 +16,6 @@ export type AddonStartup =
export type AddonState = "started" | "stopped" | null;
export type AddonRepository = "core" | "local" | string;
interface AddonTranslations {
[key: string]: Record<string, Record<string, Record<string, string>>>;
}
export interface HassioAddonInfo {
advanced: boolean;
available: boolean;
@@ -86,7 +82,6 @@ export interface HassioAddonDetails extends HassioAddonInfo {
slug: string;
startup: AddonStartup;
stdin: boolean;
translations: AddonTranslations;
watchdog: null | boolean;
webui: null | string;
}
@@ -309,12 +304,13 @@ export const updateHassioAddon = async (
method: "post",
timeout: null,
});
} else {
await hass.callApi<HassioResponse<void>>(
"POST",
`hassio/addons/${slug}/update`
);
return;
}
await hass.callApi<HassioResponse<void>>(
"POST",
`hassio/addons/${slug}/update`
);
};
export const restartHassioAddon = async (
-16
View File
@@ -1,16 +0,0 @@
import {
HassEntityAttributeBase,
HassEntityBase,
} from "home-assistant-js-websocket";
export const REMOTE_SUPPORT_LEARN_COMMAND = 1;
export const REMOTE_SUPPORT_DELETE_COMMAND = 2;
export const REMOTE_SUPPORT_ACTIVITY = 4;
export type RemoteEntity = HassEntityBase & {
attributes: HassEntityAttributeBase & {
current_activity: string | null;
activity_list: string[] | null;
[key: string]: any;
};
};
+3 -2
View File
@@ -14,7 +14,8 @@ export const updateCore = async (hass: HomeAssistant) => {
method: "post",
timeout: null,
});
} else {
await hass.callApi<HassioResponse<void>>("POST", `hassio/core/update`);
return;
}
await hass.callApi<HassioResponse<void>>("POST", `hassio/core/update`);
};
-3
View File
@@ -1,6 +1,5 @@
import { Connection, getCollection } from "home-assistant-js-websocket";
import { Store } from "home-assistant-js-websocket/dist/store";
import { LocalizeFunc } from "../../common/translations/localize";
import { HomeAssistant } from "../../types";
import { HassioAddonsInfo } from "../hassio/addon";
import { HassioHassOSInfo, HassioHostInfo } from "../hassio/host";
@@ -47,7 +46,6 @@ interface supervisorApiRequest {
method?: "get" | "post" | "delete" | "put";
force_rest?: boolean;
data?: any;
timeout?: number | null;
}
export interface SupervisorEvent {
@@ -67,7 +65,6 @@ export interface Supervisor {
os: HassioHassOSInfo;
addon: HassioAddonsInfo;
store: SupervisorStore;
localize: LocalizeFunc;
}
export const supervisorApiWsRequest = <T>(
@@ -1,93 +0,0 @@
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
import {
css,
CSSResult,
customElement,
html,
LitElement,
property,
TemplateResult,
} from "lit-element";
import { supportsFeature } from "../../../common/entity/supports-feature";
import "../../../components/ha-attributes";
import "../../../components/ha-paper-dropdown-menu";
import { RemoteEntity, REMOTE_SUPPORT_ACTIVITY } from "../../../data/remote";
import { HomeAssistant } from "../../../types";
const filterExtraAttributes = "activity_list,current_activity";
@customElement("more-info-remote")
class MoreInfoRemote extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public stateObj?: RemoteEntity;
protected render(): TemplateResult {
if (!this.hass || !this.stateObj) {
return html``;
}
const stateObj = this.stateObj;
return html`
${supportsFeature(stateObj, REMOTE_SUPPORT_ACTIVITY)
? html`
<ha-paper-dropdown-menu
.label=${this.hass!.localize(
"ui.dialogs.more_info_control.remote.activity"
)}
>
<paper-listbox
slot="dropdown-content"
.selected=${stateObj.attributes.current_activity}
@iron-select=${this.handleActivityChanged}
attr-for-selected="item-name"
>
${stateObj.attributes.activity_list!.map(
(activity) => html`
<paper-item .itemName=${activity}>
${activity}
</paper-item>
`
)}
</paper-listbox>
</ha-paper-dropdown-menu>
`
: ""}
<ha-attributes
.stateObj=${this.stateObj}
.extraFilters=${filterExtraAttributes}
></ha-attributes>
`;
}
private handleActivityChanged(ev: CustomEvent) {
const oldVal = this.stateObj!.attributes.current_activity;
const newVal = ev.detail.item.itemName;
if (!newVal || oldVal === newVal) {
return;
}
this.hass.callService("remote", "turn_on", {
entity_id: this.stateObj!.entity_id,
activity: newVal,
});
}
static get styles(): CSSResult {
return css`
paper-item {
cursor: pointer;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"more-info-remote": MoreInfoRemote;
}
}
@@ -21,7 +21,6 @@ const LAZY_LOADED_MORE_INFO_CONTROL = {
lock: () => import("./controls/more-info-lock"),
media_player: () => import("./controls/more-info-media_player"),
person: () => import("./controls/more-info-person"),
remote: () => import("./controls/more-info-remote"),
script: () => import("./controls/more-info-script"),
sun: () => import("./controls/more-info-sun"),
timer: () => import("./controls/more-info-timer"),
+1 -1
View File
@@ -7,7 +7,7 @@ import { computeLocalize } from "../common/translations/localize";
import { DEFAULT_PANEL } from "../data/panel";
import { translationMetadata } from "../resources/translations-metadata";
import { HomeAssistant } from "../types";
import { getTranslation, getLocalLanguage } from "../util/hass-translation";
import { getLocalLanguage, getTranslation } from "../util/hass-translation";
import { demoConfig } from "./demo_config";
import { demoPanels } from "./demo_panels";
import { demoServices } from "./demo_services";
+7 -12
View File
@@ -16,7 +16,6 @@ import memoizeOne from "memoize-one";
import { isComponentLoaded } from "../common/config/is_component_loaded";
import { restoreScroll } from "../common/decorators/restore-scroll";
import { navigate } from "../common/navigate";
import { LocalizeFunc } from "../common/translations/localize";
import { computeRTL } from "../common/util/compute_rtl";
import "../components/ha-icon";
import "../components/ha-icon-button-arrow-prev";
@@ -41,9 +40,7 @@ export interface PageNavigation {
class HassTabsSubpage extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ type: Boolean }) public supervisor = false;
@property({ attribute: false }) public localizeFunc?: LocalizeFunc;
@property({ type: Boolean }) public hassio = false;
@property({ type: String, attribute: "back-path" }) public backPath?: string;
@@ -51,9 +48,9 @@ class HassTabsSubpage extends LitElement {
@property({ type: Boolean, attribute: "main-page" }) public mainPage = false;
@property({ attribute: false }) public route!: Route;
@property() public route!: Route;
@property({ attribute: false }) public tabs!: PageNavigation[];
@property() public tabs!: PageNavigation[];
@property({ type: Boolean, reflect: true }) public narrow = false;
@@ -74,8 +71,7 @@ class HassTabsSubpage extends LitElement {
showAdvanced: boolean | undefined,
_components,
_language,
_narrow,
localizeFunc
_narrow
) => {
const shownTabs = tabs.filter(
(page) =>
@@ -95,7 +91,7 @@ class HassTabsSubpage extends LitElement {
.active=${page === activeTab}
.narrow=${this.narrow}
.name=${page.translationKey
? localizeFunc(page.translationKey)
? this.hass.localize(page.translationKey)
: page.name}
>
${page.iconPath
@@ -134,8 +130,7 @@ class HassTabsSubpage extends LitElement {
this.hass.userData?.showAdvanced,
this.hass.config.components,
this.hass.language,
this.narrow,
this.localizeFunc || this.hass.localize
this.narrow
);
const showTabs = tabs.length > 1 || !this.narrow;
return html`
@@ -143,7 +138,7 @@ class HassTabsSubpage extends LitElement {
${this.mainPage
? html`
<ha-menu-button
.hassio=${this.supervisor}
.hassio=${this.hassio}
.hass=${this.hass}
.narrow=${this.narrow}
></ha-menu-button>
+1 -1
View File
@@ -1,7 +1,7 @@
import { LitElement, property, PropertyValues } from "lit-element";
import { computeLocalize, LocalizeFunc } from "../common/translations/localize";
import { Constructor, Resources } from "../types";
import { getTranslation, getLocalLanguage } from "../util/hass-translation";
import { getLocalLanguage, getTranslation } from "../util/hass-translation";
const empty = () => "";
@@ -161,8 +161,8 @@ export class HaConfigDevicePage extends LitElement {
const batteryState = batteryEntity
? this.hass.states[batteryEntity.entity_id]
: undefined;
const batteryIsBinary =
batteryState && computeStateDomain(batteryState) === "binary_sensor";
const batteryIsBinary = batteryState
&& computeStateDomain(batteryState) === "binary_sensor";
const batteryChargingState = batteryChargingEntity
? this.hass.states[batteryChargingEntity.entity_id]
: undefined;
@@ -1,7 +1,7 @@
import "@material/mwc-button";
import {
mdiInformationOutline,
mdiClipboardTextMultipleOutline,
mdiClipboardTextMultipleOutline
} from "@mdi/js";
import "@polymer/paper-checkbox/paper-checkbox";
import "@polymer/paper-input/paper-input";
@@ -169,10 +169,7 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
<th>[[localize('ui.panel.developer-tools.tabs.states.state')]]</th>
<th hidden$="[[narrow]]">
[[localize('ui.panel.developer-tools.tabs.states.attributes')]]
<paper-checkbox
checked="{{_showAttributes}}"
on-change="{{saveAttributeCheckboxState}}"
></paper-checkbox>
<paper-checkbox checked="{{_showAttributes}}" on-change="{{saveAttributeCheckboxState}}"></paper-checkbox>
</th>
</tr>
<tr>
@@ -288,9 +285,7 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
_showAttributes: {
type: Boolean,
value: JSON.parse(
localStorage.getItem("devToolsShowAttributes") || true
),
value: JSON.parse(localStorage.getItem("devToolsShowAttributes") || true),
},
_entities: {
@@ -199,10 +199,7 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard {
left: 0;
right: 0;
bottom: 0;
background-color: var(
--ha-picture-card-background-color,
rgba(0, 0, 0, 0.3)
);
background-color: var(--ha-picture-card-background-color, rgba(0, 0, 0, 0.3));
padding: 16px;
font-size: 16px;
line-height: 16px;
@@ -314,10 +314,7 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard {
left: 0;
right: 0;
bottom: 0;
background-color: var(
--ha-picture-card-background-color,
rgba(0, 0, 0, 0.3)
);
background-color: var(--ha-picture-card-background-color, rgba(0, 0, 0, 0.3));
padding: 4px 8px;
font-size: 16px;
line-height: 40px;
+4 -5
View File
@@ -81,7 +81,7 @@ class LovelaceFullConfigEditor extends LitElement {
</div>
<mwc-button
raised
@click=${this._handleSave}
@click="${this._handleSave}"
.disabled=${!this._changed}
>${this.hass!.localize(
"ui.panel.lovelace.editor.raw_editor.save"
@@ -95,8 +95,8 @@ class LovelaceFullConfigEditor extends LitElement {
autofocus
.rtl=${computeRTL(this.hass)}
.hass=${this.hass}
@value-changed=${this._yamlChanged}
@editor-save=${this._handleSave}
@value-changed="${this._yamlChanged}"
@editor-save="${this._handleSave}"
>
</ha-code-editor>
</div>
@@ -112,7 +112,6 @@ class LovelaceFullConfigEditor extends LitElement {
protected updated(changedProps: PropertyValues) {
const oldLovelace = changedProps.get("lovelace") as Lovelace | undefined;
if (
!this._saving &&
oldLovelace &&
this.lovelace &&
oldLovelace.config !== this.lovelace.config &&
@@ -306,8 +305,8 @@ class LovelaceFullConfigEditor extends LitElement {
});
}
window.onbeforeunload = null;
this._changed = false;
this._saving = false;
this._changed = false;
}
private get yamlEditor(): HaCodeEditor {
+1 -1
View File
@@ -12,8 +12,8 @@ import { translationMetadata } from "../resources/translations-metadata";
import { Constructor, HomeAssistant } from "../types";
import { storeState } from "../util/ha-pref-storage";
import {
getTranslation,
getLocalLanguage,
getTranslation,
getUserLanguage,
} from "../util/hass-translation";
import { HassBaseEl } from "./hass-base-mixin";
-395
View File
@@ -611,9 +611,6 @@
"updater": {
"title": "Update Instructions"
},
"remote": {
"activity": "Current activity"
},
"restored": {
"not_provided": "This entity is currently unavailable and is an orphan to a removed, changed or dysfunctional integration or device.",
"remove_intro": "If the entity is no longer in use, you can clean it up by removing it.",
@@ -3420,397 +3417,5 @@
}
}
}
},
"supervisor": {
"addon": {
"failed_to_reset": "Failed to reset add-on configuration, {error}",
"failed_to_save": "Failed to save add-on configuration, {error}",
"state": {
"installed": "Add-on is installed",
"not_installed": "Add-on is not installed",
"not_available": "Add-on is not available on your system"
},
"panel": {
"configuration": "Configuration",
"documentation": "Documentation",
"info": "Info",
"log": "Log"
},
"configuration": {
"no_configuration": "This add-on does not expose configuration for you to mess with...",
"audio": {
"header": "Audio",
"default": "Default",
"input": "Input",
"output": "Output"
},
"options": {
"header": "Options",
"edit_in_ui": "Edit in UI",
"edit_in_yaml": "Edit in YAML",
"invalid_yaml": "Invalid YAML",
"show_unused_optional": "Show unused optional configuration options"
},
"network": {
"container": "Container",
"disabled": "Disabled",
"header": "Network",
"host": "Host"
}
},
"dashboard": {
"changelog": "Changelog",
"cpu_usage": "Add-on CPU Usage",
"ram_usage": "Add-on RAM Usage",
"hostname": "Hostname",
"new_update_available": "{name} {version} is available",
"not_available_arch": "This add-on is not compatible with the processor of your device or the operating system you have installed on your device.",
"not_available_version": "You are unning Home Assistant {core_version_installed}, to update to this version of the add-on you need at least version {core_version_needed} of Home Assistan",
"visit_addon_page": "Visit the {name} page for more detals",
"restart": "restart",
"start": "start",
"stop": "stop",
"install": "install",
"uninstall": "uninstall",
"rebuild": "rebuild",
"open_web_ui": "Open web UI",
"protection_mode": {
"title": "Warning: Protection mode is disabled!",
"content": "Protection mode on this add-on is disabled! This gives the add-on full access to the entire system, which adds security risks, and could damage your system when used incorrectly. Only disable the protection mode if you know, need AND trust the source of this add-on.",
"enable": "Enable Protection mode"
},
"capability": {
"stage": {
"title": "Add-on Stage",
"description": "Add-ons can have one of three stages:\n\n{icon_stable} **Stable**: These are add-ons ready to be used in production.\n\n{icon_experimental} **Experimental**: These may contain bugs, and may be unfinished.\n\n{icon_deprecated} **Deprecated**: These add-ons will no longer receive any updates."
},
"rating": {
"title": "Add-on Security Rating",
"description": "Home Assistant provides a security rating to each of the add-ons, which indicates the risks involved when using this add-on. The more access an add-on requires on your system, the lower the score, thus raising the possible security risks.\n\nA score is on a scale from 1 to 6. Where 1 is the lowest score (considered the most insecure and highest risk) and a score of 6 is the highest score (considered the most secure and lowest risk)."
},
"host_network": {
"title": "Host Network",
"description": "Add-ons usually run in their own isolated network layer, which prevents them from accessing the network of the host operating system. In some cases, this network isolation can limit add-ons in providing their services and therefore, the isolation can be lifted by the add-on author, giving the add-on full access to the network capabilities of the host machine. This gives the add-on more networking capabilities but lowers the security, hence, the security rating of the add-on will be lowered when this option is used by the add-on."
},
"homeassistant_api": {
"title": "Home Assistant API Access",
"description": "This add-on is allowed to access your running Home Assistant instance directly via the Home Assistant API. This mode handles authentication for the add-on as well, which enables an add-on to interact with Home Assistant without the need for additional authentication tokens."
},
"full_access": {
"title": "Full Hardware Access",
"description": "This add-on is given full access to the hardware of your system, by request of the add-on author. Access is comparable to the privileged mode in Docker. Since this opens up possible security risks, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on."
},
"hassio_api": {
"title": "Supervisor API Access",
"description": "The add-on was given access to the Supervisor API, by request of the add-on author. By default, the add-on can access general version information of your system. When the add-on requests 'manager' or 'admin' level access to the API, it will gain access to control multiple parts of your Home Assistant system. This permission is indicated by this badge and will impact the security score of the add-on negatively."
},
"docker_api": {
"title": "Full Docker Access",
"description": "The add-on author has requested the add-on to have management access to the Docker instance running on your system. This mode gives the add-on full access and control to your entire Home Assistant system, which adds security risks, and could damage your system when misused. Therefore, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on."
},
"host_pid": {
"title": "Host Processes Namespace",
"description": "Usually, the processes the add-on runs, are isolated from all other system processes. The add-on author has requested the add-on to have access to the system processes running on the host system instance, and allow the add-on to spawn processes on the host system as well. This mode gives the add-on full access and control to your entire Home Assistant system, which adds security risks, and could damage your system when misused. Therefore, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on."
},
"apparmor": {
"title": "AppArmor",
"description": "AppArmor ('Application Armor') is a Linux kernel security module that restricts add-ons capabilities like network access, raw socket access, and permission to read, write, or execute specific files.\n\nAdd-on authors can provide their security profiles, optimized for the add-on, or request it to be disabled. If AppArmor is disabled, it will raise security risks and therefore, has a negative impact on the security score of the add-on."
},
"auth_api": {
"title": "Home Assistant Authentication",
"description": "An add-on can authenticate users against Home Assistant, allowing add-ons to give users the possibility to log into applications running inside add-ons, using their Home Assistant username/password. This badge indicates if the add-on author requests this capability."
},
"ingress": {
"title": "Ingress",
"description": "This add-on is using Ingress to embed its interface securely into Home Assistant."
},
"label": {
"stage": "stage",
"rating": "rating",
"hardware": "hardware",
"host": "host",
"hass": "hass",
"hassio": "hassio",
"docker": "docker",
"host_pid": "host pid",
"apparmor": "apparmor",
"auth": "auth",
"ingress": "ingress"
},
"role": {
"manager": "manager",
"default": "default",
"homeassistant": "homeassistant",
"backup": "backup",
"admin": "admin"
}
},
"option": {
"boot": {
"title": "Start on boot",
"description": "Make the add-on start during a system boot"
},
"watchdog": {
"title": "Watchdog",
"description": "This will start the add-on if it crashes"
},
"auto_update": {
"title": "Auto update",
"description": "Auto update the add-on when there is a new version available"
},
"ingress_panel": {
"title": "Show in sidebar",
"description": "Add this add-on to your sidebar"
},
"protected": {
"title": "Protection mode",
"description": "Blocks elevated system access from the add-on"
}
},
"action_error": {
"uninstall": "Failed to uninstall add-on",
"install": "Failed to install add-on",
"stop": "Failed to stop add-on",
"restart": "Failed to restart add-on",
"start": "Failed to start add-on",
"go_to_config": "Failed to start add-on - configuration validation failed!",
"start_invalid_config": "Go to configuration",
"validate_config": "Failed to validate add-on configuration",
"get_changelog": "Failed to get add-on changelog"
}
},
"documentation": {
"get_documentation": "Failed to get add-on documentation, {error}"
},
"logs": {
"get_logs": "Failed to get add-on logs, {error}"
}
},
"common": {
"cancel": "[%key:ui::common::cancel%]",
"yes": "[%key:ui::common::yes%]",
"no": "[%key:ui::common::no%]",
"description": "Description",
"failed_to_restart_name": "Failed to restart {name}",
"failed_to_update_name": "Failed to update {name}",
"learn_more": "Learn more",
"new_version_available": "New version available",
"newest_version": "Newest Version",
"refresh": "[%key:ui::common::refresh%]",
"release_notes": "Release notes",
"reload": "Reload",
"reset_defaults": "Reset to defaults",
"reset_options": "Reset options",
"restart_name": "Restart {name}",
"restart": "Restart",
"running_version": "You are currently running version {version}",
"save": "Save",
"show_more": "Show more information about this",
"update_available": "{count, plural,\n one {Update}\n other {{count} Updates}\n} pending",
"update": "Update",
"version": "Version",
"error": {
"unknown": "Unknown error",
"update_failed": "Update failed"
}
},
"confirm": {
"update": {
"title": "Update {name}",
"text": "Are you sure you want to update {name} to version {version}?"
},
"restart": {
"title": "[%key:supervisor::common::restart_name%]",
"text": "Are you sure you want to restart {name}?"
},
"reset_options": {
"title": "Reset options",
"text": "Are you sure you want to reset all your options?"
}
},
"dashboard": {
"addon_new_version": "New version available",
"addon_running": "Add-on is running",
"addon_stopped": "Add-on is stopped",
"addons": "Add-ons",
"no_addons": "You don't have any add-ons installed yet. Head over to the add-on store to get started!"
},
"store": {
"missing_addons": "Missing add-ons? Enable advanced mode in your user profile page",
"no_results_found": "No results found in {repository}.",
"registries": "Registries",
"repositories": "Repositories"
},
"panel": {
"dashboard": "Dashboard",
"snapshots": "Snapshots",
"store": "Add-on Store",
"system": "System"
},
"my": {
"not_supported": "[%key:ui::panel::my::not_supported%]",
"faq_link": "[%key:ui::panel::my::faq_link%]",
"error": "[%key:ui::panel::my::error%]"
},
"system": {
"log": {
"log_provider": "Log Provider",
"get_logs": "Failed to get {provider} logs, {error}"
},
"supervisor": {
"cpu_usage": "Supervisor CPU Usage",
"ram_usage": "Supervisor RAM Usage",
"failed_to_set_option": "Failed to set Supervisor option",
"failed_to_reload": "Failed to reload the Supervisor",
"failed_to_update": "Failed to update the Supervisor",
"unsupported_title": "You are running an unsupported installation",
"unsupported_description": "Below is a list of issues found with your installation, click on the links to learn how you can resolve the issues.",
"unhealthy_title": "Your installation is unhealthy",
"unhealthy_description": "Running an unhealthy installation will cause issues. Below is a list of issues found with your installation, click on the links to learn how you can resolve the issues.",
"update_supervisor": "Update the Supervisor",
"channel": "Channel",
"leave_beta_action": "Leave beta channel",
"leave_beta_description": "Get stable updates for Home Assistant, Supervisor and host",
"join_beta_action": "Join beta channel",
"join_beta_description": "Get beta updates for Home Assistant (RCs), Supervisor and host",
"share_diagnostics": "Share Diagnostics",
"share_diagnostics_description": "Share crash reports and diagnostic information.",
"reload_supervisor": "Reload Supervisor",
"warning": "WARNING",
"beta_warning": "Beta releases are for testers and early adopters and can contain unstable code changes",
"beta_backup": "Make sure you have backups of your data before you activate this feature.",
"beta_release_items": "This includes beta releases for:",
"beta_join_confirm": "Do you want to join the beta channel?",
"share_diagonstics_title": "Help Improve Home Assistant",
"share_diagonstics_description": "Would you want to automatically share crash reports and diagnostic information when the Supervisor encounters unexpected errors? {line_break} This will allow us to fix the problems, the information is only accessible to the Home Assistant Core team and will not be shared with others.{line_break} The data does not include any private/sensitive information and you can disable this in settings at any time you want.",
"unsupported_reason": {
"container": "Containers known to cause issues",
"dbus": "DBUS",
"docker_configuration": "Docker Configuration",
"docker_version": "Docker Version",
"job_conditions": "Ignored job conditions",
"lxc": "LXC",
"network_manager": "Network Manager",
"os": "Operating System",
"privileged": "Supervisor is not privileged",
"systemd": "Systemd"
},
"unhealthy_reason": {
"privileged": "Supervisor is not privileged",
"supervisor": "Supervisor was not able to update",
"setup": "Setup of the Supervisor failed",
"docker": "The Docker environment is not working properly"
}
},
"host": {
"failed_to_get_hardware_list": "Failed to get hardware list",
"failed_to_reboot": "Failed to reboot the host",
"failed_to_shutdown": "Failed to shutdown the host",
"failed_to_set_hostname": "Setting hostname failed",
"failed_to_import_from_usb": "Failed to import from USB",
"used_space": "Used space",
"hostname": "Hostname",
"change_hostname": "Change Hostname",
"new_hostname": "Please enter a new hostname:",
"ip_address": "IP Address",
"change": "Change",
"operating_system": "Operating System",
"docker_version": "Docker version",
"deployment": "Deployment",
"emmc_lifetime_used": "eMMC Lifetime Used",
"reboot_host": "Reboot host",
"confirm_reboot": "Are you sure you want to reboot the host?",
"confirm_shutdown": "Are you sure you want to shutdown the host?",
"shutdown_host": "Shutdown host",
"hardware": "Hardware",
"import_from_usb": "Import from USB"
},
"core": {
"cpu_usage": "Core CPU Usage",
"ram_usage": "Core RAM Usage"
}
},
"snapshot": {
"description": "Snapshots allow you to easily backup and restore all data of your Home Assistant instance.",
"available_snapshots": "Available Snapshots",
"no_snapshots": "You don't have any snapshots yet.",
"create_blocked_not_running": "Creating a snapshot is not possible right now because the system is in {state} state.",
"could_not_create": "Could not create snapshot",
"upload_snapshot": "Upload snapshot",
"create_snapshot": "Create snapshot",
"create": "Create",
"name": "Name",
"type": "Type",
"security": "Security",
"full_snapshot": "Full snapshot",
"partial_snapshot": "Partial snapshot",
"addons": "Add-ons",
"folders": "Folders",
"password": "Password",
"password_protection": "Password protection",
"password_protected": "password protected",
"enter_password": "Please enter a password.",
"folder": {
"homeassistant": "Home Assistant configuration",
"ssl": "SSL",
"share": "Share",
"media": "Media",
"addons/local": "Local add-ons"
}
},
"dialog": {
"network": {
"title": "Network settings",
"connected_to": "Connected to {ssid}",
"scan_ap": "Scan for accesspoints",
"open": "Open",
"wep": "WEP",
"wpa": "wpa-psk",
"warning": "If you are changing the Wi-Fi, IP or gateway addresses, you might lose the connection!",
"static": "Static",
"dhcp": "DHCP",
"disabled": "Disabled",
"ip_netmask": "IP address/Netmask",
"gateway": "Gateway address",
"dns_servers": "DNS Servers",
"unsaved": "You have unsaved changes, these will get lost if you change tabs, do you want to continue?",
"failed_to_change": "Failed to change network settings"
},
"registries": {
"title_add": "Add New Container Registry",
"title_manage": "Manage Container Registries",
"registry": "Registry",
"username": "Username",
"password": "Password",
"no_registries": "No registries configured",
"add_registry": "Add registry",
"add_new_registry": "Add new registry",
"remove": "Remove",
"failed_to_add": "Failed to add registry",
"failed_to_remove": "Failed to remove registry"
},
"repositories": {
"title": "Manage add-on repositories",
"add": "Add",
"remove": "Remove"
},
"restart_addon": {
"confirm_text": "Restart add-on",
"text": "Do you want to restart the add-on with your changes?"
},
"update": {
"snapshot": "Snapshot",
"create_snapshot": "Create a snapshot of {name} before updating",
"updating": "Updating {name} to version {version}",
"snapshotting": "Creating snapshot of {name}"
}
}
}
}
-56
View File
@@ -1,56 +0,0 @@
import { translationMetadata } from "../resources/translations-metadata";
const DEFAULT_BASE_URL = "/static/translations";
// Store loaded translations in memory so translations are available immediately
// when DOM is created in Polymer. Even a cache lookup creates noticeable latency.
const translations = {};
async function fetchTranslation(fingerprint: string, base_url: string) {
const response = await fetch(`${base_url}/${fingerprint}`, {
credentials: "same-origin",
});
if (!response.ok) {
throw new Error(
`Fail to fetch translation ${fingerprint}: HTTP response status is ${response.status}`
);
}
return response.json();
}
export async function getTranslation(
fragment: string | null,
language: string,
base_url?: string
) {
const metadata = translationMetadata.translations[language];
if (!metadata) {
if (language !== "en") {
return getTranslation(fragment, "en", base_url);
}
throw new Error("Language en is not found in metadata");
}
// nl-abcd.jon or logbook/nl-abcd.json
const fingerprint = `${fragment ? fragment + "/" : ""}${language}-${
metadata.hash
}.json`;
// Fetch translation from the server
if (!translations[fingerprint]) {
translations[fingerprint] = fetchTranslation(
fingerprint,
base_url || DEFAULT_BASE_URL
)
.then((data) => ({ language, data }))
.catch((error) => {
delete translations[fingerprint];
if (language !== "en") {
// Couldn't load selected translation. Try a fall back to en before failing.
return getTranslation(fragment, "en", base_url);
}
return Promise.reject(error);
});
}
return translations[fingerprint];
}
+44 -3
View File
@@ -1,7 +1,6 @@
import { fetchTranslationPreferences } from "../data/translation";
import { translationMetadata } from "../resources/translations-metadata";
import { HomeAssistant } from "../types";
import { getTranslation as commonGetTranslation } from "./common-translation";
const STORAGE = window.localStorage || {};
@@ -94,13 +93,55 @@ export function getLocalLanguage() {
return "en";
}
// Store loaded translations in memory so translations are available immediately
// when DOM is created in Polymer. Even a cache lookup creates noticeable latency.
const translations = {};
async function fetchTranslation(fingerprint) {
const response = await fetch(`/static/translations/${fingerprint}`, {
credentials: "same-origin",
});
if (!response.ok) {
throw new Error(
`Fail to fetch translation ${fingerprint}: HTTP response status is ${response.status}`
);
}
return response.json();
}
export async function getTranslation(
fragment: string | null,
language: string
) {
return commonGetTranslation(fragment, language);
const metadata = translationMetadata.translations[language];
if (!metadata) {
if (language !== "en") {
return getTranslation(fragment, "en");
}
throw new Error("Language en is not found in metadata");
}
// nl-abcd.jon or logbook/nl-abcd.json
const fingerprint = `${fragment ? fragment + "/" : ""}${language}-${
metadata.hash
}.json`;
// Fetch translation from the server
if (!translations[fingerprint]) {
translations[fingerprint] = fetchTranslation(fingerprint)
.then((data) => ({ language, data }))
.catch((error) => {
delete translations[fingerprint];
if (language !== "en") {
// Couldn't load selected translation. Try a fall back to en before failing.
return getTranslation(fragment, "en");
}
return Promise.reject(error);
});
}
return translations[fingerprint];
}
// Load selected translation into memory immediately so it is ready when Polymer
// initializes.
commonGetTranslation(null, getLocalLanguage());
getTranslation(null, getLocalLanguage());
+1
View File
@@ -697,6 +697,7 @@
"script": "Programació (scripts)",
"server_control": "Controls del servidor",
"tag": "Etiquetes",
"tags": "Etiquetes",
"users": "Usuaris",
"zone": "Zones"
},
+1
View File
@@ -697,6 +697,7 @@
"script": "Skripty",
"server_control": "Ovládání serveru",
"tag": "Štítky",
"tags": "Štítky",
"users": "Uživatelé",
"zone": "Zóny"
},
+1
View File
@@ -675,6 +675,7 @@
"scene": "Scener",
"script": "Scripts",
"server_control": "Serveradministration",
"tags": "",
"users": "Brugere",
"zone": "Zoner"
},
+1 -40
View File
@@ -102,40 +102,6 @@
"unknown": "Unbekannt"
}
},
"supervisor": {
"addon": {
"panel": {
"configuration": "Konfiguration",
"documentation": "Dokumentation",
"info": "Informationen",
"log": "Protokoll"
}
},
"common": {
"cancel": "Abbrechen",
"newest_version": "Neueste Version",
"release_notes": "Versionshinweise",
"update": "Aktualisieren"
},
"confirm": {
"update": {
"text": "Sind Sie sicher, dass Sie {name} auf Version {version} aktualisieren möchten?",
"title": "Aktualisiere {name}"
}
},
"dashboard": {
"addon_new_version": "Neue Version verfügbar",
"addon_running": "Add-on wird ausgeführt",
"addon_stopped": "Add-on ist gestoppt",
"no_addons": "Sie haben noch keine Add-Ons installiert. Gehen Sie zum Add-on-Shop, um loszulegen!"
},
"panel": {
"dashboard": "Dashboard",
"snapshots": "Datensicherungen",
"store": "Add-on Shop",
"system": "System"
}
},
"ui": {
"auth_store": {
"ask": "Möchtest du angemeldet bleiben?",
@@ -411,8 +377,6 @@
"changed_to_state": "wechselte zu {state}",
"cleared_device_class": "zurückgesetzt (kein(e) {device_class} erkannt)",
"detected_device_class": "{device_class} erkannt",
"is_closing": "wird geschlossen",
"is_opening": "wird geöffnet",
"rose": "aufgegangen",
"set": "untergegangen",
"turned_off": "ausgeschaltet",
@@ -733,6 +697,7 @@
"script": "Skripte",
"server_control": "Serversteuerung",
"tag": "NFC Tags",
"tags": "Tags",
"users": "Benutzer",
"zone": "Zonen"
},
@@ -2406,9 +2371,7 @@
"inclusion_failed": "Der Knoten konnte nicht hinzugefügt werden. Bitte überprüfe die Protokolle für weitere Informationen.",
"inclusion_finished": "Der Knoten wurde hinzugefügt. Es kann einige Minuten dauern, bis alle Einheiten angezeigt werden, da der Knoten im Hintergrund fertig eingerichtet wird.",
"introduction": "Dieser Assistent führt dich durch das Hinzufügen eines Knotens zu deinem Z-Wave-Netzwerk.",
"secure_inclusion_warning": "Sichere Geräte benötigen zusätzliche Bandbreite; zu viele sichere Geräte können Ihr Z-Wave-Netzwerk ausbremsen. Wir empfehlen, die sichere Einbindung nur für Geräte zu verwenden, die sie benötigen, wie Schlösser oder Garagentoröffner.",
"title": "Z-Wave-Knoten hinzufügen",
"use_secure_inclusion": "Sichere Einbindung verwenden",
"view_device": "Gerät anzeigen"
},
"button": "Konfigurieren",
@@ -2457,7 +2420,6 @@
"remove_node": {
"exclusion_failed": "Der Knoten konnte nicht entfernt werden. Bitte in den Logs nach mehr Informationen suchen.",
"exclusion_finished": "Der Knoten {id} wurde aus deinem Z-Wave-Netzwerk entfernt.",
"follow_device_instructions": "Befolge die mit dem Gerät gelieferten Anweisungen, um die Kopplung am Gerät auszulösen.",
"introduction": "Entferne einen Knoten aus deinem Z-Wave-Netzwerk und entferne die zugehörigen Geräte und Entitäten aus Home Assistant.",
"title": "Z-Wave-Knoten entfernen"
}
@@ -3038,7 +3000,6 @@
"error_remove": "Konfiguration konnte nicht entfernt werden: {error}",
"error_save_yaml": "YAML konnte nicht gespeichert werden: {error}",
"header": "Konfiguration bearbeiten",
"reload": "Neu laden",
"resources_moved": "Ressourcen sollten nicht mehr zur Lovelace-Konfiguration hinzugefügt werden, sondern können im Lovelace-Konfigurationsfenster hinzugefügt werden.",
"save": "Speichern",
"saved": "Gespeichert",
+1 -42
View File
@@ -102,42 +102,6 @@
"unknown": "Άγνωστη"
}
},
"supervisor": {
"addon": {
"panel": {
"configuration": "Ρυθμίσεις",
"documentation": "Τεκμηρίωση",
"info": "Πληροφορίες",
"log": "Αρχείο καταγραφής"
}
},
"common": {
"cancel": "Ακύρωση",
"newest_version": "Νεότερη έκδοση",
"release_notes": "Σημειώσεις έκδοσης",
"update": "Ενημέρωση",
"version": "Έκδοση"
},
"confirm": {
"update": {
"text": "Είστε βέβαιοι ότι θέλετε να ενημερώσετε το {name} στην έκδοση {version} ;",
"title": "Ενημέρωση {name}"
}
},
"dashboard": {
"addon_new_version": "Νέα έκδοση διαθέσιμη",
"addon_running": "Το πρόσθετο εκτελείται",
"addon_stopped": "Το πρόσθετο έχει σταματήσει",
"addons": "Πρόσθετα",
"no_addons": "Δεν έχετε εγκαταστήσει πρόσθετα ακόμα. Επισκεφθείτε το κατάστημα πρόσθετων για να ξεκινήσετε!"
},
"panel": {
"dashboard": "Πίνακας Επισκόπησης",
"snapshots": "Στιγμιότυπα",
"store": "Κατάστημα πρόσθετων",
"system": "Σύστημα"
}
},
"ui": {
"auth_store": {
"ask": "Θέλετε να αποθηκεύσετε αυτή τη σύνδεση;",
@@ -413,8 +377,6 @@
"changed_to_state": "άλλαξε σε {state}",
"cleared_device_class": "παραγράφηκε (δεν εντοπίστηκε {device_class} )",
"detected_device_class": "εντόπισε {device_class}",
"is_closing": "κλείνει",
"is_opening": "ανοίγει",
"rose": "ανέτειλε",
"set": "έδυσε",
"turned_off": "απενεργοποιήθηκε",
@@ -735,6 +697,7 @@
"script": "Scripts",
"server_control": "Στοιχεία ελέγχου Server",
"tag": "Ετικέτες",
"tags": "Ετικέτες",
"users": "Χρήστες",
"zone": "Ζώνες"
},
@@ -793,7 +756,6 @@
"clusters": "Διαχείριση συμπλεγμάτων",
"reconfigure": "Ρυθμίστε Ξανά Τη Συσκευή",
"remove": "Κατάργηση συσκευής",
"view_in_visualization": "Προβολή στην Απεικόνιση",
"zigbee_information": "Υπογραφή συσκευής Zigbee"
},
"confirmations": {
@@ -2371,7 +2333,6 @@
"caption": "Απεικόνιση",
"header": "Απεικόνιση δικτύου",
"highlight_label": "Επισήμανση συσκευών",
"refresh_topology": "Ανανέωση τοπολογίας",
"zoom_label": "Ζουμ στη συσκευή"
}
},
@@ -3049,8 +3010,6 @@
"error_remove": "Δεν είναι δυνατή η κατάργηση της διαμόρφωσης: {error}",
"error_save_yaml": "Δεν είναι δυνατή η αποθήκευση του YAML: {error}",
"header": "Επεξεργασία διαμόρφωσης",
"lovelace_changed": "Η διαμόρφωση Lovelace ενημερώθηκε, θέλετε να φορτώσετε την ενημερωμένη διαμόρφωση στο πρόγραμμα επεξεργασίας και να χάσετε τις τρέχουσες αλλαγές σας;",
"reload": "Επαναφόρτωση",
"resources_moved": "Οι πόροι δεν θα πρέπει πλέον να προστίθενται στη διαμόρφωση Lovelace, αλλά μπορούν να προστεθούν στον πίνακα παραμέτρων Lovelace.",
"save": "Αποθήκευση",
"saved": "Αποθηκεύτηκε",
+3 -393
View File
@@ -102,391 +102,6 @@
"unknown": "Unknown"
}
},
"supervisor": {
"addon": {
"configuration": {
"audio": {
"default": "Default",
"header": "Audio",
"input": "Input",
"output": "Output"
},
"network": {
"container": "Container",
"disabled": "Disabled",
"header": "Network",
"host": "Host"
},
"no_configuration": "This add-on does not expose configuration for you to mess with...",
"options": {
"edit_in_ui": "Edit in UI",
"edit_in_yaml": "Edit in YAML",
"header": "Options",
"invalid_yaml": "Invalid YAML",
"show_unused_optional": "Show unused optional configuration options"
}
},
"dashboard": {
"action_error": {
"get_changelog": "Failed to get add-on changelog",
"go_to_config": "Failed to start add-on - configuration validation failed!",
"install": "Failed to install add-on",
"restart": "Failed to restart add-on",
"start": "Failed to start add-on",
"start_invalid_config": "Go to configuration",
"stop": "Failed to stop add-on",
"uninstall": "Failed to uninstall add-on",
"validate_config": "Failed to validate add-on configuration"
},
"capability": {
"apparmor": {
"description": "AppArmor ('Application Armor') is a Linux kernel security module that restricts add-ons capabilities like network access, raw socket access, and permission to read, write, or execute specific files.\n\nAdd-on authors can provide their security profiles, optimized for the add-on, or request it to be disabled. If AppArmor is disabled, it will raise security risks and therefore, has a negative impact on the security score of the add-on.",
"title": "AppArmor"
},
"auth_api": {
"description": "An add-on can authenticate users against Home Assistant, allowing add-ons to give users the possibility to log into applications running inside add-ons, using their Home Assistant username/password. This badge indicates if the add-on author requests this capability.",
"title": "Home Assistant Authentication"
},
"docker_api": {
"description": "The add-on author has requested the add-on to have management access to the Docker instance running on your system. This mode gives the add-on full access and control to your entire Home Assistant system, which adds security risks, and could damage your system when misused. Therefore, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on.",
"title": "Full Docker Access"
},
"full_access": {
"description": "This add-on is given full access to the hardware of your system, by request of the add-on author. Access is comparable to the privileged mode in Docker. Since this opens up possible security risks, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on.",
"title": "Full Hardware Access"
},
"hassio_api": {
"description": "The add-on was given access to the Supervisor API, by request of the add-on author. By default, the add-on can access general version information of your system. When the add-on requests 'manager' or 'admin' level access to the API, it will gain access to control multiple parts of your Home Assistant system. This permission is indicated by this badge and will impact the security score of the add-on negatively.",
"title": "Supervisor API Access"
},
"homeassistant_api": {
"description": "This add-on is allowed to access your running Home Assistant instance directly via the Home Assistant API. This mode handles authentication for the add-on as well, which enables an add-on to interact with Home Assistant without the need for additional authentication tokens.",
"title": "Home Assistant API Access"
},
"host_network": {
"description": "Add-ons usually run in their own isolated network layer, which prevents them from accessing the network of the host operating system. In some cases, this network isolation can limit add-ons in providing their services and therefore, the isolation can be lifted by the add-on author, giving the add-on full access to the network capabilities of the host machine. This gives the add-on more networking capabilities but lowers the security, hence, the security rating of the add-on will be lowered when this option is used by the add-on.",
"title": "Host Network"
},
"host_pid": {
"description": "Usually, the processes the add-on runs, are isolated from all other system processes. The add-on author has requested the add-on to have access to the system processes running on the host system instance, and allow the add-on to spawn processes on the host system as well. This mode gives the add-on full access and control to your entire Home Assistant system, which adds security risks, and could damage your system when misused. Therefore, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on.",
"title": "Host Processes Namespace"
},
"ingress": {
"description": "This add-on is using Ingress to embed its interface securely into Home Assistant.",
"title": "Ingress"
},
"label": {
"apparmor": "apparmor",
"auth": "auth",
"docker": "docker",
"hardware": "hardware",
"hass": "hass",
"hassio": "hassio",
"host": "host",
"host_pid": "host pid",
"ingress": "ingress",
"rating": "rating",
"stage": "stage"
},
"rating": {
"description": "Home Assistant provides a security rating to each of the add-ons, which indicates the risks involved when using this add-on. The more access an add-on requires on your system, the lower the score, thus raising the possible security risks.\n\nA score is on a scale from 1 to 6. Where 1 is the lowest score (considered the most insecure and highest risk) and a score of 6 is the highest score (considered the most secure and lowest risk).",
"title": "Add-on Security Rating"
},
"role": {
"admin": "admin",
"backup": "backup",
"default": "default",
"homeassistant": "homeassistant",
"manager": "manager"
},
"stage": {
"description": "Add-ons can have one of three stages:\n\n{icon_stable} **Stable**: These are add-ons ready to be used in production.\n\n{icon_experimental} **Experimental**: These may contain bugs, and may be unfinished.\n\n{icon_deprecated} **Deprecated**: These add-ons will no longer receive any updates.",
"title": "Add-on Stage"
}
},
"changelog": "Changelog",
"cpu_usage": "Add-on CPU Usage",
"hostname": "Hostname",
"install": "install",
"new_update_available": "{name} {version} is available",
"not_available_arch": "This add-on is not compatible with the processor of your device or the operating system you have installed on your device.",
"not_available_version": "You are unning Home Assistant {core_version_installed}, to update to this version of the add-on you need at least version {core_version_needed} of Home Assistan",
"open_web_ui": "Open web UI",
"option": {
"auto_update": {
"description": "Auto update the add-on when there is a new version available",
"title": "Auto update"
},
"boot": {
"description": "Make the add-on start during a system boot",
"title": "Start on boot"
},
"ingress_panel": {
"description": "Add this add-on to your sidebar",
"title": "Show in sidebar"
},
"protected": {
"description": "Blocks elevated system access from the add-on",
"title": "Protection mode"
},
"watchdog": {
"description": "This will start the add-on if it crashes",
"title": "Watchdog"
}
},
"protection_mode": {
"content": "Protection mode on this add-on is disabled! This gives the add-on full access to the entire system, which adds security risks, and could damage your system when used incorrectly. Only disable the protection mode if you know, need AND trust the source of this add-on.",
"enable": "Enable Protection mode",
"title": "Warning: Protection mode is disabled!"
},
"ram_usage": "Add-on RAM Usage",
"rebuild": "rebuild",
"restart": "restart",
"start": "start",
"stop": "stop",
"uninstall": "uninstall",
"visit_addon_page": "Visit the {name} page for more detals"
},
"documentation": {
"get_documentation": "Failed to get add-on documentation, {error}"
},
"failed_to_reset": "Failed to reset add-on configuration, {error}",
"failed_to_save": "Failed to save add-on configuration, {error}",
"logs": {
"get_logs": "Failed to get add-on logs, {error}"
},
"panel": {
"configuration": "Configuration",
"documentation": "Documentation",
"info": "Info",
"log": "Log"
},
"state": {
"installed": "Add-on is installed",
"not_available": "Add-on is not available on your system",
"not_installed": "Add-on is not installed"
}
},
"common": {
"cancel": "Cancel",
"description": "Description",
"error": {
"unknown": "Unknown error",
"update_failed": "Update failed"
},
"failed_to_restart_name": "Failed to restart {name}",
"failed_to_update_name": "Failed to update {name}",
"learn_more": "Learn more",
"new_version_available": "New version available",
"newest_version": "Newest Version",
"no": "No",
"refresh": "Refresh",
"release_notes": "Release notes",
"reload": "Reload",
"reset_defaults": "Reset to defaults",
"reset_options": "Reset options",
"restart": "Restart",
"restart_name": "Restart {name}",
"running_version": "You are currently running version {version}",
"save": "Save",
"show_more": "Show more information about this",
"update": "Update",
"update_available": "{count, plural,\n one {Update}\n other {{count} Updates}\n} pending",
"version": "Version",
"yes": "Yes"
},
"confirm": {
"reset_options": {
"text": "Are you sure you want to reset all your options?",
"title": "Reset options"
},
"restart": {
"text": "Are you sure you want to restart {name}?",
"title": "Restart {name}"
},
"update": {
"text": "Are you sure you want to update {name} to version {version}?",
"title": "Update {name}"
}
},
"dashboard": {
"addon_new_version": "New version available",
"addon_running": "Add-on is running",
"addon_stopped": "Add-on is stopped",
"addons": "Add-ons",
"no_addons": "You don't have any add-ons installed yet. Head over to the add-on store to get started!"
},
"dialog": {
"network": {
"connected_to": "Connected to {ssid}",
"dhcp": "DHCP",
"disabled": "Disabled",
"dns_servers": "DNS Servers",
"failed_to_change": "Failed to change network settings",
"gateway": "Gateway address",
"ip_netmask": "IP address/Netmask",
"open": "Open",
"scan_ap": "Scan for accesspoints",
"static": "Static",
"title": "Network settings",
"unsaved": "You have unsaved changes, these will get lost if you change tabs, do you want to continue?",
"warning": "If you are changing the Wi-Fi, IP or gateway addresses, you might lose the connection!",
"wep": "WEP",
"wpa": "wpa-psk"
},
"registries": {
"add_new_registry": "Add new registry",
"add_registry": "Add registry",
"failed_to_add": "Failed to add registry",
"failed_to_remove": "Failed to remove registry",
"no_registries": "No registries configured",
"password": "Password",
"registry": "Registry",
"remove": "Remove",
"title_add": "Add New Container Registry",
"title_manage": "Manage Container Registries",
"username": "Username"
},
"repositories": {
"add": "Add",
"remove": "Remove",
"title": "Manage add-on repositories"
},
"restart_addon": {
"confirm_text": "Restart add-on",
"text": "Do you want to restart the add-on with your changes?"
},
"update": {
"create_snapshot": "Create a snapshot of {name} before updating",
"snapshot": "Snapshot",
"snapshotting": "Creating snapshot of {name}",
"updating": "Updating {name} to version {version}"
}
},
"my": {
"error": "An unknown error occured",
"faq_link": "My Home Assistant FAQ",
"not_supported": "This redirect is not supported by your Home Assistant instance. Check the {link} for the supported redirects and the version they where introduced."
},
"panel": {
"dashboard": "Dashboard",
"snapshots": "Snapshots",
"store": "Add-on Store",
"system": "System"
},
"snapshot": {
"addons": "Add-ons",
"available_snapshots": "Available Snapshots",
"could_not_create": "Could not create snapshot",
"create": "Create",
"create_blocked_not_running": "Creating a snapshot is not possible right now because the system is in {state} state.",
"create_snapshot": "Create snapshot",
"description": "Snapshots allow you to easily backup and restore all data of your Home Assistant instance.",
"enter_password": "Please enter a password.",
"folder": {
"addons/local": "Local add-ons",
"homeassistant": "Home Assistant configuration",
"media": "Media",
"share": "Share",
"ssl": "SSL"
},
"folders": "Folders",
"full_snapshot": "Full snapshot",
"name": "Name",
"no_snapshots": "You don't have any snapshots yet.",
"partial_snapshot": "Partial snapshot",
"password": "Password",
"password_protected": "password protected",
"password_protection": "Password protection",
"security": "Security",
"type": "Type",
"upload_snapshot": "Upload snapshot"
},
"store": {
"missing_addons": "Missing add-ons? Enable advanced mode in your user profile page",
"no_results_found": "No results found in {repository}.",
"registries": "Registries",
"repositories": "Repositories"
},
"system": {
"core": {
"cpu_usage": "Core CPU Usage",
"ram_usage": "Core RAM Usage"
},
"host": {
"change": "Change",
"change_hostname": "Change Hostname",
"confirm_reboot": "Are you sure you want to reboot the host?",
"confirm_shutdown": "Are you sure you want to shutdown the host?",
"deployment": "Deployment",
"docker_version": "Docker version",
"emmc_lifetime_used": "eMMC Lifetime Used",
"failed_to_get_hardware_list": "Failed to get hardware list",
"failed_to_import_from_usb": "Failed to import from USB",
"failed_to_reboot": "Failed to reboot the host",
"failed_to_set_hostname": "Setting hostname failed",
"failed_to_shutdown": "Failed to shutdown the host",
"hardware": "Hardware",
"hostname": "Hostname",
"import_from_usb": "Import from USB",
"ip_address": "IP Address",
"new_hostname": "Please enter a new hostname:",
"operating_system": "Operating System",
"reboot_host": "Reboot host",
"shutdown_host": "Shutdown host",
"used_space": "Used space"
},
"log": {
"get_logs": "Failed to get {provider} logs, {error}",
"log_provider": "Log Provider"
},
"supervisor": {
"beta_backup": "Make sure you have backups of your data before you activate this feature.",
"beta_join_confirm": "Do you want to join the beta channel?",
"beta_release_items": "This includes beta releases for:",
"beta_warning": "Beta releases are for testers and early adopters and can contain unstable code changes",
"channel": "Channel",
"cpu_usage": "Supervisor CPU Usage",
"failed_to_reload": "Failed to reload the Supervisor",
"failed_to_set_option": "Failed to set Supervisor option",
"failed_to_update": "Failed to update the Supervisor",
"join_beta_action": "Join beta channel",
"join_beta_description": "Get beta updates for Home Assistant (RCs), Supervisor and host",
"leave_beta_action": "Leave beta channel",
"leave_beta_description": "Get stable updates for Home Assistant, Supervisor and host",
"ram_usage": "Supervisor RAM Usage",
"reload_supervisor": "Reload Supervisor",
"share_diagnostics": "Share Diagnostics",
"share_diagnostics_description": "Share crash reports and diagnostic information.",
"share_diagonstics_description": "Would you want to automatically share crash reports and diagnostic information when the Supervisor encounters unexpected errors? {line_break} This will allow us to fix the problems, the information is only accessible to the Home Assistant Core team and will not be shared with others.{line_break} The data does not include any private/sensitive information and you can disable this in settings at any time you want.",
"share_diagonstics_title": "Help Improve Home Assistant",
"unhealthy_description": "Running an unhealthy installation will cause issues. Below is a list of issues found with your installation, click on the links to learn how you can resolve the issues.",
"unhealthy_reason": {
"docker": "The Docker environment is not working properly",
"privileged": "Supervisor is not privileged",
"setup": "Setup of the Supervisor failed",
"supervisor": "Supervisor was not able to update"
},
"unhealthy_title": "Your installation is unhealthy",
"unsupported_description": "Below is a list of issues found with your installation, click on the links to learn how you can resolve the issues.",
"unsupported_reason": {
"container": "Containers known to cause issues",
"dbus": "DBUS",
"docker_configuration": "Docker Configuration",
"docker_version": "Docker Version",
"job_conditions": "Ignored job conditions",
"lxc": "LXC",
"network_manager": "Network Manager",
"os": "Operating System",
"privileged": "Supervisor is not privileged",
"systemd": "Systemd"
},
"unsupported_title": "You are running an unsupported installation",
"update_supervisor": "Update the Supervisor",
"warning": "WARNING"
}
}
},
"ui": {
"auth_store": {
"ask": "Do you want to stay logged in?",
@@ -762,8 +377,6 @@
"changed_to_state": "changed to {state}",
"cleared_device_class": "cleared (no {device_class} detected)",
"detected_device_class": "detected {device_class}",
"is_closing": "is closing",
"is_opening": "is opening",
"rose": "rose",
"set": "set",
"turned_off": "turned off",
@@ -1019,8 +632,8 @@
"remove_intro": "If the entity is no longer in use, you can clean it up by removing it."
},
"script": {
"last_action": "Last action",
"last_triggered": "Last triggered"
"last_action": "Last Action",
"last_triggered": "Last Triggered"
},
"settings": "Entity settings",
"sun": {
@@ -1084,6 +697,7 @@
"script": "Scripts",
"server_control": "Server Controls",
"tag": "Tags",
"tags": "Tags",
"users": "Users",
"zone": "Zones"
},
@@ -1142,7 +756,6 @@
"clusters": "Manage Clusters",
"reconfigure": "Reconfigure Device",
"remove": "Remove Device",
"view_in_visualization": "View in Visualization",
"zigbee_information": "Zigbee device signature"
},
"confirmations": {
@@ -2720,7 +2333,6 @@
"caption": "Visualization",
"header": "Network Visualization",
"highlight_label": "Highlight Devices",
"refresh_topology": "Refresh Topology",
"zoom_label": "Zoom To Device"
}
},
@@ -3398,8 +3010,6 @@
"error_remove": "Unable to remove configuration: {error}",
"error_save_yaml": "Unable to save YAML: {error}",
"header": "Edit Configuration",
"lovelace_changed": "The Lovelace config was updated, do you want to load the updated config in the editor and lose your current changes?",
"reload": "Reload",
"resources_moved": "Resources should no longer be added to the Lovelace configuration but can be added in the Lovelace config panel.",
"save": "Save",
"saved": "Saved",
+1 -17
View File
@@ -102,23 +102,6 @@
"unknown": "Desconocido"
}
},
"supervisor": {
"common": {
"version": "Versión"
},
"confirm": {
"update": {
"text": "¿Estás seguro de actualizar {name} a la versión {version}?"
}
},
"dashboard": {
"addon_new_version": "Nueva versión disponible",
"addon_running": "El complemento se está ejecutando"
},
"panel": {
"system": "Sistema"
}
},
"ui": {
"auth_store": {
"ask": "¿Desea permanecer conectado?",
@@ -713,6 +696,7 @@
"scene": "Escenas",
"script": "",
"server_control": "Controles del servidor",
"tags": "Etiquetas",
"users": "Usuarios",
"zone": "Zonas"
},
+1
View File
@@ -697,6 +697,7 @@
"script": "Scripts",
"server_control": "Controles del servidor",
"tag": "Etiquetas",
"tags": "Etiquetas",
"users": "Usuarios",
"zone": "Zonas"
},
+3 -44
View File
@@ -102,42 +102,6 @@
"unknown": "Teadmata"
}
},
"supervisor": {
"addon": {
"panel": {
"configuration": "Seaded",
"documentation": "Dokumentatsioon",
"info": "Info",
"log": "Logikirjed"
}
},
"common": {
"cancel": "Loobu",
"newest_version": "Uusim versioon",
"release_notes": "Väljalaske teave",
"update": "Uuenda",
"version": "Versioon"
},
"confirm": {
"update": {
"text": "Kas soovid kindlasti värskendada {name} versioonile {version}?",
"title": "Uuenda {name}"
}
},
"dashboard": {
"addon_new_version": "Uus versioon on saadaval",
"addon_running": "Lisandmoodul töötab",
"addon_stopped": "Lisandmoodul on peatatud",
"addons": "Lisandmoodulid",
"no_addons": "Ühtegi lisandmoodulit pole veel paigaldatud. Alustamiseks mine lisandmoodulite hoidlasse!"
},
"panel": {
"dashboard": "Kasutajaliidese vaade",
"snapshots": "Hetke varukoopia",
"store": "Lisandmoodulite hoidla",
"system": "Süsteem"
}
},
"ui": {
"auth_store": {
"ask": "Kas Te soovite jääda sisselogituks selles seadmes?",
@@ -413,8 +377,6 @@
"changed_to_state": "muutus olekusse {state}",
"cleared_device_class": "lõpetatud ( {device_class} ei leitud)",
"detected_device_class": "tuvastati {device_class}",
"is_closing": "sulgub",
"is_opening": "avaneb",
"rose": "tõusis",
"set": "määratud",
"turned_off": "lülitus välja",
@@ -670,8 +632,8 @@
"remove_intro": "Kui olemit enam ei kasutata, võid selle eemaldada."
},
"script": {
"last_action": "Viimatine tegevus",
"last_triggered": "Viimati käivitatud"
"last_action": "Viimane tegevus",
"last_triggered": "Viimati vallandunud"
},
"settings": "Olemi seaded",
"sun": {
@@ -735,6 +697,7 @@
"script": "Scriptid",
"server_control": "Serveri juhtimine",
"tag": "Märgised",
"tags": "Märgised",
"users": "Kasutajad",
"zone": "Tsoonid"
},
@@ -793,7 +756,6 @@
"clusters": "Halda seadmekobaraid",
"reconfigure": "Muuda seadme sätteid",
"remove": "Eemalda seade",
"view_in_visualization": "Visualiseeri",
"zigbee_information": "Zigbee seadme tunnus"
},
"confirmations": {
@@ -2371,7 +2333,6 @@
"caption": "Visualiseerimine",
"header": "Võrgu visualiseerimine",
"highlight_label": "Tõsta seadmed esile",
"refresh_topology": "Värskenda seadmete kaarti",
"zoom_label": "Näita seadet"
}
},
@@ -3049,8 +3010,6 @@
"error_remove": "Konfiguratsiooni ei saa eemaldada: {error}",
"error_save_yaml": "YAML-i ei saa salvestada: {error}",
"header": "Muuda seadeid",
"lovelace_changed": "Lovelace'i konfiguratsiooni värskendati, kas soovid uuendatud konfiguratsiooni redaktorisse laadida ja oma praegused muudatused kaotada?",
"reload": "Taaslae",
"resources_moved": "Ressursse ei tohiks enam lisada Lovelace konfiguratsiooni kuid saab lisada Lovelace config paneeli.",
"save": "Salvesta",
"saved": "Salvestatud",
+1
View File
@@ -658,6 +658,7 @@
"person": "Henkilöt",
"script": "Skriptit",
"server_control": "Palvelimen hallinta",
"tags": "Tägit",
"users": "Käyttäjät",
"zone": "Alueet"
},
+1
View File
@@ -697,6 +697,7 @@
"script": "Scripts",
"server_control": "Contrôle du serveur",
"tag": "Balises",
"tags": "Balises",
"users": "Utilisateurs",
"zone": "Zones"
},
+1
View File
@@ -664,6 +664,7 @@
"scene": "Jelenetek",
"script": "Szkriptek",
"server_control": "Szerver vezérlés",
"tags": "Címkék",
"users": "Felhasználók",
"zone": "Zónák"
},
+1 -42
View File
@@ -100,42 +100,6 @@
"unknown": "Tidak diketahui"
}
},
"supervisor": {
"addon": {
"panel": {
"configuration": "Konfigurasi",
"documentation": "Dokumentasi",
"info": "Info",
"log": "Log"
}
},
"common": {
"cancel": "Batalkan",
"newest_version": "Versi Terbaru",
"release_notes": "Catatan rilis",
"update": "Perbarui",
"version": "Versi:"
},
"confirm": {
"update": {
"text": "Yakin ingin memperbarui {name} ke versi {version}?",
"title": "Perbarui {name}"
}
},
"dashboard": {
"addon_new_version": "Versi baru tersedia",
"addon_running": "Add-on sedang berjalan",
"addon_stopped": "Add-on dihentikan",
"addons": "Add-on",
"no_addons": "Anda belum memasang add-on apa pun. Kunjungi toko add-on untuk memulai!"
},
"panel": {
"dashboard": "Dasbor",
"snapshots": "Snapshot",
"store": "Toko Add-on",
"system": "Sistem"
}
},
"ui": {
"auth_store": {
"ask": "Ingin menyimpan login ini?",
@@ -410,8 +374,6 @@
"changed_to_state": "berubah menjadi {state}",
"cleared_device_class": "dibersihkan (tidak ada {device_class} yang terdeteksi)",
"detected_device_class": "terdeteksi {device_class}",
"is_closing": "menutup",
"is_opening": "membuka",
"rose": "terbit",
"set": "terbenam",
"turned_off": "dimatikan",
@@ -730,6 +692,7 @@
"script": "Skrip",
"server_control": "Kontrol Server",
"tag": "Tag",
"tags": "Tag",
"users": "Pengguna",
"zone": "Zona"
},
@@ -788,7 +751,6 @@
"clusters": "Kelola Cluster",
"reconfigure": "Konfigurasi Ulang Perangkat",
"remove": "Hapus Perangkat",
"view_in_visualization": "Tampilkan dalam Visualisasi",
"zigbee_information": "Tanda tangan perangkat Zigbee"
},
"confirmations": {
@@ -2366,7 +2328,6 @@
"caption": "Visualisasi",
"header": "Visualisasi Jaringan",
"highlight_label": "Sorot Perangkat",
"refresh_topology": "Segarkan Topologi",
"zoom_label": "Perbesar Ke Perangkat"
}
},
@@ -3033,8 +2994,6 @@
"error_remove": "Tidak dapat menghapus konfigurasi: {error}",
"error_save_yaml": "Tidak dapat menyimpan YAML: {error}",
"header": "Edit Konfigurasi",
"lovelace_changed": "Konfigurasi Lovelace telah diperbarui. Ingin memuat konfigurasi yang diperbarui di editor dan kehilangan perubahan Anda saat ini?",
"reload": "Muat Ulang",
"resources_moved": "Sumber daya seharusnya tidak lagi ditambahkan ke konfigurasi Lovelace tetapi dapat ditambahkan di panel konfigurasi Lovelace.",
"save": "Simpan",
"saved": "Disimpan",
+1
View File
@@ -466,6 +466,7 @@
"person": "Persónur",
"scene": "Senur",
"script": "Skriftur",
"tags": "Strikamerki",
"users": "Notendur",
"zone": "Svæði"
},
+1 -392
View File
@@ -102,391 +102,6 @@
"unknown": "Sconosciuto"
}
},
"supervisor": {
"addon": {
"configuration": {
"audio": {
"default": "Predefinito",
"header": "Audio",
"input": "Ingresso",
"output": "Uscita"
},
"network": {
"container": "Container",
"disabled": "Disabilitato",
"header": "Rete",
"host": "Host"
},
"no_configuration": "Questo componente aggiuntivo non espone la sua configurazione per fartela pasticciare...",
"options": {
"edit_in_ui": "Modifica nell'interfaccia utente",
"edit_in_yaml": "Modifica in YAML",
"header": "Opzioni",
"invalid_yaml": "YAML non valido",
"show_unused_optional": "Mostra opzioni di configurazione facoltative inutilizzate"
}
},
"dashboard": {
"action_error": {
"get_changelog": "Impossibile ottenere il registro delle modifiche del componente aggiuntivo",
"go_to_config": "Impossibile avviare il componente aggiuntivo - convalida della configurazione non riuscita!",
"install": "Impossibile installare il componente aggiuntivo",
"restart": "Impossibile riavviare il componente aggiuntivo",
"start": "Impossibile avviare il componente aggiuntivo",
"start_invalid_config": "Vai alla configurazione",
"stop": "Impossibile arrestare il componente aggiuntivo",
"uninstall": "Impossibile disinstallare il componente aggiuntivo",
"validate_config": "Impossibile convalidare la configurazione del componente aggiuntivo"
},
"capability": {
"apparmor": {
"description": "AppArmor (\"Application Armor\") è un modulo di sicurezza del kernel Linux che limita le funzionalità dei componenti aggiuntivi come l'accesso alla rete, l'accesso raw socket e l'autorizzazione a leggere, scrivere o eseguire file specifici. \n\nGli autori di componenti aggiuntivi possono fornire i propri profili di sicurezza, ottimizzati per il componente aggiuntivo o richiederne la disabilitazione. Se AppArmor è disabilitato, aumenterà i rischi per la sicurezza e, di conseguenza, avrà un impatto negativo sul punteggio di sicurezza del componente aggiuntivo.",
"title": "AppArmor"
},
"auth_api": {
"description": "Un componente aggiuntivo può autenticare gli utenti rispetto a Home Assistant, consentendo ai componenti aggiuntivi la possibilità di offrire agli utenti l'accesso alle applicazioni in esecuzione all'interno dei componenti aggiuntivi stessi, utilizzando il proprio nome utente/password di Home Assistant. Questo distintivo indica se l'autore del componente aggiuntivo richiede questa funzionalità.",
"title": "Autenticazione di Home Assistant"
},
"docker_api": {
"description": "L'autore del componente aggiuntivo ha richiesto al componente aggiuntivo di avere accesso alla gestione dell'istanza Docker in esecuzione nel sistema. Questa modalità offre al componente aggiuntivo l'accesso completo e il controllo all'intero sistema Home Assistant, il che aggiunge rischi per la sicurezza e potrebbe danneggiare il sistema in caso di uso improprio. Pertanto, questa funzionalità influisce negativamente sul punteggio di sicurezza del componente aggiuntivo.\n\nQuesto livello di accesso non viene concesso automaticamente e deve essere confermato dall'utente. Per fare ciò, è necessario disabilitare manualmente la modalità di protezione sul componente aggiuntivo. Disabilitare la modalità di protezione solo se si sa, è necessario e considerare attendibile l'origine di questo componente aggiuntivo.",
"title": "Accesso completo a Docker"
},
"full_access": {
"description": "Questo componente aggiuntivo ha pieno accesso all'hardware del sistema, su richiesta dell'autore del componente aggiuntivo. L'accesso è paragonabile alla modalità privilegiata in Docker. Poiché ciò apre possibili rischi per la sicurezza, questa funzionalità influisce negativamente sul punteggio di sicurezza aggiuntivo.\n\nQuesto livello di accesso non viene concesso automaticamente e deve essere confermato dall'utente. Per fare ciò, è necessario disabilitare manualmente la modalità di protezione sul componente aggiuntivo. Disabilitare la modalità di protezione solo se si sa, è necessario e considerare attendibile l'origine di questo componente aggiuntivo.",
"title": "Accesso completo all'hardware"
},
"hassio_api": {
"description": "Al componente aggiuntivo è stato concesso l'accesso all'API Supervisor, su richiesta dell'autore del componente aggiuntivo. Per impostazione predefinita, il componente aggiuntivo può accedere alle informazioni generali sulla versione del sistema. Quando il componente aggiuntivo richiede l'accesso all'API a livello di \"manager\" o \"admin\", avrà accesso per controllare più parti del sistema Home Assistant. Questa autorizzazione è indicata da questo distintivo e avrà un impatto negativo sul punteggio di sicurezza del componente aggiuntivo.",
"title": "Accesso API Supervisor"
},
"homeassistant_api": {
"description": "Questo componente aggiuntivo può accedere all'istanza di Home Assistant in esecuzione direttamente tramite l'API di Home Assistant. Questa modalità gestisce anche l'autenticazione per il componente aggiuntivo, che consente a un componente aggiuntivo di interagire con Home Assistant senza la necessità di token di autenticazione aggiuntivi.",
"title": "Accesso all'API di Home Assistant"
},
"host_network": {
"description": "I componenti aggiuntivi vengono in genere eseguiti nel proprio livello di rete isolato, impedendo loro di accedere alla rete del sistema operativo host. In alcuni casi, questo isolamento della rete può limitare i componenti aggiuntivi nella fornitura dei propri servizi e, pertanto, l'isolamento può essere revocato dall'autore del componente aggiuntivo, offrendo al componente aggiuntivo l'accesso completo alle funzionalità di rete del computer host. In questo modo il componente aggiuntivo offre più funzionalità di rete, ma riduce la sicurezza, pertanto la classificazione di sicurezza del componente aggiuntivo verrà abbassata quando questa opzione viene utilizzata dal componente aggiuntivo.",
"title": "Rete host"
},
"host_pid": {
"description": "In genere, i processi che il componente aggiuntivo esegue, sono isolati da tutti gli altri processi di sistema. L'autore del componente aggiuntivo ha richiesto al componente aggiuntivo di avere accesso ai processi di sistema in esecuzione nell'istanza del sistema host e di consentire al componente aggiuntivo di generare processi anche nel sistema host. Questa modalità offre al componente aggiuntivo l'accesso completo e il controllo all'intero sistema Home Assistant, il che aggiunge rischi per la sicurezza e potrebbe danneggiare il sistema in caso di uso improprio. Pertanto, questa funzionalità influisce negativamente sul punteggio di sicurezza del componente aggiuntivo.\n\nQuesto livello di accesso non viene concesso automaticamente e deve essere confermato dall'utente. Per fare ciò, è necessario disabilitare manualmente la modalità di protezione sul componente aggiuntivo. Disabilitare la modalità di protezione solo se si sa, è necessario e considerare attendibile l'origine di questo componente aggiuntivo.",
"title": "Spazio dei nomi dei processi host"
},
"ingress": {
"description": "Questo componente aggiuntivo utilizza Ingress per incorporare la sua interfaccia in modo sicuro in Home Assistant.",
"title": "Ingress"
},
"label": {
"apparmor": "apparmor",
"auth": "auth",
"docker": "docker",
"hardware": "hardware",
"hass": "hass",
"hassio": "hassio",
"host": "host",
"host_pid": "host pid",
"ingress": "ingress",
"rating": "valutazione",
"stage": "fase"
},
"rating": {
"description": "Home Assistant fornisce una classificazione di sicurezza a ciascuno dei componenti aggiuntivi, che indica i rischi connessi all'utilizzo di questo componente aggiuntivo. Maggiore è l'accesso necessario a un componente aggiuntivo sul sistema, minore è il punteggio, aumentando così i possibili rischi per la sicurezza.\n\nIl punteggio è su una scala da 1 a 6. Dove 1 è il punteggio più basso (considerato il più insicuro ed a rischio più alto) e un punteggio di 6 è il punteggio più alto (considerato il più sicuro ed a rischio più basso).",
"title": "Classificazione di sicurezza del componente aggiuntivo"
},
"role": {
"admin": "admin",
"backup": "backup",
"default": "predefinito",
"homeassistant": "homeassistant",
"manager": "manager"
},
"stage": {
"description": "I componenti aggiuntivi possono avere una delle tre fasi seguenti:\n\n{icon_stable} **Stabile**: si tratta di componenti aggiuntivi pronti per l'uso in produzione.\n\n{icon_experimental} **Sperimentale**: questi possono contenere bug e potrebbero non essere completati.\n\n{icon_deprecated} **Deprecato**: questi componenti aggiuntivi non riceveranno più aggiornamenti.",
"title": "Fase del componente aggiuntivo"
}
},
"changelog": "Registro delle modifiche",
"cpu_usage": "Utilizzo CPU componente aggiuntivo",
"hostname": "Nome host",
"install": "installa",
"new_update_available": "{name} {version} è disponibile",
"not_available_arch": "Questo componente aggiuntivo non è compatibile con il processore del dispositivo o con il sistema operativo installato nel dispositivo.",
"not_available_version": "Stai eseguendo Home Assistant {core_version_installed}, per aggiornare a questa versione del componente aggiuntivo è necessaria almeno la versione {core_version_needed} di Home Assistant",
"open_web_ui": "Apri l'interfaccia utente web",
"option": {
"auto_update": {
"description": "Aggiorna automaticamente il componente aggiuntivo quando è disponibile una nuova versione",
"title": "Aggiornamento automatico"
},
"boot": {
"description": "Avvia il componente aggiuntivo durante l'avvio del sistema",
"title": "Inizia dall'avvio"
},
"ingress_panel": {
"description": "Aggiungi questo componente aggiuntivo alla barra laterale",
"title": "Mostra nella barra laterale"
},
"protected": {
"description": "Blocca l'accesso al sistema con privilegi elevati dal componente aggiuntivo",
"title": "Modalità di protezione"
},
"watchdog": {
"description": "Questo avvierà il componente aggiuntivo se si arresta in modo anomalo",
"title": "Watchdog"
}
},
"protection_mode": {
"content": "La modalità di protezione su questo componente aggiuntivo è disabilitata! Questo dà al componente aggiuntivo pieno accesso all'intero sistema, il che aggiunge rischi per la sicurezza e potrebbe danneggiare il tuo sistema se usato in modo scorretto. Disabilita la modalità di protezione solo se conosci, hai bisogno e ti fidi della fonte di questo componente aggiuntivo.",
"enable": "Abilita la modalità di protezione",
"title": "Attenzione: la modalità di protezione è disabilitata!"
},
"ram_usage": "Utilizzo RAM componente aggiuntivo",
"rebuild": "ricostruisci",
"restart": "Riavvia",
"start": "avvia",
"stop": "ferma",
"uninstall": "disinstalla",
"visit_addon_page": "Visita la pagina di {name} per maggiori dettagli"
},
"documentation": {
"get_documentation": "Impossibile ottenere la documentazione del componente aggiuntivo, {error}"
},
"failed_to_reset": "Impossibile reimpostare la configurazione del componente aggiuntivo, {error}",
"failed_to_save": "Impossibile salvare la configurazione del componente aggiuntivo, {error}",
"logs": {
"get_logs": "Impossibile ottenere i registri del componente aggiuntivo, {error}"
},
"panel": {
"configuration": "Configurazione",
"documentation": "Documentazione",
"info": "Informazioni",
"log": "Registro"
},
"state": {
"installed": "Il componente aggiuntivo è installato",
"not_available": "Il componente aggiuntivo non è disponibile sul tuo sistema",
"not_installed": "Il componente aggiuntivo non è installato"
}
},
"common": {
"cancel": "Annulla",
"description": "Descrizione",
"error": {
"unknown": "Errore sconosciuto",
"update_failed": "Aggiornamento non riuscito"
},
"failed_to_restart_name": "Impossibile riavviare {name}",
"failed_to_update_name": "Impossibile aggiornare {name}",
"learn_more": "Ulteriori informazioni",
"new_version_available": "Nuova versione disponibile",
"newest_version": "Ultima versione",
"no": "No",
"refresh": "Aggiorna",
"release_notes": "Note sulla versione",
"reload": "Ricarica",
"reset_defaults": "Ripristina le impostazioni predefinite",
"reset_options": "Ripristina le opzioni",
"restart": "Riavvia",
"restart_name": "Riavvia {name}",
"running_version": "È attualmente in esecuzione la versione {version}",
"save": "Salva",
"show_more": "Ulteriori informazioni al riguardo",
"update": "Aggiorna",
"update_available": "{count, plural,\n one {aggiornamento}\n other {{count} aggiornamenti}\n} in sospeso",
"version": "Versione",
"yes": "Sì"
},
"confirm": {
"reset_options": {
"text": "Reimpostare tutte le opzioni?",
"title": "Ripristina le opzioni"
},
"restart": {
"text": "Riavviare {name}?",
"title": "Riavvia {name}"
},
"update": {
"text": "Aggiornare {name} alla versione {version}?",
"title": "Aggiorna {name}"
}
},
"dashboard": {
"addon_new_version": "Nuova versione disponibile",
"addon_running": "Il componente aggiuntivo è in esecuzione",
"addon_stopped": "Il componente aggiuntivo viene arrestato",
"addons": "Componenti aggiuntivi",
"no_addons": "Non hai ancora installato alcun componente aggiuntivo. Vai al negozio di componenti aggiuntivi per iniziare!"
},
"dialog": {
"network": {
"connected_to": "Connesso a {ssid}",
"dhcp": "DHCP",
"disabled": "Disabilitato",
"dns_servers": "Server DNS",
"failed_to_change": "Impossibile modificare le impostazioni di rete",
"gateway": "Indirizzo del gateway",
"ip_netmask": "Indirizzo IP/Netmask",
"open": "Aperto",
"scan_ap": "Scansione dei punti di accesso",
"static": "Statico",
"title": "Impostazioni di rete",
"unsaved": "Hai modifiche non salvate, queste andranno perse se cambi scheda, vuoi continuare?",
"warning": "Se stai modificando gli indirizzi Wi-Fi, IP o gateway, potresti perdere la connessione!",
"wep": "WEP",
"wpa": "WPA-PSK"
},
"registries": {
"add_new_registry": "Aggiungi nuovo registro",
"add_registry": "Aggiungi registro",
"failed_to_add": "Impossibile aggiungere il registro",
"failed_to_remove": "Impossibile rimuovere il registro",
"no_registries": "Nessun registro configurato",
"password": "Password",
"registry": "Registro",
"remove": "Rimuovi",
"title_add": "Aggiungi nuovo registro container",
"title_manage": "Gestisci i registri dei container",
"username": "Nome utente"
},
"repositories": {
"add": "Aggiungi",
"remove": "Rimuovi",
"title": "Gestisci i repository dei componenti aggiuntivi"
},
"restart_addon": {
"confirm_text": "Riavvia il componente aggiuntivo",
"text": "Riavviare il componente aggiuntivo con le modifiche?"
},
"update": {
"create_snapshot": "Creare un'istantanea di {name} prima dell'aggiornamento",
"snapshot": "Istantanea",
"snapshotting": "Creazione istantanea di {name}",
"updating": "Aggiornamento di {name} alla versione {version}"
}
},
"my": {
"error": "Si è verificato un errore sconosciuto",
"faq_link": "My Home Assistant FAQ",
"not_supported": "Questo reindirizzamento non è supportato dall'istanza di Home Assistant. Controlla il {link} per i reindirizzamenti supportati e la versione in cui sono stati introdotti."
},
"panel": {
"dashboard": "Pannello di controllo",
"snapshots": "Istantanee",
"store": "Negozio dei componenti aggiuntivi",
"system": "Sistema"
},
"snapshot": {
"addons": "Componenti aggiuntivi",
"available_snapshots": "Istantanee disponibili",
"could_not_create": "Impossibile creare l'istantanea",
"create": "Crea",
"create_blocked_not_running": "La creazione di un'istantanea non è al momento possibile perché il sistema è nello stato {state}.",
"create_snapshot": "Crea istantanea",
"description": "Le istantanee ti consentono di eseguire facilmente il backup e il ripristino di tutti i dati dell'istanza di Home Assistant.",
"enter_password": "Immettere una password.",
"folder": {
"addons/local": "Componenti aggiuntivi locali",
"homeassistant": "Configurazione di Home Assistant",
"media": "Media",
"share": "Share",
"ssl": "SSL"
},
"folders": "Cartelle",
"full_snapshot": "Istantanea completa",
"name": "Nome",
"no_snapshots": "Non hai ancora nessuna istantanea.",
"partial_snapshot": "Istantanea parziale",
"password": "Password",
"password_protected": "protetto da password",
"password_protection": "Protezione con password",
"security": "Sicurezza",
"type": "Tipo",
"upload_snapshot": "Invia istantanea"
},
"store": {
"missing_addons": "Componenti aggiuntivi mancanti? Abilita la modalità avanzata nella pagina del tuo profilo utente",
"no_results_found": "Nessun risultato trovato in {repository}.",
"registries": "Registri",
"repositories": "Repository"
},
"system": {
"core": {
"cpu_usage": "Utilizzo della CPU principale",
"ram_usage": "Utilizzo della RAM principale"
},
"host": {
"change": "Cambia",
"change_hostname": "Cambia nome host",
"confirm_reboot": "Riavviare l'host?",
"confirm_shutdown": "Arrestare l'host?",
"deployment": "Distribuzione",
"docker_version": "Versione Docker",
"emmc_lifetime_used": "Durata eMMC usata",
"failed_to_get_hardware_list": "Impossibile ottenere l'elenco hardware",
"failed_to_import_from_usb": "Importazione da USB non riuscita",
"failed_to_reboot": "Impossibile riavviare l'host",
"failed_to_set_hostname": "Impostazione del nome host non riuscita",
"failed_to_shutdown": "Impossibile arrestare l'host",
"hardware": "Hardware",
"hostname": "Nome host",
"import_from_usb": "Importa da USB",
"ip_address": "Indirizzo IP",
"new_hostname": "Inserisci un nuovo nome host:",
"operating_system": "Sistema operativo",
"reboot_host": "Riavvia host",
"shutdown_host": "Arresta host",
"used_space": "Spazio utilizzato"
},
"log": {
"get_logs": "Impossibile ottenere i registri di {provider}, {error}",
"log_provider": "Fornitore del registro"
},
"supervisor": {
"beta_backup": "Assicurati di disporre di backup dei tuoi dati prima di attivare questa funzione.",
"beta_join_confirm": "Vuoi entrare a far parte del canale beta?",
"beta_release_items": "Questo include le versioni beta per:",
"beta_warning": "Le versioni beta sono per \"tester\" e \"early adopter\" e possono contenere modifiche al codice instabili",
"channel": "Canale",
"cpu_usage": "Utilizzo CPU Supervisor",
"failed_to_reload": "Impossibile ricaricare il Supervisor",
"failed_to_set_option": "Impossibile impostare l'opzione Supervisor",
"failed_to_update": "Impossibile aggiornare il Supervisor",
"join_beta_action": "Partecipa al canale beta",
"join_beta_description": "Ricevi gli aggiornamenti beta per Home Assistant (RC), Supervisor e host",
"leave_beta_action": "Lascia il canale beta",
"leave_beta_description": "Ricevi aggiornamenti stabili per Home Assistant, Supervisor e host",
"ram_usage": "Utilizzo RAM Supervisor",
"reload_supervisor": "Ricarica Supervisor",
"share_diagnostics": "Condividi diagnostica",
"share_diagnostics_description": "Condividi i rapporti sugli arresti anomali e le informazioni diagnostiche.",
"share_diagonstics_description": "Vorresti condividere automaticamente i rapporti sugli arresti anomali e le informazioni diagnostiche quando il Supervisor rileva errori imprevisti? {line_break} Questo ci consentirà di risolvere i problemi, le informazioni sono accessibili solo al team di Home Assistant Core e non saranno condivise con altri. {line_break} I dati non includono alcuna informazione privata/sensibile e puoi disabilitarla nelle impostazioni in qualsiasi momento lo desideri.",
"share_diagonstics_title": "Aiutaci a migliorare Home Assistant",
"unhealthy_description": "L'esecuzione di un'installazione non funzionante causerà problemi. Di seguito è riportato un elenco dei problemi riscontrati con l'installazione, fare clic sui collegamenti per scoprire come risolvere i problemi.",
"unhealthy_reason": {
"docker": "L'ambiente Docker non funziona correttamente",
"privileged": "Il Supervisor non è privilegiato",
"setup": "Configurazione del Supervisor non riuscita",
"supervisor": "Il Supervisor non è stato in grado di aggiornare"
},
"unhealthy_title": "L'installazione non è integra",
"unsupported_description": "Di seguito è riportato un elenco dei problemi riscontrati con l'installazione, fare clic sui collegamenti per scoprire come risolvere i problemi.",
"unsupported_reason": {
"container": "Container noti per causare problemi",
"dbus": "DBUS",
"docker_configuration": "Configurazione Docker",
"docker_version": "Versione Docker",
"job_conditions": "Condizioni di lavoro ignorate",
"lxc": "LXC",
"network_manager": "Gestione della rete",
"os": "Sistema operativo",
"privileged": "Il Supervisor non è privilegiato",
"systemd": "Systemd"
},
"unsupported_title": "Stai eseguendo un'installazione non supportata",
"update_supervisor": "Aggiorna il Supervisor",
"warning": "ATTENZIONE"
}
}
},
"ui": {
"auth_store": {
"ask": "Vuoi rimanere connesso?",
@@ -762,8 +377,6 @@
"changed_to_state": "cambiato in {state}",
"cleared_device_class": "sgombro (nessun {device_class} rilevato)",
"detected_device_class": "rilevato {device_class}",
"is_closing": "in chiusura",
"is_opening": "in apertura",
"rose": "sorto",
"set": "tramontato",
"turned_off": "spento",
@@ -1083,7 +696,7 @@
"scene": "Scene",
"script": "Script",
"server_control": "Controlli del Server",
"tag": "Etichette",
"tags": "Etichette",
"users": "Utenti",
"zone": "Zone"
},
@@ -1142,7 +755,6 @@
"clusters": "Gestisci i cluster",
"reconfigure": "Riconfigura dispositivo",
"remove": "Rimuovi dispositivo",
"view_in_visualization": "Visualizza in visualizzazione",
"zigbee_information": "Firma del dispositivo Zigbee"
},
"confirmations": {
@@ -2720,7 +2332,6 @@
"caption": "Visualizzazione",
"header": "Visualizzazione di rete",
"highlight_label": "Evidenzia dispositivi",
"refresh_topology": "Aggiorna la topologia",
"zoom_label": "Ingrandisci al dispositivo"
}
},
@@ -3398,8 +3009,6 @@
"error_remove": "Impossibile rimuovere la configurazione: {error}",
"error_save_yaml": "Impossibile salvare YAML: {error}",
"header": "Modifica Configurazione",
"lovelace_changed": "La configurazione di Lovelace è stata aggiornata, vuoi caricare la configurazione aggiornata nell'editor e perdere le modifiche attuali?",
"reload": "Ricarica",
"resources_moved": "Le risorse non dovrebbero più essere aggiunte alla configurazione di Lovelace ma possono essere aggiunte nel pannello di configurazione di Lovelace.",
"save": "Salva",
"saved": "Salvato",
+1 -13
View File
@@ -96,16 +96,6 @@
"unknown": "不明"
}
},
"supervisor": {
"common": {
"cancel": "キャンセル"
},
"confirm": {
"update": {
"title": "{name}更新"
}
}
},
"ui": {
"auth_store": {
"ask": "このログインの保存をよろしいですか?",
@@ -469,9 +459,6 @@
"week": "{count} {count, plural,\n one {週}\n other {週}前\n}"
}
},
"service-control": {
"target": "ターゲット"
},
"service-picker": {
"service": "サービス"
},
@@ -681,6 +668,7 @@
"scene": "シーン",
"script": "スクリプト",
"server_control": "サーバーコントロール",
"tags": "タグ",
"users": "ユーザー",
"zone": "場所"
},
+1
View File
@@ -638,6 +638,7 @@
"scene": "씬",
"script": "스크립트",
"server_control": "서버 제어",
"tags": "태그",
"users": "사용자",
"zone": "지역"
},
+1
View File
@@ -650,6 +650,7 @@
"scene": "Zeene",
"script": "Skripte",
"server_control": "Server Kontrolle",
"tags": "Tags",
"users": "Benotzer",
"zone": "Zone"
},
+1
View File
@@ -230,6 +230,7 @@
"scene": "Scenos",
"script": "Skriptai",
"server_control": "Serverio valdikliai",
"tags": "Žymės",
"users": "Vartotojai",
"zone": "Zonos"
}
+1 -42
View File
@@ -102,42 +102,6 @@
"unknown": "Ukjent"
}
},
"supervisor": {
"addon": {
"panel": {
"configuration": "Konfigurasjon",
"documentation": "Dokumentasjon",
"info": "Info",
"log": "Logg"
}
},
"common": {
"cancel": "Avbryt",
"newest_version": "Nyeste versjon",
"release_notes": "Utgivelsesmerknader",
"update": "Oppdater",
"version": "Versjon"
},
"confirm": {
"update": {
"text": "Er du sikker på at du vil oppdatere {name} til version {version} ?",
"title": "Oppdater {name}"
}
},
"dashboard": {
"addon_new_version": "Ny versjon tilgjengelig",
"addon_running": "Tillegget kjører",
"addon_stopped": "Tillegget er stoppet",
"addons": "Tillegg",
"no_addons": "Du har ikke installert tilleggsprogrammer ennå. Gå over til tilleggsbutikken for å komme i gang!"
},
"panel": {
"dashboard": "Dashboard",
"snapshots": "Snapshots",
"store": "Tilleggsbutikk",
"system": "System"
}
},
"ui": {
"auth_store": {
"ask": "Vil du forbli innlogget på denne enheten?",
@@ -413,8 +377,6 @@
"changed_to_state": "endret til {state}",
"cleared_device_class": "klar (ingen {device_class} oppdaget)",
"detected_device_class": "oppdaget {device_class}",
"is_closing": "stenger",
"is_opening": "åpner",
"rose": "soloppgang",
"set": "solnedgang",
"turned_off": "slått av",
@@ -735,6 +697,7 @@
"script": "Skript",
"server_control": "Server-kontroller",
"tag": "Tagger",
"tags": "Tagger",
"users": "Brukere",
"zone": "Soner"
},
@@ -793,7 +756,6 @@
"clusters": "Behandle Clusters",
"reconfigure": "Rekonfigurer enhet",
"remove": "Fjern enhet",
"view_in_visualization": "Visning i visualisering",
"zigbee_information": "ZigBee-enhetssignatur"
},
"confirmations": {
@@ -2371,7 +2333,6 @@
"caption": "Visualisering",
"header": "Nettverksvisualisering",
"highlight_label": "Fremhev enheter",
"refresh_topology": "Oppdater topologi",
"zoom_label": "Zoom til enhet"
}
},
@@ -3049,8 +3010,6 @@
"error_remove": "Kan ikke fjerne konfigurasjonen: {error}",
"error_save_yaml": "Kan ikke lagre YAML: {error}",
"header": "Rediger konfigurasjon",
"lovelace_changed": "Lovelace-konfigurasjonen ble oppdatert, vil du laste den oppdaterte konfigurasjonen i redigeringsprogrammet og miste gjeldende endringer?",
"reload": "Last inn på nytt",
"resources_moved": "Ressurser skal ikke lenger legges til Lovelace-konfigurasjonen, men kan legges til i Lovelace-konfigurasjonspanelet.",
"save": "Lagre",
"saved": "Lagret",
+1 -31
View File
@@ -102,37 +102,6 @@
"unknown": "Onbekend"
}
},
"supervisor": {
"addon": {
"dashboard": {
"option": {
"boot": {
"title": "Start bij opstarten"
},
"ingress_panel": {
"title": "Weergeven in zijbalk"
}
}
}
},
"common": {
"description": "Omschrijving",
"learn_more": "Meer informatie",
"new_version_available": "Nieuwe versie beschikbaar"
},
"dialog": {
"update": {
"snapshotting": "Maak een snapshot van {name}"
}
},
"system": {
"supervisor": {
"beta_join_confirm": "Wil je meedoen met de bèta releases?",
"reload_supervisor": "Herlaad de Supervisor",
"share_diagonstics_title": "Help Home Assistant te verbeteren"
}
}
},
"ui": {
"auth_store": {
"ask": "Wil je ingelogd blijven?",
@@ -728,6 +697,7 @@
"script": "Scripts",
"server_control": "Server Controls",
"tag": "Tags",
"tags": "Tags",
"users": "Gebruikers",
"zone": "Zones"
},
+4 -150
View File
@@ -86,42 +86,6 @@
"unknown": "Ukjent"
}
},
"supervisor": {
"addon": {
"panel": {
"configuration": "Konfigurasjon ",
"documentation": "Dokumentasjon ",
"info": "Info",
"log": "Logg"
}
},
"common": {
"cancel": "Avbryt",
"newest_version": "Nyaste versjon",
"release_notes": "Utgjevingsnotat",
"update": "Oppdater ",
"version": "Versjon"
},
"confirm": {
"update": {
"text": "Er du sikker på at du vil oppdatere {name} til versjon {version}",
"title": "Oppdater {name}"
}
},
"dashboard": {
"addon_new_version": "Ny versjon tilgjengeleg",
"addon_running": "Tillegg køyrer",
"addon_stopped": "Tillegg stoppa",
"addons": "Tillegg",
"no_addons": "Du har ikkje installert nokon tillegg endå. Gå til tilleggsbutikken for å kome i gang!"
},
"panel": {
"dashboard": "Skrivebord",
"snapshots": "Snapshots",
"store": "Tillegsbutikk",
"system": "System"
}
},
"ui": {
"auth_store": {
"ask": "Vil du lagre denne pålogginga?",
@@ -165,7 +129,6 @@
"direction": "Retning",
"forward": "Framover",
"oscillate": "Sving",
"preset_mode": "Malmodus",
"reverse": "Bakover",
"speed": "Fart"
},
@@ -193,8 +156,7 @@
},
"script": {
"cancel": "Avbryt",
"cancel_multiple": "Avbryt {number}",
"run": "Køyr"
"cancel_multiple": "Avbryt {number}"
},
"service": {
"run": "Køyr"
@@ -271,19 +233,6 @@
"successfully_saved": "Vellukka lagring"
},
"components": {
"addon-picker": {
"addon": "Tillegg",
"error": {
"fetch_addons": {
"description": "Henter tillegget som gav feilen.",
"title": "Feil ved henting av tillegg."
},
"no_supervisor": {
"description": "Fann ikkje Supervisor, så tillegget kunne ikkje lastast.",
"title": "Inga Supervisor"
}
}
},
"area-picker": {
"add_dialog": {
"add": "Legg til",
@@ -315,12 +264,6 @@
"loading_history": "Lastar tilstandshistoria...",
"no_history_found": "Inga tilstandshistorie funne"
},
"logbook": {
"messages": {
"is_closing": "stenger",
"is_opening": "opnar"
}
},
"related-items": {
"area": "Område",
"device": "Eining",
@@ -336,12 +279,6 @@
},
"never": "Aldri"
},
"service-control": {
"required": "Dette feltet obligatorisk",
"service_data": "Tenestedata",
"target": "Mål",
"target_description": "Kva skal denne tenesta bruke som målretta område, einingar og oppføringar."
},
"service-picker": {
"service": "Teneste"
}
@@ -418,17 +355,7 @@
"description": "Vala vart lagra vellukka."
}
},
"quick-bar": {
"commands": {
"navigation": {
"tag": "Merknader"
}
}
},
"zha_device_info": {
"buttons": {
"view_in_visualization": "Visning i visualisering"
},
"confirmations": {
"remove": "Er du sikker på at du vil fjerne eininga?"
},
@@ -452,12 +379,6 @@
"second": "{count} {count, plural,\none {sekund}\nother {sekundar}\n}",
"week": "{count} {count, plural,\none {veke}\nother {veker}\n}"
},
"errors": {
"config": {
"key_not_expected": "Nøkkelen \"{key}\" er ikkje forventa eller støtta av den visuelle redigeraren.",
"key_wrong_type": "Den gitte verdien for \"{key}\" er ikkje støtta av den visuelle redigeraren. Vi støttar ({type_correct}), men mottok ({type_wrong})."
}
},
"login-form": {
"log_in": "Logg inn",
"password": "Passord",
@@ -523,9 +444,6 @@
},
"device_id": {
"action": "Handling ",
"extra_fields": {
"position": "Posisjon"
},
"label": "Eining"
},
"event": {
@@ -726,18 +644,6 @@
}
},
"cloud": {
"account": {
"tts": {
"dialog": {
"example_message": "Hei {name}! Du kan spele kva som heilst tekst på kva som heilst støtta mediaspelar\"",
"header": "Prøv tekst til tale",
"play": "Spel",
"target": "Mål",
"target_browser": "Nettlesar"
},
"try": "Prøv "
}
},
"alexa": {
"title": "Alexa"
},
@@ -801,7 +707,6 @@
},
"cant_edit": "Du kan berre redigere element som er laga i brukargrensesnittet.",
"caption": "Einingar",
"confirm_disable_config_entry": "Det er ikkje fleire einingar for konfigurasjonsoppføringa {entry_name}. Vil du heller deaktivere konfigurasjonsoppføringa?",
"confirm_rename_entity_ids": "Vil du også endre ID-ane til oppføringane dine?",
"data_table": {
"area": "Område",
@@ -849,8 +754,7 @@
},
"filtering": {
"clear": "Klarer",
"filtering_by": "Filtrerer etter",
"show": "Vis "
"filtering_by": "Filtrerer etter"
},
"header": "Konfigurer Home Assistant",
"info": {
@@ -867,18 +771,6 @@
"delete_confirm": "Er du sikker på at du vil slette denne integrasjonen?",
"device_unavailable": "Eininga utilgjengeleg",
"devices": "{count} {count, plural,\n one {eining}\n other {einingar}\n}",
"disable_restart_confirm": "Start Home Assistant på nytt for å fullføre deaktiveringa av denne integrasjonen",
"disable": {
"disable_confirm": "Er du sikker på at du vil deaktivere denne konfigurasjonsoppføringa? Einingane og oppføringane vil verte deaktivert.",
"disabled": "Deaktivert ",
"disabled_by": {
"device": "eining ",
"integration": "integrasjon ",
"user": "brukar "
},
"disabled_cause": "Deaktivert av {cause}"
},
"enable_restart_confirm": "Start Home Assistant på nytt for å fullføre aktiveringa av denne integrasjonen",
"entities": "{count} {count, plural,\n one {oppføring}\n other {oppføringar}\n}",
"entity_unavailable": "Oppføringa utilgjengeleg",
"firmware": "Firmware: {version}",
@@ -893,29 +785,18 @@
},
"config_flow": {
"close": "Lukk",
"could_not_load": "Konfigurasjonsflyt kunne ikkje lastast inn",
"dismiss": "Avvis dialogboksa",
"error": "Feil",
"external_step": {
"description": "Ei ekstern nettside må besøkast for å fullføre dette steget.",
"open_site": "Opne nettside"
},
"finish": "Fullfør",
"pick_flow_step": {
"new_flow": "Nei, sett opp ein anna førekomst av {integration}",
"title": "Vi oppdaga desse. Vil du sette dei opp?"
},
"submit": "Send inn"
},
"configure": "Konfigurer",
"configured": "Konfigurer",
"confirm_new": "Vil du sette opp {integration}?",
"confirm_new": "Vil du setje opp {integration}?",
"description": "Administrer tilkopla einingar og tenester",
"disable": {
"disabled_integrations": "{number} deaktivert ",
"hide_disabled": "Skjul deaktivert integrasjonar",
"show_disabled": "Vis deaktiverte integrasjonar"
},
"discovered": "Oppdaga",
"integration": "integrasjon ",
"new": "Sett opp ein ny integrasjon",
@@ -1054,9 +935,6 @@
},
"groups": {
"caption": "Grupper"
},
"visualization": {
"refresh_topology": "Oppdater topologi"
}
},
"zone": {
@@ -1078,12 +956,6 @@
"wakeup_interval": "Vekkarintervall"
},
"description": "Administrer Z-Wave-nettverket ditt",
"migration": {
"ozw": {
"header": "Migrer til OpenZWave",
"introduction": "Denne vegvisaren vil hjelpe deg å migrere frå den eldre Z-Wave-integrasjonen til OpenZWave-integrasjonen som for augneblinken er i beta."
}
},
"network_management": {
"header": "Z-Wave-nettverksadministrering",
"introduction": "Køyr kommandoar som påverkar Z-wave-nettverket. Du kjem ikkje til å få tilbakemelding om kommandoande lukkast, men du kan sjekke i OZW-loggen, og prøve å finne ut av det."
@@ -1163,15 +1035,9 @@
"title": "Hendingar"
},
"services": {
"accepts_target": "Denne tenesta godtek eit mål, for eksempel: `entity_id: light.bed_light`",
"all_parameters": "Alle tilgjengelege parameter ",
"title": "Tenester",
"ui_mode": "Gå til UI-modus",
"yaml_mode": "Gå til YAML-modus",
"yaml_parameters": "Parameter berre tilgjengeleg i YAML-modus"
"title": "Tenester"
},
"states": {
"copy_id": "Kopier ID til utklippstavla",
"no_entities": "Ingen oppføringar",
"title": "Statusar"
},
@@ -1312,8 +1178,6 @@
},
"header": "Rediger brukargrensesnitt",
"menu": {
"manage_dashboards": "Administrer skriveborda",
"manage_resources": "Adminstrer ressursar",
"raw_editor": "Rå konfigurasjonsredigerar"
},
"migrate": {
@@ -1324,8 +1188,6 @@
},
"raw_editor": {
"header": "Rediger konfigurasjon",
"lovelace_changed": "Lovelace-konfigurasjonen vart oppdatert. Vil du laste den oppdaterte konfigurasjonen i redigeringsprogrammet og miste gjeldende endringar?",
"reload": "Last inn på nytt",
"save": "Lagre",
"saved": "Lagra",
"unsaved_changes": "Ikkje lagra endringar"
@@ -1372,14 +1234,6 @@
"empty": "Du har ingen meldingar",
"playback_title": "Meldingsavspeling"
},
"my": {
"component_not_loaded": "Denne viderekoplinga er ikkje støtta av Home Assistant-førekomsten. Du treng {integration}-integrasjonen å bruke denne viderekoplinga.",
"documentation": "dokumentasjon",
"error": "Det hende ein ukjent feil ",
"faq_link": "Mine Home Assitant-FAQ",
"no_supervisor": "Denne viderekoplinga er ikkje støtta av Home Assistant-installasjonen. Det trengs anten installasjonsmetoden Home Assistant eller Home Assistant Supervised. For meir informasjon, sjå {docs_link} .",
"not_supported": "Denne viderekoplinga er ikkje støtta av Home Assistant-førekomsten. Sjå {link} for dei støtta vidarekoplingane og ved kva versjon dei vart introdusert."
},
"page-authorize": {
"abort_intro": "Innlogging avbrote",
"authorizing_client": "Du held på å gi {clientId} tilgang til Home Assistant-instansen din.",
+11 -427
View File
@@ -102,391 +102,6 @@
"unknown": "nieznany"
}
},
"supervisor": {
"addon": {
"configuration": {
"audio": {
"default": "Domyślne",
"header": "Audio",
"input": "Wejście",
"output": "Wyjście"
},
"network": {
"container": "Kontener",
"disabled": "Wyłączona",
"header": "Sieć",
"host": "Host"
},
"no_configuration": "Ten dodatek nie udostępnia konfiguracji, abyś mógł w niej grzebać.",
"options": {
"edit_in_ui": "Edytuj w interfejsie użytkownika",
"edit_in_yaml": "Edytuj w trybie YAML",
"header": "Opcje",
"invalid_yaml": "Nieprawidłowy YAML",
"show_unused_optional": "Pokaż nieużywane opcjonalne opcje konfiguracji"
}
},
"dashboard": {
"action_error": {
"get_changelog": "Nie udało się uzyskać listy zmian dodatku",
"go_to_config": "Nie udało się uruchomić dodatku - sprawdzanie poprawności konfiguracji nie powiodło się!",
"install": "Nie udało się zainstalować dodatku",
"restart": "Nie udało się ponownie uruchomić dodatku",
"start": "Nie udało się uruchomić dodatku",
"start_invalid_config": "Przejdź do konfiguracji",
"stop": "Nie udało się zatrzymać dodatku",
"uninstall": "Nie udało się odinstalować dodatku",
"validate_config": "Nie powiodło się sprawdzenie konfiguracji dodatku."
},
"capability": {
"apparmor": {
"description": "AppArmor ('Application Armor') to moduł bezpieczeństwa jądra Linuksa, który ogranicza możliwości dodatków, takie jak dostęp do sieci, dostęp do gniazda typu RAW i uprawnienia do odczytu, zapisu lub wykonywania określonych plików. \n\nAutorzy dodatków mogą podać swoje profile bezpieczeństwa, zoptymalizowane dla dodatku lub zażądać jego wyłączenia. Jeśli AppArmor jest wyłączony, zwiększy to zagrożenie bezpieczeństwa, a zatem ma negatywny wpływ na ocenę zabezpieczeń dodatku.",
"title": "AppArmor"
},
"auth_api": {
"description": "Dodatek może uwierzytelniać użytkowników względem Home Assistant, umożliwiając dodatkom możliwości logowania się do aplikacji działających wewnątrz dodatków przy użyciu nazwy użytkownika/hasła Home Assistant. Ta plakietka wskazuje, czy autor dodatku żąda takiej możliwości.",
"title": "Uwierzytelnianie Home Assistant"
},
"docker_api": {
"description": "Autor dodatku zażądał, aby dodatek miał dostęp administracyjny do Dockera działającej w Twoim systemie. Ten tryb zapewnia dodatkowi pełny dostęp i kontrolę nad całym systemem Home Assistant, co zwiększa ryzyko bezpieczeństwa i może uszkodzić system w przypadku niewłaściwego użycia. Dlatego ta funkcja negatywnie wpływa na ocenę zabezpieczeń dodatku. \n\nTen poziom dostępu nie jest przyznawany automatycznie i musi zostać potwierdzony przez Ciebie. Aby to zrobić, musisz ręcznie wyłączyć tryb ochrony w dodatku. Wyłącz tryb ochrony tylko wtedy, gdy znasz, potrzebujesz i ufasz źródłowi tego dodatku.",
"title": "Pełny dostęp do Dockera"
},
"full_access": {
"description": "Ten dodatek otrzymuje pełny dostęp do sprzętu Twojego systemu, na żądanie autora dodatku. Dostęp jest porównywalny z trybem uprzywilejowanym w Dockerze. Ponieważ otwiera to potencjalne zagrożenia bezpieczeństwa, ta funkcja negatywnie wpływa na wynik zabezpieczeń dodatku. \n\nTen poziom dostępu nie jest przyznawany automatycznie i musi zostać potwierdzony przez Ciebie. Aby to zrobić, musisz ręcznie wyłączyć tryb ochrony w dodatku. Wyłącz tryb ochrony tylko wtedy, gdy znasz, potrzebujesz i ufasz źródłowi tego dodatku.",
"title": "Pełny dostęp do sprzętu"
},
"hassio_api": {
"description": "Dodatek uzyskał dostęp do interfejsu API Supervisora na żądanie autora dodatku. Domyślnie dodatek może uzyskać dostęp do ogólnych informacji o wersji systemu. Gdy dodatek zażąda dostępu do API na poziomie „menedżera” lub „administratora”, uzyska dostęp do kontroli wielu części systemu Home Assistanta. To uprawnienie jest oznaczone tą plakietką i będzie miało negatywny wpływ na ocenę zabezpieczeń dodatku.",
"title": "Dostęp do interfejsu API Supervisora"
},
"homeassistant_api": {
"description": "Ten dodatek może uzyskać dostęp do uruchomionej instancji Home Assistant bezpośrednio przez interfejs API. Ten tryb obsługuje również uwierzytelnianie dla dodatku, co umożliwia dodatkowi interakcję z Home Assistantem bez potrzeby stosowania dodatkowych tokenów uwierzytelniających.",
"title": "Dostęp do interfejsu API Home Assistanta"
},
"host_network": {
"description": "Dodatki zwykle działają we własnej izolowanej warstwie sieciowej, co uniemożliwia im dostęp do sieci systemu operacyjnego hosta. W niektórych przypadkach ta izolacja sieciowa może ograniczyć dodatki w świadczeniu ich usług, a zatem izolacja może zostać zniesiona przez autora dodatku, zapewniając dodatkowi pełny dostęp do możliwości sieciowych komputera hosta. Daje to dodatkowe możliwości sieciowe, ale obniża poziom bezpieczeństwa, dlatego ocena bezpieczeństwa dodatku zostanie obniżona, gdy ta opcja jest używana przez dodatek.",
"title": "Sieć hosta"
},
"host_pid": {
"description": "Zwykle procesy uruchamiane przez dodatek są odizolowane od wszystkich innych procesów systemowych. Autor dodatku zażądał, aby dodatek miał dostęp do procesów systemowych działających w systemie hosta i zezwolił dodatkowi na uruchamianie procesów również w systemie hosta. Ten tryb zapewnia dodatkowi pełny dostęp i kontrolę nad całym systemem Home Assistant, co zwiększa ryzyko bezpieczeństwa i może uszkodzić system w przypadku niewłaściwego użycia. Dlatego ta funkcja negatywnie wpływa na ocenę zabezpieczeń dodatku. \n\nTen poziom dostępu nie jest przyznawany automatycznie i musi zostać potwierdzony przez Ciebie. Aby to zrobić, musisz ręcznie wyłączyć tryb ochrony w dodatku. Wyłącz tryb ochrony tylko wtedy, gdy znasz, potrzebujesz i ufasz źródłowi tego dodatku.",
"title": "Procesy hosta"
},
"ingress": {
"description": "Ten dodatek używa Ingress do bezpiecznego osadzania swojego interfejsu w Home Assistant.",
"title": "Osadzanie"
},
"label": {
"apparmor": "apparmor",
"auth": "uwierzyt",
"docker": "docker",
"hardware": "sprzęt",
"hass": "hass",
"hassio": "hassio",
"host": "host",
"host_pid": "pid hosta",
"ingress": "osadz.",
"rating": "ocena",
"stage": "etap"
},
"rating": {
"description": "Home Assistant zapewnia ocenę bezpieczeństwa dla każdego z dodatków, która wskazuje ryzyko związane z używaniem tego dodatku. Im większy dostęp wymaga w systemie dodatek, tym niższy wynik, a tym samym zwiększa potencjalne zagrożenie bezpieczeństwa. \n\nWynik jest w skali od 1 do 6, gdzie 1 to najniższy wynik (uważany za najbardziej niepewny i najwyższy poziom ryzyka), a wynik 6 to najwyższy wynik (uważany za najbardziej bezpieczny i najniższy poziom ryzyka).",
"title": "Ocena bezpieczeństwa dodatku"
},
"role": {
"admin": "admin",
"backup": "kopia zap.",
"default": "domyślne",
"homeassistant": "homeassistant",
"manager": "menedżer"
},
"stage": {
"description": "Dodatki mogą mieć jeden z trzech etapów: \n\n {icon_stable} **Stabilny**: to dodatki gotowe do użycia w środowisku produkcyjnym. \n\n {icon_experimental} **Eksperymentalny**: mogą zawierać błędy i być niedokończone. \n\n {icon_deprecated} **Wycofane**: te dodatki nie będą już otrzymywać żadnych aktualizacji.",
"title": "Etap dodatku"
}
},
"changelog": "Lista zmian",
"cpu_usage": "Zużycie procesora przez dodatek",
"hostname": "Nazwa hosta",
"install": "zainstaluj",
"new_update_available": "{name} {version} jest dostępna",
"not_available_arch": "Ten dodatek nie jest zgodny z typem procesora lub systemem operacyjnym zainstalowanym na Twoim urządzeniu.",
"not_available_version": "Masz wersję {core_version_installed} Home Assistanta, aby zaktualizować dodatek do tej wersji, potrzebujesz co najmniej wersji {core_version_needed} Home Assistanta.",
"open_web_ui": "Otwórz interfejs użytkownika",
"option": {
"auto_update": {
"description": "Automatycznie aktualizuj dodatek, gdy pojawi się nowa wersja",
"title": "Automatyczna aktualizacja"
},
"boot": {
"description": "Uruchom dodatek podczas rozruchu systemu",
"title": "Uruchamianie przy starcie"
},
"ingress_panel": {
"description": "Dodaj ten dodatek do bocznego paska",
"title": "Na pasku bocznym"
},
"protected": {
"description": "Blokuje podwyższony dostęp do systemu z poziomu dodatku",
"title": "Tryb ochrony"
},
"watchdog": {
"description": "Spowoduje to uruchomienie dodatku, jeśli się zawiesi",
"title": "Obserwator"
}
},
"protection_mode": {
"content": "Tryb ochrony tego dodatku jest wyłączony! Daje to dodatkowi pełny dostęp do całego systemu, co zwiększa ryzyko bezpieczeństwa i może uszkodzić system, gdy jest używany nieprawidłowo. Wyłącz tryb ochrony tylko wtedy, gdy znasz, potrzebujesz i ufasz źródłowi tego dodatku.",
"enable": "Włącz tryb ochrony",
"title": "Ostrzeżenie: Tryb ochrony jest wyłączony!"
},
"ram_usage": "Zużycie pamięci przez dodatek",
"rebuild": "przeinstaluj",
"restart": "uruchom ponownie",
"start": "uruchom",
"stop": "zatrzymaj",
"uninstall": "odinstaluj",
"visit_addon_page": "Odwiedź stronę {name}, aby uzyskać więcej szczegółów."
},
"documentation": {
"get_documentation": "Nie udało się uzyskać dokumentacji dodatku, {error}"
},
"failed_to_reset": "Nie udało się zresetować konfiguracji dodatku, {error}",
"failed_to_save": "Nie udało się zapisać konfiguracji dodatku, {error}",
"logs": {
"get_logs": "Nie udało się uzyskać logów dodatku, {error}"
},
"panel": {
"configuration": "Konfiguracja",
"documentation": "Dokumentacja",
"info": "Informacje",
"log": "Logi"
},
"state": {
"installed": "Dodatek jest zainstalowany",
"not_available": "Dodatek nie jest dostępny na Twoim systemie",
"not_installed": "Dodatek nie jest zainstalowany"
}
},
"common": {
"cancel": "Anuluj",
"description": "Opis",
"error": {
"unknown": "Nieznany błąd",
"update_failed": "Aktualizacja nie powiodła się"
},
"failed_to_restart_name": "Nie udało się ponownie uruchomić {name}",
"failed_to_update_name": "Nie udało się zaktualizować {name}",
"learn_more": "Dowiedz się więcej",
"new_version_available": "Dostępna nowa wersja",
"newest_version": "Najnowsza wersja",
"no": "Nie",
"refresh": "Odśwież",
"release_notes": "Informacje o wydaniu",
"reload": "Wczytaj ponownie",
"reset_defaults": "Przywróć domyślne",
"reset_options": "Resetuj opcje",
"restart": "Uruchom ponownie",
"restart_name": "Uruchom ponownie {name}",
"running_version": "Aktualnie używasz wersji {version}",
"save": "Zapisz",
"show_more": "Pokaż więcej informacji na ten temat",
"update": "Aktualizuj",
"update_available": "{count, plural,\n one {oczekująca aktualizacja}\n few {oczekujące aktualizacje}\n many {oczekujących aktualizacji}\n other {{count} oczekujące aktualizacje}\n}",
"version": "Wersja",
"yes": "Tak"
},
"confirm": {
"reset_options": {
"text": "Czy na pewno chcesz zresetować wszystkie opcje?",
"title": "Resetuj opcje"
},
"restart": {
"text": "Czy na pewno chcesz ponownie uruchomić {name}?",
"title": "Uruchom ponownie {name}"
},
"update": {
"text": "Czy na pewno chcesz zaktualizować {name} do wersji {version}?",
"title": "Zaktualizuj {name}"
}
},
"dashboard": {
"addon_new_version": "Nowa wersja dostępna",
"addon_running": "Dodatek jest uruchomiony",
"addon_stopped": "Dodatek jest zatrzymany",
"addons": "Dodatki",
"no_addons": "Nie masz jeszcze zainstalowanych żadnych dodatków. Przejdź do sklepu z dodatkami, aby rozpocząć!"
},
"dialog": {
"network": {
"connected_to": "Połączono z {ssid}",
"dhcp": "DHCP",
"disabled": "Wyłączona",
"dns_servers": "Serwery DNS",
"failed_to_change": "Nie udało się zmienić ustawień sieciowych",
"gateway": "Adres bramki dostępu",
"ip_netmask": "Adres IP/Maska sieci",
"open": "Otwórz",
"scan_ap": "Wyszukaj punkty dostępu",
"static": "Stały",
"title": "Ustawienia sieci",
"unsaved": "Masz niezapisane zmiany, które zostaną utracone, jeśli zmienisz karty. Czy chcesz kontynuować?",
"warning": "Jeśli zmieniasz Wi-Fi, adres IP lub adres bramki dostępu, możesz utracić połączenie!",
"wep": "WEP",
"wpa": "wpa-psk"
},
"registries": {
"add_new_registry": "Dodaj nowy rejestr",
"add_registry": "Dodaj rejestr",
"failed_to_add": "Nie udało się dodać rejestru",
"failed_to_remove": "Nie udało się usunąć rejestru",
"no_registries": "Brak skonfigurowanych rejestrów",
"password": "Hasło",
"registry": "Rejestr",
"remove": "Usuń",
"title_add": "Dodaj nowy rejestr kontenera",
"title_manage": "Zarządzaj rejestrami kontenera",
"username": "Nazwa użytkownika"
},
"repositories": {
"add": "Dodaj",
"remove": "Usuń",
"title": "Zarządzaj repozytoriami dodatków"
},
"restart_addon": {
"confirm_text": "Uruchom ponownie dodatek",
"text": "Czy chcesz ponownie uruchomić dodatek ze zmianami?"
},
"update": {
"create_snapshot": "Utwórz snapshot {name} przed aktualizacją",
"snapshot": "Snapshot",
"snapshotting": "Tworzę snapshot {name}",
"updating": "Aktualizuję {name} do wersji {version}"
}
},
"my": {
"error": "Wystąpił nieznany błąd",
"faq_link": "Mój Home Assistant - często zadawane pytania",
"not_supported": "To przekierowanie nie jest obsługiwane przez Twoją instancję Home Assistanta. Sprawdź {link} aby znaleźć obsługiwane przekierowania i wersję, w której zostały wprowadzone."
},
"panel": {
"dashboard": "Dashboard",
"snapshots": "Snapshoty",
"store": "Sklep z dodatkami",
"system": "System"
},
"snapshot": {
"addons": "Dodatki",
"available_snapshots": "Dostępne snapshoty",
"could_not_create": "Nie udało się utworzyć snapshota",
"create": "Utwórz",
"create_blocked_not_running": "Tworzenie snapshota nie jest teraz możliwe, ponieważ system jest w {state}.",
"create_snapshot": "Utwórz snapshot",
"description": "Snapshoty umożliwiają łatwe tworzenie kopii zapasowych i przywracanie wszystkich danych instancji Home Assistant.",
"enter_password": "Proszę wprowadzić hasło.",
"folder": {
"addons/local": "Folder Local add-ons",
"homeassistant": "Folder konfiguracji Home Assistant",
"media": "Folder Media",
"share": "Folder Share",
"ssl": "Folder SSL"
},
"folders": "Foldery",
"full_snapshot": "Pełny snapshot",
"name": "Nazwa",
"no_snapshots": "Nie masz jeszcze żadnych snapshotów.",
"partial_snapshot": "Częściowy snapshot",
"password": "Hasło",
"password_protected": "chroniony hasłem",
"password_protection": "Ochrona hasłem",
"security": "Bezpieczeństwo",
"type": "Typ",
"upload_snapshot": "Prześlij snapshota"
},
"store": {
"missing_addons": "Brakuje dodatków? Włącz tryb zaawansowany na stronie profilu użytkownika.",
"no_results_found": "Brak wyników w {repository}.",
"registries": "Rejestry",
"repositories": "Repozytoria"
},
"system": {
"core": {
"cpu_usage": "Zużycie procesora przez HA Core",
"ram_usage": "Zużycie pamięci przez HA Core"
},
"host": {
"change": "Zmień",
"change_hostname": "Zmień nazwę hosta",
"confirm_reboot": "Czy na pewno chcesz ponownie uruchomić hosta?",
"confirm_shutdown": "Czy na pewno chcesz zamknąć hosta?",
"deployment": "Wdrożenie",
"docker_version": "Wersja Dockera",
"emmc_lifetime_used": "Czas zużycia eMMC",
"failed_to_get_hardware_list": "Nie udało się pobrać listy sprzętu",
"failed_to_import_from_usb": "Nie udało się zaimportować z USB",
"failed_to_reboot": "Nie udało się ponownie uruchomić hosta",
"failed_to_set_hostname": "Ustawienie nazwy hosta nie powiodło się",
"failed_to_shutdown": "Nie udało się zamknąć hosta",
"hardware": "Sprzęt",
"hostname": "Nazwa hosta",
"import_from_usb": "Importuj z USB",
"ip_address": "Adres IP",
"new_hostname": "Wprowadź nową nazwę hosta:",
"operating_system": "System operacyjny",
"reboot_host": "Uruchom ponownie hosta",
"shutdown_host": "Zamknij hosta",
"used_space": "Zajęte miejsce"
},
"log": {
"get_logs": "Nie udało się pobrać dzienników od {provider} {error}",
"log_provider": "Dostawca dziennika"
},
"supervisor": {
"beta_backup": "Przed aktywacją tej funkcji upewnij się, że masz kopie zapasowe swoich danych.",
"beta_join_confirm": "Czy chcesz dołączyć do kanału beta?",
"beta_release_items": "Obejmuje to wersje beta dla:",
"beta_warning": "Wersje beta są przeznaczone dla testerów i wczesnych użytkowników i mogą zawierać niestabilne zmiany w kodzie",
"channel": "Kanał",
"cpu_usage": "Zużycie procesora przez Supervisora",
"failed_to_reload": "Nie udało się przeładować Supervisora",
"failed_to_set_option": "Nie udało się ustawić opcji Supervisora",
"failed_to_update": "Nie udało się zaktualizować Supervisora",
"join_beta_action": "Dołącz do kanału beta",
"join_beta_description": "Pobierz aktualizacje beta dla Home Assistant (RC), Supervisora i hosta",
"leave_beta_action": "Opuść kanał beta",
"leave_beta_description": "Uzyskaj stabilne aktualizacje dla Home Assistanta, Supervisora i hosta",
"ram_usage": "Zużycie pamięci przez Supervisora",
"reload_supervisor": "Przeładuj Supervisora",
"share_diagnostics": "Udostępnij dane diagnostyczne",
"share_diagnostics_description": "Udostępniaj raporty o awariach i informacje diagnostyczne.",
"share_diagonstics_description": "Czy chcesz automatycznie udostępniać raporty o awariach i informacje diagnostyczne, gdy Supervisor napotka nieoczekiwane błędy? {line_break} Pozwoli nam to rozwiązać problemy, informacje są dostępne tylko dla głównego zespołu Home Assistant Core i nie będą udostępniane innym. {line_break} Dane nie zawierają żadnych prywatnych/wrażliwych informacji i możesz to wyłączyć w ustawieniach w dowolnym momencie.",
"share_diagonstics_title": "Pomóż ulepszyć Home Assistanta",
"unhealthy_description": "Używanie \"niezdrowej\" instalacji spowoduje problemy. Poniżej znajduje się lista problemów z Twoją instalacją. Kliknij łącza, aby dowiedzieć się, jak możesz je rozwiązać.",
"unhealthy_reason": {
"docker": "Środowisko Dockera nie działa poprawnie",
"privileged": "Supervisor nie jest uprzywilejowany",
"setup": "Konfiguracja Supervisora nie powiodła się",
"supervisor": "Supervisor nie mógł się zaktualizować"
},
"unhealthy_title": "Twoja instalacja jest \"niezdrowa\"",
"unsupported_description": "Poniżej znajduje się lista problemów z Twoją instalacją. Kliknij łącza, aby dowiedzieć się, jak możesz je rozwiązać.",
"unsupported_reason": {
"container": "Kontenery, o których wiadomo, że powodują problemy",
"dbus": "DBUS",
"docker_configuration": "Konfiguracja Dockera",
"docker_version": "Wersja Dockera",
"job_conditions": "Zignorowane warunki pracy",
"lxc": "LXC",
"network_manager": "Menedżer sieci",
"os": "System operacyjny",
"privileged": "Supervisor nie jest uprzywilejowany",
"systemd": "Systemd"
},
"unsupported_title": "Używasz nieobsługiwanej instalacji",
"update_supervisor": "Zaktualizuj Supervisora",
"warning": "OSTRZEŻENIE"
}
}
},
"ui": {
"auth_store": {
"ask": "Czy chcesz pozostać zalogowany?",
@@ -505,7 +120,7 @@
},
"automation": {
"last_triggered": "Ostatnie uruchomienie",
"trigger": "Uruchom akcje"
"trigger": "Uruchom"
},
"camera": {
"not_available": "Obraz niedostępny"
@@ -585,8 +200,7 @@
},
"script": {
"cancel": "Anuluj",
"cancel_multiple": "Anuluj {number}",
"run": "Uruchom"
"cancel_multiple": "Anuluj {number}"
},
"service": {
"run": "Uruchom"
@@ -681,19 +295,6 @@
"yes": "Tak"
},
"components": {
"addon-picker": {
"addon": "Dodatek",
"error": {
"fetch_addons": {
"description": "Pobieranie dodatków zwróciło błąd.",
"title": "Błąd podczas pobierania dodatków"
},
"no_supervisor": {
"description": "Nie znaleziono Supervisora, więc nie można załadować dodatków.",
"title": "Brak Supervisora"
}
}
},
"area-picker": {
"add_dialog": {
"add": "Dodaj",
@@ -762,8 +363,6 @@
"changed_to_state": "nastąpiła zmiana stanu na {state}",
"cleared_device_class": "brak",
"detected_device_class": "wykryto",
"is_closing": "zamyka się",
"is_opening": "otwiera się",
"rose": "wzeszło",
"set": "zaszło",
"turned_off": "nastąpiło wyłączenie",
@@ -871,8 +470,8 @@
"service-control": {
"required": "To pole jest wymagane",
"service_data": "Dane usługi",
"target": "Cele",
"target_description": "Jaki powinien być docelowy obszar, urządzenie lub encja do wywołania tej usługi."
"target": "Cel",
"target_description": "Jaki powinien być cel wywołania tej usługi"
},
"service-picker": {
"service": "Usługa"
@@ -1083,7 +682,7 @@
"scene": "Sceny",
"script": "Skrypty",
"server_control": "Kontrola serwera",
"tag": "Tagi",
"tags": "Tagi",
"users": "Użytkownicy",
"zone": "Strefy"
},
@@ -1142,7 +741,6 @@
"clusters": "Zarządzaj klastrami",
"reconfigure": "Rekonfiguracja urządzenia",
"remove": "Usuń urządzenie",
"view_in_visualization": "Wyświetl w wizualizacji",
"zigbee_information": "Sygnatura urządzenia Zigbee"
},
"confirmations": {
@@ -1298,8 +896,7 @@
},
"event": {
"event": "Zdarzenie:",
"label": "Wywołanie zdarzenia",
"service_data": "Dane usługi"
"label": "Wywołanie zdarzenia"
},
"repeat": {
"label": "Powtórzenie",
@@ -1887,7 +1484,6 @@
"cant_edit": "Możesz edytować tylko elementy utworzone w interfejsie użytkownika.",
"caption": "Urządzenia",
"confirm_delete": "Czy na pewno chcesz usunąć to urządzenie?",
"confirm_disable_config_entry": "Nie ma więcej urządzeń dla wpisu konfiguracji {entry_name} , czy zamiast tego chcesz wyłączyć ten wpis konfiguracyjny?",
"confirm_rename_entity_ids": "Czy chcesz także zmienić identyfikatory encji?",
"confirm_rename_entity_ids_warning": "Nie zmieni to konfiguracji (automatyzacji, skryptów, scen, dashboardów), które obecnie używają tych encji. Będziesz musiał je zaktualizować samemu, by używać nowych identyfikatorów encji!",
"data_table": {
@@ -2000,8 +1596,7 @@
},
"filtering": {
"clear": "Wyczyść",
"filtering_by": "Filtrowanie przez",
"show": "Pokaż"
"filtering_by": "Filtrowanie przez"
},
"header": "Konfiguruj Home Assistanta",
"helpers": {
@@ -2072,7 +1667,6 @@
"delete_confirm": "Czy na pewno chcesz usunąć tę integrację?",
"device_unavailable": "Urządzenie niedostępne",
"devices": "{count} {count, plural,\n one {urządzenie}\n few {urządzenia}\n many {urządzeń}\n other {urządzeń}\n}",
"disable_restart_confirm": "Zrestartuj Home Assistanta, aby zakończyć wyłączanie tej integracji",
"disable": {
"disable_confirm": "Czy na pewno chcesz wyłączyć ten wpis? Jego urządzenia i instancje zostaną wyłączone.",
"disabled": "Wyłączone",
@@ -2127,11 +1721,6 @@
"confirm_new": "Czy chcesz skonfigurować {integration}?",
"description": "Zarządzaj integracjami z usługami, urządzeniami, ...",
"details": "Szczegóły integracji",
"disable": {
"disabled_integrations": "Wyłączonych: {number}",
"hide_disabled": "Ukryj wyłączone integracje",
"show_disabled": "Pokaż wyłączone integracje"
},
"discovered": "Wykryte",
"home_assistant_website": "Home Assistant",
"ignore": {
@@ -2468,7 +2057,7 @@
"id": "Identyfikator encji",
"id_already_exists": "Ten identyfikator już istnieje",
"id_already_exists_save_error": "Nie możesz zapisać tego skryptu, ponieważ identyfikator nie jest unikalny, wprowadź inny identyfikator lub pozostaw pole puste, aby wygenerować go automatycznie.",
"introduction": "Użyj skryptów, aby uruchomić sekwencję akcji.",
"introduction": "Użyj skryptów, aby wykonać sekwencję akcji.",
"link_available_actions": "Dowiedz się więcej o dostępnych akcjach.",
"load_error_not_editable": "Tylko skrypty zdefiniowane w pliku scripts.yaml są edytowalne",
"max": {
@@ -2720,7 +2309,6 @@
"caption": "Wizualizacja",
"header": "Wizualizacja sieci",
"highlight_label": "Zaznacz urządzenia",
"refresh_topology": "Odśwież topologię",
"zoom_label": "Powiększ do urządzenia"
}
},
@@ -3017,11 +2605,11 @@
},
"cards": {
"actions": {
"action_confirmation": "Czy na pewno chcesz uruchomić akcję \"{action}\"?",
"action_confirmation": "Czy na pewno chcesz wykonać akcję \"{action}\"?",
"no_entity_more_info": "Nie wybrano encji dla okna dialogowego \"więcej informacji\"",
"no_entity_toggle": "Nie wybrano encji do przełączenia",
"no_navigation_path": "Nie określono ścieżki nawigacji",
"no_service": "Nie określono usługi do uruchomienia",
"no_service": "Nie określono usługi do wykonania",
"no_url": "Nie określono adresu URL do otwarcia"
},
"confirm_delete": "Czy na pewno chcesz usunąć tę kartę?",
@@ -3392,14 +2980,12 @@
"confirm_remove_config_text": "Jeśli usuniesz konfigurację interfejsu użytkownika Lovelace, widoki automatycznie będą generowane z obszarów i urządzeń.",
"confirm_remove_config_title": "Na pewno chcesz usunąć konfigurację interfejsu użytkownika Lovelace? Widoki będą automatycznie generowane z obszarów i urządzeń.",
"confirm_unsaved_changes": "Masz niezapisane zmiany. Na pewno chcesz wyjść?",
"confirm_unsaved_comments": "Twoja konfiguracja może zawierać komentarze, które nie zostaną zapisane. Czy chcesz kontynuować?",
"confirm_unsaved_comments": "Twoja konfiguracja zawiera komentarze, które nie zostaną zapisane. Czy chcesz kontynuować?",
"error_invalid_config": "Twoja konfiguracja jest nieprawidłowa: {error}",
"error_parse_yaml": "Nie można przeanalizować YAML: {error}",
"error_remove": "Nie można usunąć konfiguracji: {error}",
"error_save_yaml": "Nie można zapisać YAML: {error}",
"header": "Edytuj konfigurację",
"lovelace_changed": "Konfiguracja Lovelace została zaktualizowana, czy chcesz załadować zaktualizowaną konfigurację do edytora i stracić obecne zmiany?",
"reload": "Wczytaj ponownie",
"resources_moved": "Zasoby nie powinny być już dodawane do konfiguracji Lovelace, można je dodawać w panelu konfiguracji Lovelace.",
"save": "Zapisz",
"saved": "Zapisano",
@@ -3487,10 +3073,8 @@
},
"my": {
"component_not_loaded": "To przekierowanie nie jest obsługiwane przez Twoją instancję Home Assistanta. Aby skorzystać z tego przekierowania, potrzebujesz integracji {integration}.",
"documentation": "dokumentacja",
"error": "Wystąpił nieznany błąd",
"faq_link": "Mój Home Assistant - często zadawane pytania",
"no_supervisor": "To przekierowanie nie jest obsługiwane przez Twoją instalację Home Assistant. Wymagany jest Home Assistant OS lub Home Assistant Supervised. Więcej informacji można znaleźć na {docs_link}.",
"not_supported": "To przekierowanie nie jest obsługiwane przez Twoją instancję Home Assistanta. Sprawdź {link} aby znaleźć obsługiwane przekierowania i wersję, w której zostały wprowadzone."
},
"page-authorize": {
+1
View File
@@ -673,6 +673,7 @@
"scene": "Cenários",
"script": "Script",
"server_control": "Controlo do servidor",
"tags": "Etiquetas",
"users": "Utilizadores",
"zone": "Zonas"
},
+1
View File
@@ -648,6 +648,7 @@
"person": "Persoane",
"scene": "Scene",
"script": "Scripturi",
"tags": "Etichete",
"users": "Utilizatori",
"zone": "Zone"
},
+1 -42
View File
@@ -102,42 +102,6 @@
"unknown": "Неизвестно"
}
},
"supervisor": {
"addon": {
"panel": {
"configuration": "Конфигурация",
"documentation": "Документация",
"info": "Информация",
"log": "Журнал"
}
},
"common": {
"cancel": "Отмена",
"newest_version": "Последняя версия",
"release_notes": "Список изменений",
"update": "Обновить",
"version": "Версия"
},
"confirm": {
"update": {
"text": "Вы уверены, что хотите обновить {name} до версии {version}?",
"title": "Обновление {name}"
}
},
"dashboard": {
"addon_new_version": "Доступна новая версия",
"addon_running": "Дополнение работает",
"addon_stopped": "Дополнение остановлено",
"addons": "Дополнения",
"no_addons": "Нет установленных дополнений. Вы можете установить их из магазина дополнений."
},
"panel": {
"dashboard": "Панель",
"snapshots": "Снапшоты",
"store": "Магазин дополнений",
"system": "Система"
}
},
"ui": {
"auth_store": {
"ask": "Запомнить меня на этом устройстве?",
@@ -413,8 +377,6 @@
"changed_to_state": "изменяет состояние на \"{state}\"",
"cleared_device_class": "не обнаруживает {device_class}",
"detected_device_class": "обнаруживает {device_class}",
"is_closing": "закрывается",
"is_opening": "открывается",
"rose": "всходит",
"set": "заходит",
"turned_off": "выключается",
@@ -735,6 +697,7 @@
"script": "Сценарии",
"server_control": "Сервер",
"tag": "Метки",
"tags": "Метки",
"users": "Пользователи",
"zone": "Зоны"
},
@@ -793,7 +756,6 @@
"clusters": "Управление кластерами",
"reconfigure": "Перенастроить устройство",
"remove": "Удалить устройство",
"view_in_visualization": "Просмотреть на схеме визуализации сети",
"zigbee_information": "Подпись устройства Zigbee"
},
"confirmations": {
@@ -2371,7 +2333,6 @@
"caption": "Визуализация",
"header": "Визуализация сети",
"highlight_label": "Выделить устройства",
"refresh_topology": "Обновить топологию",
"zoom_label": "Показать устройство"
}
},
@@ -3049,8 +3010,6 @@
"error_remove": "Не удалось удалить конфигурацию: {error}",
"error_save_yaml": "Не удалось сохранить YAML: {error}",
"header": "Редактирование конфигурации",
"lovelace_changed": "Конфигурация Lovelace была обновлена, Вы хотите загрузить в редактор обновленную конфигурацию? Внимание, текущие изменения будут потеряны!",
"reload": "Перезагрузить",
"resources_moved": "Ресурсы не должны более добавляться в конфигурацию Lovelace, но их можно добавить на панели конфигурации Lovelace.",
"save": "Сохранить",
"saved": "Сохранено",
+1
View File
@@ -667,6 +667,7 @@
"scene": "Scene",
"script": "Skripti",
"server_control": "Nadzor strežnika",
"tags": "Značke",
"users": "Uporabniki",
"zone": "Območja"
},
+1
View File
@@ -676,6 +676,7 @@
"scene": "Scener",
"script": "Skript",
"server_control": "Serverhantering",
"tags": "Taggar",
"users": "Användare",
"zone": "Zoner"
},
+2 -134
View File
@@ -102,139 +102,6 @@
"unknown": "Bilinmeyen"
}
},
"supervisor": {
"common": {
"cancel": "İptal"
},
"confirm": {
"update": {
"title": "{name} güncelleyin"
}
},
"dialog": {
"network": {
"connected_to": "{ssid} bağlantı kuruldu",
"dhcp": "DHCP",
"disabled": "Devre dışı",
"dns_servers": "DNS Sunucuları",
"failed_to_change": "Ağ ayarları değiştirilemedi",
"gateway": "Ağ geçidi adresi",
"ip_netmask": "IP adresi / Ağ maskesi",
"open": "Açık",
"scan_ap": "Erişim noktalarını tara",
"static": "Statik",
"title": "Ağ ayarları",
"unsaved": "Kaydedilmemiş değişiklikleriniz var, sekmeleri değiştirirseniz bunlar kaybolacak, devam etmek istiyor musunuz?",
"warning": "Wi-Fi, IP veya ağ geçidi adreslerini değiştirirseniz, bağlantıyı kaybedebilirsiniz!",
"wep": "WEP",
"wpa": "wpa-psk"
},
"registries": {
"add_new_registry": "Yeni kayıt ekle",
"add_registry": "Kayıt ekle",
"failed_to_add": "Kayıt eklenemedi",
"failed_to_remove": "Kayıt kaldırılamadı",
"no_registries": "Yapılandırılmış kayıt yok",
"password": "Parola",
"registry": "Kayıt",
"remove": "Kaldır",
"title_add": "Yeni Kapsayıcı Kaydı Ekle",
"title_manage": "Kapsayıcı Kayıtlarını Yönetin",
"username": "Kullanıcı adı"
},
"repositories": {
"add": "Ekle",
"remove": "Kaldır",
"title": "Eklenti depolarını yönetme"
},
"restart_addon": {
"confirm_text": "Eklentiyi yeniden başlatın",
"text": "Eklentiyi değişikliklerinizle yeniden başlatmak istiyor musunuz?"
},
"update": {
"create_snapshot": "Güncellemeden önce {name} anlık görüntüsünü oluşturun",
"snapshot": "Anlık görüntü",
"snapshotting": "{name} anlık görüntüsü oluşturuluyor",
"updating": "{name} , {version} sürümüne güncelleniyor"
}
},
"snapshot": {
"addons": "Eklentiler",
"available_snapshots": "Kullanılabilir Anlık Görüntüler",
"could_not_create": "Anlık görüntü oluşturulamadı",
"create": "Oluştur",
"create_blocked_not_running": "{state} durumunda olduğundan şu anda anlık görüntü oluşturmak mümkün değil.",
"create_snapshot": "Anlık görüntü oluştur",
"description": "Anlık görüntüler, Home Assistant örneğinizin tüm verilerini kolayca yedeklemenizi ve geri yüklemenizi sağlar.",
"enter_password": "Lütfen bir parola girin.",
"folder": {
"addons/local": "Yerel eklentiler",
"homeassistant": "Home Assistant yapılandırması",
"media": "Medya",
"share": "Paylaş",
"ssl": "SSL"
},
"folders": "Klasörler",
"full_snapshot": "Tam anlık görüntü",
"name": "Ad",
"no_snapshots": "Henüz anlık görüntünüz yok.",
"partial_snapshot": "Kısmi anlık görüntü",
"password": "Parola",
"password_protected": "parola korumalı",
"password_protection": "Parola koruması",
"security": "Güvenlik",
"type": "Tür",
"upload_snapshot": "Anlık görüntü yükle"
},
"system": {
"core": {
"cpu_usage": "Çekirdek CPU Kullanımı",
"ram_usage": "Çekirdek RAM Kullanımı"
},
"host": {
"change": "Değişiklik",
"change_hostname": "Ana Bilgisayar Adını Değiştirin",
"confirm_reboot": "Ana bilgisayarı yeniden başlatmak istediğinizden emin misiniz?",
"confirm_shutdown": "Ana bilgisayarı kapatmak istediğinizden emin misiniz?",
"deployment": "Dağıtım",
"docker_version": "Docker sürümü",
"emmc_lifetime_used": "eMMC Kullanım Ömrü",
"failed_to_get_hardware_list": "Donanım listesi alınamadı",
"failed_to_import_from_usb": "USB'den içe aktarılamadı",
"failed_to_reboot": "Ana bilgisayar yeniden başlatılamadı",
"failed_to_set_hostname": "Ana bilgisayar adı ayarlanamadı",
"failed_to_shutdown": "Ana bilgisayar kapatılamadı",
"hardware": "Donanım",
"hostname": "Ana bilgisayar adı",
"import_from_usb": "USB'den içe aktar",
"ip_address": "IP Adresi",
"new_hostname": "Lütfen yeni bir ana bilgisayar adı girin:",
"operating_system": "İşletim sistemi",
"reboot_host": "Ana bilgisayarı yeniden başlatın",
"shutdown_host": "Ana bilgisayarı kapat",
"used_space": "Kullanılan alan"
},
"supervisor": {
"unhealthy_reason": {
"docker": "Docker ortamı düzgün çalışmıyor",
"privileged": "Süpervizör ayrıcalıklı değil",
"setup": "Süpervizörün kurulumu başarısız oldu",
"supervisor": "Süpervizör güncellenemedi"
},
"unsupported_reason": {
"dbus": "DBUS",
"docker_configuration": "Docker Yapılandırması",
"docker_version": "Docker Sürümü",
"job_conditions": "Yoksayılan iş koşulları",
"lxc": "LXC",
"network_manager": "Ağ yöneticisi",
"os": "İşletim sistemi",
"privileged": "Süpervizör ayrıcalıklı değil",
"systemd": "Systemd"
}
}
}
},
"ui": {
"auth_store": {
"ask": "Oturumunuzun açık kalmasını istiyor musunuz?",
@@ -765,7 +632,7 @@
"remove_intro": "Varlık artık kullanılmıyorsa, kaldırarak temizleyebilirsiniz."
},
"script": {
"last_action": "Son eylem",
"last_action": "Son Eylem",
"last_triggered": "Son Tetiklenen"
},
"settings": "Varlık ayarları",
@@ -830,6 +697,7 @@
"script": "Senaryolar",
"server_control": "Sunucu Kontrolleri",
"tag": "Etiketler",
"tags": "Etiketler",
"users": "Kullanıcılar",
"zone": "Bölgeler"
},
+1
View File
@@ -663,6 +663,7 @@
"scene": "Сцени",
"script": "Скрипти",
"server_control": "Керування сервером",
"tags": "Теги",
"users": "Користувачі",
"zone": "Зони"
},
+1
View File
@@ -697,6 +697,7 @@
"script": "脚本",
"server_control": "服务控制",
"tag": "标签",
"tags": "标签",
"users": "用户",
"zone": "地点"
},
+5 -46
View File
@@ -102,42 +102,6 @@
"unknown": "未知"
}
},
"supervisor": {
"addon": {
"panel": {
"configuration": "設定",
"documentation": "相關文件",
"info": "資訊",
"log": "日誌"
}
},
"common": {
"cancel": "取消",
"newest_version": "最新版本",
"release_notes": "發行說明",
"update": "更新",
"version": "版本"
},
"confirm": {
"update": {
"text": "確定要更新 {name} 至 {version} 版?",
"title": "更新 {name}"
}
},
"dashboard": {
"addon_new_version": "新版本可供下載",
"addon_running": "附加元件執行中",
"addon_stopped": "附加元件已停止",
"addons": "附加元件",
"no_addons": "目前似乎沒有安裝任何附加元件。點選下方附加元件商店以新增!"
},
"panel": {
"dashboard": "主面板",
"snapshots": "系統備份",
"store": "附加元件商店",
"system": "系統"
}
},
"ui": {
"auth_store": {
"ask": "是否要保持登錄狀態?",
@@ -333,14 +297,14 @@
},
"components": {
"addon-picker": {
"addon": "附加元件",
"addon": "Add-on",
"error": {
"fetch_addons": {
"description": "取得附加元件回報錯誤",
"title": "取得附加元件錯誤"
"description": "取得 Add-on 回報錯誤",
"title": "取得 Add-on 錯誤"
},
"no_supervisor": {
"description": "找不到 Supervisor、因此附加元件無法載入。",
"description": "找不到 Supervisor、因此 Add-on 無法載入。",
"title": "找不到 Supervisor"
}
}
@@ -413,8 +377,6 @@
"changed_to_state": "變更為{state}",
"cleared_device_class": "安全(未偵測到 {device_class}",
"detected_device_class": "偵測到 {device_class}",
"is_closing": "關閉中",
"is_opening": "開啟中",
"rose": "升高",
"set": "設定",
"turned_off": "關閉",
@@ -735,6 +697,7 @@
"script": "腳本",
"server_control": "伺服器控制",
"tag": "標籤",
"tags": "標籤",
"users": "使用者",
"zone": "區域"
},
@@ -793,7 +756,6 @@
"clusters": "管理叢集",
"reconfigure": "重新設定裝置",
"remove": "移除裝置",
"view_in_visualization": "網路形象化",
"zigbee_information": "Zigbee 裝置簽章"
},
"confirmations": {
@@ -2371,7 +2333,6 @@
"caption": "形象化",
"header": "網路形象化",
"highlight_label": "高亮顯示裝置",
"refresh_topology": "更新拓樸",
"zoom_label": "縮放到裝置"
}
},
@@ -3049,8 +3010,6 @@
"error_remove": "無法移除設定:{error}",
"error_save_yaml": "無法儲存 YAML{error}",
"header": "編輯設定",
"lovelace_changed": "Lovelace 設定已更新,是否要於編輯器中載入更新設定,並放棄目前變更?",
"reload": "重新載入",
"resources_moved": "無法再透過 Lovelace 設定新增資源,需透過 Lovelace 設定面板進行新增。",
"save": "儲存",
"saved": "已儲存",
+3 -3
View File
@@ -2026,9 +2026,9 @@
integrity sha512-KL+cM+uJPW5skyuTRoW43lOaSQq3YDNEPx5z0V/9Wsz9R9dK4kVP5NIRMUFgl9MUCQ9UxIotvgPDpz65j9wjuA==
"@codemirror/view@^0.17.0":
version "0.17.13"
resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-0.17.13.tgz#e805ccaa31c22fcff87f0a1c88c143ff17960458"
integrity sha512-TWmQF2OMzWYY51gvzcq0ECvW1EyhEVpy//dmu1MDvJrv8nDZWGY/a414fUCc+v6DKNpujg7IIpP9sD2izYJFpg==
version "0.17.11"
resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-0.17.11.tgz#d9fad5aa405769f97621bb77fab7abc2edb55f2d"
integrity sha512-pl5fOiBLifExuqAuqhv/yOZvDODQrO26HEtljv4DJqx2Em5kKjzWVHhQymq0dh+nPY+qA4vZCGcT5r/ySNR52Q==
dependencies:
"@codemirror/rangeset" "^0.17.0"
"@codemirror/state" "^0.17.0"